.. _kernel_system_thread: 系统线程 ######### 系统线程是内核初始化过程中自动启动的两个线程,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``\ 标记此时主线程可以正常终止并且不会引发错误。 空闲线程 ======== 当系统没有其他工作要做时,休眠线程将执行。在支持硬件休眠的SOC架构下空闲线程会通过电源管理系统让SOC进入休眠以节省电量, 否则空闲线程只会执行“busy loop” 。 只要系统在运行,空闲线程就一直存在并且永远不会终止。 空闲线程始终使用系统配置的最低线程优先级。 如果系统被配置为不支持可抢占优先级时,空闲线程将变成一个协作线程,因此空闲线程会重复让出 CPU 以允许其他线程在需要时运行。 空闲线程是必不可少的线程,在创建空闲线程时会指定\ ``K_ESSENTIAL``\ 表示其不能终止,中止空闲线程会引发致命的系统错误。 空闲线程的堆栈由\ ``CONFIG_IDLE_STACK_SIZE``\ 指定,由于空闲线程内做的工作需要堆栈不大,因此默认配置为256字节,一些不同的CPU体系架构会有稍微大一点的堆栈,但都不会超过1K字节。 其它 ==== 主线程和空闲线程是Zephyr系统不能缺少的系统线程,同时根据应用程序指定的内核和主板配置选项,也可能产生额外的系统线程。 例如,启用系统系统工作队列会产生一个系统线程为提交给它的工作项提供服务。 参考 ==== https://docs.zephyrproject.org/latest/kernel/services/threads/system_threads.html