Zephyr OS 驱动篇之设备初始化顺序
来源:互联网 发布:一级域名注册 编辑:程序博客网 时间:2024/05/18 13:24
Zephyr OS 驱动篇之设备初始化顺序
在前面的 Zephyr OS 驱动篇之设备驱动模型 中已讲解了 Zephyr OS 中的设备驱动模型。Zephyr OS 将设备分为 PRIMARY、SECONDARY、NANOKERNEL 等五个等级,并在系统启动的相应阶段初始化该等级内的所有设备。那么问题来了,每个等级内有很多设备,它们的初始化时有依赖关系吗,即它们需要按照某个顺序初始化吗?
答案是:YES!
再看看设备的定义:
复制代码在这个宏定义中,有两个参数至关重要,level 和 prio。这两个参数没有出现在具体的代码中,而是出现在 __attribute__ 属性中:
复制代码编译器在预编译的时候会将 “#” 后面到参数转换为字符串,例如 #PRIMARY 将被转换为 “PRIMARY”。
TRINGIFY(s) 的作用也是将参数 s 转换为字符串 “s”, 其代码如下:
复制代码举个例如,如果在调用 DEVICE_AND_API_INIT 时传入的参数 level 和 prio 分别为 PRIMARY 和 50,那么编译器就会将上面那段代码放到名为 .init_PRIMARY50 的段中。
现在转移视线,在 linker-defs.h 中有如下代码
复制代码在链接脚本文件 linker.ld 中将会调用上述代码。上面代码的大意是将所有的设备定义的代码按照设备等级(level)依次排列,且在每个等级中,按数字(prio)的大小从小到大依次排列。
假设系统一共定义了十个设备,它们的参数如下:
devicelevelprio设备 APRIMARY 32设备 BPRIMARY 24设备 CNANOKERNEL 50设备 DPRIMARY 30设备 EMICROKERNEL 30设备 FAPPLICATION 3设备 GSECONDARY 18设备 HPRIMARY 0设备 ISECONDARY 44设备 JPRIMARY 20
编译器会按照下面的顺序依次存放各个设备的代码:
devicelevelprio设备 HPRIMARY 0设备 JPRIMARY 20设备 BPRIMARY 24设备 DPRIMARY 30设备 APRIMARY 32设备 GSECONDARY 18设备 ISECONDARY 44设备 CNANOKERNEL 50设备 EMICROKERNEL 30设备 FAPPLICATION 3
所以系统启动时,各设备的初始化顺序是 H, J, B, D, A, G, I, C, E, F。
总结一下,在系统初始化设备时,除了要按照设备等级(level)排序外,在每个等级内部还要按照优先级(prio)排序。
在前面的 Zephyr OS 驱动篇之设备驱动模型 中已讲解了 Zephyr OS 中的设备驱动模型。Zephyr OS 将设备分为 PRIMARY、SECONDARY、NANOKERNEL 等五个等级,并在系统启动的相应阶段初始化该等级内的所有设备。那么问题来了,每个等级内有很多设备,它们的初始化时有依赖关系吗,即它们需要按照某个顺序初始化吗?
答案是:YES!
再看看设备的定义:
- #define DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, \
- level, prio, api) \
- \
- static struct device_config __config_##dev_name __used \
- __attribute__((__section__(".devconfig.init"))) = { \
- .name = drv_name, .init = (init_fn), \
- .config_info = (cfg_info) \
- }; \
- \
- static struct device (__device_##dev_name) __used \
- __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
- .config = &(__config_##dev_name), \
- .driver_api = api, \
- .driver_data = data \
- }
- __attribute__((__section__(".init_" #level STRINGIFY(prio))))
TRINGIFY(s) 的作用也是将参数 s 转换为字符串 “s”, 其代码如下:
- #define _STRINGIFY(x) #x
- #define STRINGIFY(s) _STRINGIFY(s)
现在转移视线,在 linker-defs.h 中有如下代码
- #define DEVICE_INIT_SECTIONS() \
- __device_init_start = .; \
- DEVICE_INIT_LEVEL(PRIMARY) \
- DEVICE_INIT_LEVEL(SECONDARY) \
- DEVICE_INIT_LEVEL(NANOKERNEL) \
- DEVICE_INIT_LEVEL(MICROKERNEL) \
- DEVICE_INIT_LEVEL(APPLICATION) \
- __device_init_end = .; \
- DEVICE_BUSY_BITFIELD() \
- DEVICE_INIT_LEVEL 的定义如下:
- #define DEVICE_INIT_LEVEL(level) \
- __device_##level##_start = .; \
- KEEP(*(SORT(.init_##level[0-9]))); \
- KEEP(*(SORT(.init_##level[1-9][0-9]))); \
假设系统一共定义了十个设备,它们的参数如下:
devicelevelprio设备 APRIMARY 32设备 BPRIMARY 24设备 CNANOKERNEL 50设备 DPRIMARY 30设备 EMICROKERNEL 30设备 FAPPLICATION 3设备 GSECONDARY 18设备 HPRIMARY 0设备 ISECONDARY 44设备 JPRIMARY 20
编译器会按照下面的顺序依次存放各个设备的代码:
devicelevelprio设备 HPRIMARY 0设备 JPRIMARY 20设备 BPRIMARY 24设备 DPRIMARY 30设备 APRIMARY 32设备 GSECONDARY 18设备 ISECONDARY 44设备 CNANOKERNEL 50设备 EMICROKERNEL 30设备 FAPPLICATION 3
所以系统启动时,各设备的初始化顺序是 H, J, B, D, A, G, I, C, E, F。
总结一下,在系统初始化设备时,除了要按照设备等级(level)排序外,在每个等级内部还要按照优先级(prio)排序。
阅读全文
0 0
- Zephyr OS 驱动篇之设备初始化顺序
- Zephyr OS之线程
- Zephyr OS之内核调度
- Zephyr OS 内核篇:系统启动
- Zephyr OS 内核篇:系统启动
- Zephyr OS 内核篇:系统启动
- Zephyr OS之开发环境的搭建
- Zephyr OS之源码树结构
- Zephyr Kernel 设备驱动和设备模型(一)
- Zephyr Kernel 设备驱动和设备模型(二)
- USB设备驱动之设备初始化(设备枚举)
- USB设备驱动之设备初始化(设备枚举)
- Zephyr OS 基础篇:系统简介
- Zephyr OS 基础篇: 系统简介
- Zephyr OS 内核篇: 执行上下文
- Zephyr OS 内核篇: 执行上下文
- Zephyr OS 内核篇: 内核链表
- Linux Kernel设备驱动模型之设备初始化
- Android 基于google Zxing实现对手机中的二维码进行扫描
- 打印空心菱形
- linux上配置tomcat之 CentOS 7 开放防火墙端口命令
- Android 对Layout_weight属性完全解析以及使用ListView来实现表格
- 管道
- Zephyr OS 驱动篇之设备初始化顺序
- 输出学生信息
- java学习——java基础(三)之JDK介绍
- 编译原理实验手册
- Linux开发环境搭建03---Ubuntu14.04在VMware12上设置
- 头文件的包含规则(尖括号和引号的区别)
- 快速排序(基于顺序容器vector;基于数组array)
- USACO-2017-FEB-金组 Why Did the Cow Cross the Road
- MapReduce 分析 Youtube 数据