循环调度
循环 (RR) 是一个简单的调度策略,其中每个系统时钟周期都以循环顺序切换到下一个线程的上下文结束。对于 MiROS RTOS,您已经有了在最后调用调度程序 (OS_sched()) 的 SysTick_Handler() ISR。然后,您的工作归结为在每次调用调度程序时按循环顺序设置 OS_next 指针。
起点
在实现新功能(例如调度程序)时,当您尽早让某些东西正常工作时,通常更容易取得进展。为此,您不需要立即设计良好和通用的代码。该视频显示了一个足够好的起点,该起点由硬编码的 if 语句组成,该语句将OS_next指针分配给当前正在运行的线程以外的另一个闪烁线程。
通过重构改进设计
一旦你有一个工作系统,你就可以逐渐发展它,让它在每一步都正常工作。在这个称为重构的过程中,您的目标是在不更改外部行为的情况下改进内部设计。
对于调度程序实现,最重要的设计决策涉及表示启动的线程,以便 MiROS 内核可以按循环顺序排列它们,从而有效地在 OS_sched() 函数中设置OS_next指针。
使用断言
每个重要的软件都会做出内部假设。例如,MiROS 内核中的“线程注册表”是一个简单的指针数组,大小最多为 32 个线程。因此,内核假定应用程序不能启动超过那么多的线程。如果超过线程数,通常的设计将从 OSThread_start() 返回错误代码。但是应用程序没有任何合理的方法来处理此类错误,而不是更改应用程序以启动更少的线程。在这种情况下,使用断言可以简化内核和应用程序,如视频所示。
初始化时间线
初始化时间线是RTOS设计的一个重要方面。内核首先通过调用 OS_init() 进行初始化。然后通过 BSP_init() 初始化板级支持包,但这不应启用中断,因为系统尚未准备好接收中断。随后,启动组成应用程序的所有线程。最后,您可以通过 OS_run() API 将控制权转移到内核,该 API 配置和启用中断并执行第一个上下文切换。OS_run() 放在 main() 的末尾,永远不会返回。
结语
MiROS RTOS [1] 终于实现了自主运行,有效地为您的所有线程提供了一个分时环境。但是你仍然需要对轮询 BSP_delay() 函数中可怕的 CPU 周期浪费做一些事情。借助上下文切换魔术,您可以通过将上下文从延迟线程切换出去并仅在延迟过后切换回上下文来显着提高 CPU 效率。这种高效的等待称为阻塞。