zephyr驱动加载&应用层调用

struct device
zephyr内核对象,用于管理所有的设备

struct device_config
zephyr内核对象,属于struct device的成员

/** Version:V1.14, directory:/zephyr/include/device.h **/


struct device 
{
    struct device_config *config;    /** **/
    const void *driver_api;        /** 驱动的api接口,共有代码**/
    void *driver_data;             /** 驱动设备的私有数据 struct xxx_device_data**/
#if defined(__x86_64) && __SIZEOF_POINTER__ == 4
    /* The x32 ABI hits an edge case.  This is a 12 byte struct,
    * but the x86_64 linker will pack them only in units of 8
    * bytes, leading to alignment problems when iterating over
    * the link-time array.
    */
    void *padding;
#endif
};

struct device_config 
{
    const char *name;    /*驱动名称*/
    int (*init)(struct device *device);    /*设备初始化接口*/
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
    int (*device_pm_control)(struct device *device, u32_t command,
                             void *context, device_pm_cb cb, void *arg);
    struct device_pm *pm;
#endif
    const void *config_info;    /*驱动设备私有配置,struct  xxx_device_config*/
};
 

设备驱动的初始化和优先级

宏定义 DEVICE_AND_API_INIT 创建一个内核对象,配置了驱动加载优先级和在内存中段的位置。

/** Version:zephyrV1.14, Directory:/zephyr/include/device.h **/

#define DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info,  \
                            level, prio, api)                             \
        static struct device_config _CONCAT(__config_, dev_name) __used   \
        __attribute__((__section__(".devconfig.init"))) = {               \
                .name = drv_name, .init = (init_fn),                      \
                .config_info = (cfg_info)                                 \
        };                                                                \
        static struct device _CONCAT(__device_, dev_name) __used          \
        __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
                .config = &_CONCAT(__config_, dev_name),                  \
                .driver_api = api,                                        \
                .driver_data = data                                       \
        }

dev_name — input,设备名,一般没啥作用;
drv_name — input,重要参数,设备的驱动名,用于在device_get_binding中查找设备
init_fn -------- input,设备的初始化接口,在内核启动的驱动设备初始化阶段被调用
data ---------- input,其实就是struct xxx_device_data 类型的变量
cfg_info ----- input,其实就是struct xxx_device_config 类型的变量
level ---------- input,重要参数,与prio一起确定设备的初始化顺序
prio ----------- input,重要参数,与level一起驱动设备的初始化顺序
api--------------input,stuct xxx_driver_api,提供系统调用的接口


DEVICE_AND_API_INIT 在这个宏定义中,有两个参数 level 和 prio。这两个参数没有出现在具体的代码中,而是出现在 attribute 属性中:

__attribute__((__section__(".init_" #level STRINGIFY(prio))))

编译器在预编译的时候会将 “#” 后面到参数转换为字符串,STRINGIFY(s) 的作用也是将参数 s 转换为字符串 “s”。

举个例如,如果在调用 DEVICE_AND_API_INIT 时传入的参数 level 和 prio 分别为 PRIMARY 和 50,那么编译器就会将上面那段代码放到名为 .init_PRIMARY50 的段中。

通过 attribut 设置了变量 _device_dev_name 在编译后所属的段为(".init" #level STRINGIFY(prio)),这是一个与level&prio相关的段,在zephyr应用完成编译之后,会根据level & prio 参数将所有的驱动设备汇聚在一起。

在zephyr运行时,会将所有的device变量拷贝到内存中,并根据level & prio参数完成设备的初始化。

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值