zoukankan      html  css  js  c++  java
  • eCos设备驱动程序(二)

    http://blog.chinaunix.net/uid-23860671-id-150539.html

    关于设备入口表DEVTAB_ENTRY:
    在eCos中, 是通过给指定的设备定义DEVTAB_ENTRY,来达到
    对设备的注册过程
    的。
    DEVTAB_ENTRY是一个宏定义,定义在ecos/packages/io/common/current/include/devtab.h中,
    如下:
    #define DEVTAB_ENTRY(_l,_name,_dep_name,_handlers,_init,_lookup,_priv) \ 
            CHAR_DEVTAB_ENTRY(_l,_name,_dep_name,_handlers,_init,_lookup,_priv)
    默认下使用DEVTAB_ENTRY定义的是字符设备,这里就以一个字符设备为例进行说明了,
    CHAR_DEVTAB_ENTRY的定义在同一个文件当中:

    #define CHAR_DEVTAB_ENTRY(_l, _name, _dep_name, _handlers, _init, _lookup, _priv) 
    cyg_devtab_entry_t _l CYG_HAL_TABLE_ENTRY(devtab) = {                            
      _name,                                                                        
      _dep_name,                                                                    
      _handlers,                                                                    
      _init,                                                                        
      _lookup,                                                                      
      _priv,                                                                        
      CYG_DEVTAB_STATUS_CHAR                                                        
    };
    就是定义一个cyg_devtab_entry_t结构的变量,需要注意的是CYG_HAL_TABLE_ENTRY,它其实是
    将定义的
    变量 _l 放到指定的数据段
    中,看看它的定义,在
    ecos/packages/hal/common/current/include/hal_tables.h文件中:

    #define CYG_HAL_TABLE_ENTRY( _name ) 
            CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name)".data.") 
            CYGBLD_ATTRIB_USED 

    其中CYGBLD_ATTRIB_SECTION和CYGBLD_ATTRIB_USED的定义,在文件

    ecos/packages/infra/current/include/cyg_type.h中:

    #define CYGBLD_ATTRIB_SECTION(__sect__) __attribute__((section (__sect__))) 
    #define CYGBLD_ATTRIB_USED __attribute__((unused)) 

    现在将CYG_HAL_TABLE_ENTRY(devtab)展开就是:

    __atrribute__((section (".ecos.table.devtab.data."))) __attribute__((unused)) 

    也就是
    将所有的设备表入口放到.ecos.table.devtab.data.数据段中
    ,有关__attribute__的可以参考
    GNU手册中的说明。可以看出这和linux中的_init的使用是相同的,后面的__attribute__((unused))启
    动作用就是在编译时防止出现“变量未使用”警告的出现。 

    系统访问的时候,并不直接使用设备表入口的名称_l,而是通过两个指针来操

    作.ecos.table.devtab.data.数据段,分别是__DEVTAB__和__DEVTAB_END__,这两个指针定义在
    ecos/packages/io/common/current/src/ioinit.cxx中:

    CYG_HAL_TABLE_BEGIN( __DEVTAB__, devtab );
    CYG_HAL_TABLE_END( __DEVTAB_END__, devtab ); 

    CYG_HAL_TABLE_BEGIN和CYG_HAL_TABLE_END的定义在
    ecos/packages/hal/common/current/include/hal_tables.h中:

    #define CYG_HAL_TABLE_BEGIN( _label, _name )                                    
    __asm__(".section ".ecos.table." __xstring(_name) ".begin","aw"n"          
        ".globl" __xstring(CYG_LABEL_DEFN(_label)) "n"                              
        ".type  " __xstring(CYG_LABEL_DEFN((_label)) ",objectn"                    
        ".p2align " __xstring((CYGARC_P2ALIGNMENT) "n"                              
        __xstring(CYG_LABEL_DEFN(_label)) ":n"                                      
        ".previousn"                                                                
        ) 
    #define CYG_HAL_TABLE_END( _label, _name )                                      
    __asm__(".section ".ecos.table." __xstring(_name) ".finish","aw"n"          
        ".globl" __xstring(CYG_LABEL_DEFN(_label)) "n"                              
        ".type  " __xstring(CYG_LABEL_DEFN((_label)) ",objectn"                    
        ".p2align " __xstring((CYGARC_P2ALIGNMENT) "n"                              
        __xstring(CYG_LABEL_DEFN(_label)) ":n"                                      
        ".previousn"                                                                
        )
    也就是,
    __DEVTAB__和__DEVTAB_END__两个指针分别指向.ecos.table.devtab.data.的开始和结尾
     

    这样就把该设备的
    设备的入口表放入了__DEVTAB__和__DEVTAB_END__ 之间有数据段中.


    系统在启动时会通过调用cyg_io_init函数完成对所有设备的初始化,具体代码是:
    void
    cyg_io_init(void)
    {
        static int _init = false;
        cyg_devtab_entry_t *t;
        if (_init) return;
    /*******************************************************************/
        
    for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++) {
      //调用所有设备的初始化程序
            if 
    (t->init(t))
     {
                t->status |= CYG_DEVTAB_STATUS_AVAIL;
            } else {
                t->status &= ~CYG_DEVTAB_STATUS_AVAIL;  
            }
        }
    /*******************************************************************/
        _init = true;
    }


    用户可以通过cyg_io_lookup获取设备句柄
    ,具体代码如下:
    Cyg_ErrNo
    cyg_io_lookup(const char *name, cyg_io_handle_t *handle)
    {
        union devtab_entry_handle_union {
            cyg_devtab_entry_t *st;
            cyg_io_handle_t h;
        } stunion;
        cyg_devtab_entry_t *t;
        Cyg_ErrNo res;
        const char *name_ptr;
    /*******************************************************************/ 
      
    for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++) {
            if (cyg_io_compare(name, t->name, &name_ptr))
     {
                if (t->dep_name) {
                    res = cyg_io_lookup(t->dep_name, &stunion.h);
                    if (res != ENOERR) {
                        return res;
                    }
    /*******************************************************************/
                } else {
                    stunion.st = NULL;
                }
                if (t->lookup) {
                    res = (t->lookup)(&t, stunion.st, name_ptr);
                    if (res != ENOERR) {
                        return res;
                    }
                }
                *handle = (cyg_io_handle_t)t;
                return ENOERR;
            }
        }
        return -ENOENT;  
    }

  • 相关阅读:
    位运算学习
    C语言从文件中读取数字
    百度网盘视频加速代码
    算法思想
    递归解决全排列问题
    android studio出现offline情况
    二叉树的遍历(递归与非递归)
    (一)为什么要UML
    Logstash详解之——input模块
    解决maven项目update project会更改jdk版本问题
  • 原文地址:https://www.cnblogs.com/kuainiao/p/2957804.html
Copyright © 2011-2022 走看看