RT-Thread 实践笔记:启动流程、驱动分层与内存

2023/03/10

RT-Thread 实践笔记:启动流程、驱动分层与内存

自动初始化机制

RT-Thread 的组件自动初始化通过 INIT_*_EXPORT 系列宏完成,初始化顺序如下:

rti_start --> 0
BOARD_EXPORT --> 1
rti_board_end --> 1.end

DEVICE_EXPORT --> 2
COMPONENT_EXPORT --> 3
FS_EXPORT --> 4
ENV_EXPORT --> 5
APP_EXPORT --> 6

rti_end --> 6.end

其中 1.end 之前的部分在 rt_components_board_init() 中调用;2 ~ 6.end 的部分由 rt_components_init() 调用,最终是在 main 线程(main_thread_entry)中执行的。使用该机制时,驱动或组件的初始化函数必须用 INIT_BOARD_EXPORT(fn)、INIT_DEVICE_EXPORT(fn)、INIT_APP_EXPORT(fn) 等宏导出。

启动流程

  1. rtthread_startup()
  2. rt_hw_board_init():系统启动后第一个调用的初始化函数,需要先初始化好串口,方便调试
  3. rt_components_board_init()(即 INIT_BOARD_EXPORT 导出的函数)
  4. 显示版本号、初始化 timer、调度器
  5. 创建 main 线程、定时器线程(软件定时器)、idle 线程
  6. 启动调度器
  7. main 线程中执行 rt_components_init():INIT_PREV_EXPORT → INIT_DEVICE_EXPORT → INIT_COMPONENT_EXPORT → INIT_ENV_EXPORT → INIT_APP_EXPORT

编程实践:各 EXPORT 层级放什么

  1. 硬件底层驱动都使用 INIT_BOARD_EXPORT 导出,完成所有硬件外设的初始化
  2. PREV EXPORT:看具体情况,有些操作需要在设备驱动之前完成
  3. 设备驱动使用 INIT_DEVICE_EXPORT,某个设备可能使用多个硬件外设
  4. COMPONENT 适合给中间件使用,例如 uORB 这种通讯组件
  5. ENV 初始化系统运行环境相关的,看具体情况
  6. APP EXPORT 放系统应用,创建具体的应用任务

驱动分层

  1. 硬件底层驱动(Drivers)
  2. 设备驱动(Device Drivers)

应用层最好直接使用设备驱动,也可以直接调用设备底层驱动;但直接使用底层驱动的应用程序不具备可移植性,只有比较特殊的需求才这么做。

两个实用驱动组件

组件说明
hwtimer计时器,用来做精准倒计时;驱动主要解决定时器溢出的问题
cputime给系统一个高精度时钟,用来计时;需要一个 hwtimer 支持

内存笔记:堆、C 语言的栈与线程的栈

堆的末尾是 SRAM END,所以堆其实还挺大的。

这里需要区分 C 语言的栈和线程的栈:

遗留问题:可不可以这么说——一个线程的栈永远不会超过 C 语言的栈?