当有多个驱动需要INIT_DEVICE_EXPORT时,要注意设备装载顺序。
如LCD背光初始开启假如在LCD驱动中,如果先装在LCD驱动,则可能失效,原因是PWM驱动可能还未装载,等装载完毕后LCD装载已过,导致未打开背光。需要从APP中手动打开。
请教官方在同一级INIT中,如何设置顺序,有无函数调整设备装载顺序?
熊大已回复过了,见: 请求添加INIT_XXX_EXPORT 顺序支持
要解决这问题,首先得明白INIT_DEVICE_EXPORT的实现原理,
它是一个宏定义,在include/rtdef.h里面定义的,如下:
追溯到INIT_EXPORT,本质就是顶一个init-object,然后编译时放在指定的SECTION: .rti_fn里面,
以gcc编译环境为例,如下:
再到一个具体的bsp,以bsp/qemu-vexpress-a9为例,在它的链接脚本里面有:
这个SORT就是把里面的段按名称排序,因为定义段的时候引入数字,所有顺序就是.rti_fn.0 .rti_fn.1 .rti_fn.2 .rti_fn.3 .rti_fn.4 .rti_fn.5 .rti_fn.6这样,而INIT_DEVICE_EXPORT用的level3。
举个例子,如果按照你给的lcd和pwm,那应该会lcd在pwm的前面。
而这个顺序直接就决定了obj-init的顺序,实现代码见src/components.c
里面的注释里面有提到:
真正执行初始化的代码时在,本c文件的rt_components_board_init函数和rt_components_init函数
ta它的核心实现就是从段里面遍历一个个obj,然后取出obj对应的init函数指针,执行初始化。
所以段在里面的顺序就是init的执行顺序,这点可以在map文件中可以看到谁先谁后。
以我的为例:
那么问题来了,如果在同一个level的,顺序是怎么样的呢?
由于最后的init函数指针是进入到代码段的,所以谁(C文件)参与编译,谁就先被链接到指定的段里面,那么它的地址就靠前,就有点像FIFO结构那种感觉。
综上,要解决你的需求,如果不想改init-level,那么可以考虑从C文件的编译顺序来考虑,而C文件的编译顺序,跟C文件在目录和文件名是有关系的,可以去实践下。
建议在实践过程中,把init的过程打印出来,或者直接把RT_DEBUG_INIT宏打开。
以上,希望能帮助到你。
谢谢,我暂时也是这么解决的。正如回复的那句话:能解决,但感觉不那么完美。
其实系统可以增加一个参数.rti_fn.0 1 rti_fn.0 2 rti_fn.0 3.。。。。。。。。。
rti_fn.1 1 rti_fn.1 2。。。。。。。。
rti_fn.2 1 rti_fn.2 2 。。。。