Zephyr系统线程

Creative Commons
本作品采用知识共享署名

本文说明Zephyr系统线程和使用配置事项。

系统线程是内核初始化过程中自动启动的两个线程,Zephyr内核自动启动两个线程。

主线程

Zephyr在内核启动过程中,完成_SYS_INIT_LEVEL_PRE_KERNEL_1_SYS_INIT_LEVEL_PRE_KERNEL_2等级的基础硬件初始化后就启动主线程bg_thread_main,主线程内在主要完成以下任务:

  • _SYS_INIT_LEVEL_POST_KERNEL等级的设备初始化

  • _SYS_INIT_LEVEL_APPLICATION等级的设备初始化

  • 启动静态初始化线程

  • 初始化SMP

  • 跳转到main()处理

这里的main()就是Zephyr的应用程序main()入口。

主线程的优先级由CONFIG_MAIN_THREAD_PRIORITY指定,默认配置为最高的可抢占优先级0,如果内核被配置为不支持抢占线程,则主线程优先级默认为最低的协作线程优先级-1。一般情况下不建议对主线程优先级进行配置。需要注意的是由于主线程的优先级默认比所有抢占优先级都高,应用程序在main()中不要随意做”busy loop”,否则会导致其它低优先级抢占式线程无法运行。

主线程的堆栈由CONFIG_MAIN_STACK_SIZE指定,默认为1K。由于应用程序的main()是在主线程中执行,当应用程序在main()中使用大量堆栈时,需要增加CONFIG_MAIN_STACK_SIZE的大小。

主线程是执行内核初始化和应用程序main()时必不可少的线程, 因此在创建主线程时会指定K_ESSENTIAL表示其不能被中止,中止主线程会引发致命的系统错误。 但是当main()返回后主线程会主动移掉K_ESSENTIAL标记此时主线程可以正常终止并且不会引发错误。

main线程的启动流程可以参考Zephyr如何运行到main

空闲线程

当系统没有其他工作要做时,休眠线程将执行。在支持硬件休眠的SOC架构下空闲线程会通过电源管理系统让SOC进入休眠以节省电量, 否则空闲线程只会执行“busy loop” 。 只要系统在运行,空闲线程就一直存在并且永远不会终止。

空闲线程始终使用系统配置的最低线程优先级。 如果系统被配置为不支持可抢占优先级时,空闲线程将变成一个协作线程,因此空闲线程会重复让出 CPU 以允许其他线程在需要时运行。

空闲线程是必不可少的线程,在创建空闲线程时会指定K_ESSENTIAL表示其不能终止,中止空闲线程会引发致命的系统错误。

空闲线程的堆栈由CONFIG_IDLE_STACK_SIZE指定,由于空闲线程内做的工作需要堆栈不大,因此默认配置为256字节,一些不同的CPU体系架构会有稍微大一点的堆栈,但都不会超过1K字节。

空闲线程相关流程可参考Zephyr电源管理-Tickless-Idle

其它

主线程和空闲线程是Zephyr系统不能缺少的系统线程,同时根据应用程序指定的内核和主板配置选项,也可能产生额外的系统线程。 例如,启用系统系统工作队列会产生一个系统线程为提交给它的工作项提供服务。

参考

https://docs.zephyrproject.org/latest/kernel/services/threads/system_threads.html