文章目录
本笔记基于 Zephyr 版本 2.6.0-rc2
前言
本人正在学习 Zephyr,一个可移植性较强,可以兼容多种开发板及物联网设备的操作系统,如果你感兴趣,可以点此查看我的 学习笔记总述 进行了解!
Scheduling - (调度)
内核基于优先级的调度程序允许应用程序的线程共享 CPU。
1. Concepts - (概念)
调度程序确定在任何时间点允许执行哪个线程,该线程称为当前线程(current thread)。
在不同的时间点,可以让调度程序有机会更改当前线程的身份。这些点称为重新计划点(reschedule points)。一些潜在的重新计划点是:
- 线程从运行状态到挂起或等待状态的过渡,例如通过
k_sem_take()
或k_sleep()
- 将线程转换为就绪状态(ready state),例如通过
k_sem_give()
或k_thread_start()
- 处理中断后返回线程上下文
- 当正在运行的线程调用时
k_yield()
当线程自动发起操作将自身转换为挂起或者等待状态时,该线程会进入睡眠状态(sleep)。
每当调度程序更改当前线程的标识时,或者当 ISR 替换当前线程的执行时,内核都会首先保存当前线程的 CPU 寄存器值。当线程之后恢复执行时,将恢复这些寄存器的值。
2. Scheduling Algorithm - (调度算法)
内核的调度程序选择优先级最高的就绪(ready)线程作为当前线程。当存在多个具有相同优先级的就绪(ready)线程时,调度程序将选择等待时间最长的线程。
Note: ISR 的执行优先于线程执行,因此,除非屏蔽了中断,否则随时可以用 ISR 替换当前线程的执行。这适用于协作线程和抢占线程。
可以使用就绪(ready)队列实现的几种选择之一来构建内核,当添加多个线程时,可以在代码大小,恒定因子运行时开销和性能扩展之间提供不同的选择:
-
Simple linked-list ready queue (
CONFIG_SCHED_DUMB
) :
调度程序就绪队列将实现为简单的无序列表,对单线程来说,具有非常快的恒定时间性能和非常小的代码大小。应该在代码大小受限的系统上选择此实现,该系统在任何给定时间都不会在队列中看到超过少数(可能是 3 个) 可运行线程。在大多数平台(未使用 red/black tree) 上,这节省了约 2k 的代码大小。 -
Red/black tree ready queue (