裸机多任务开发(Bare-Metal Multitasking Development)是指在没有操作系统的情况下,通过软件设计实现多任务运行的机制。
这种多任务实现依赖于时间分片或任务切换,任务轮流运行,但由于切换速度快,从外部看起来就像是同时进行的。
核心机制
时间分片与任务切换
逻辑多任务通过分配给每个任务一小段时间(称为时间片)来实现多个任务的轮流执行。
- 时间片分配: 每个任务在被调度到时运行一段时间,然后暂停并切换到下一个任务。
- 任务切换: 在任务切换时,保存当前任务的运行状态(上下文,例如寄存器和程序计数器),以便下次恢复。
任务调度
逻辑多任务依赖一个调度器来决定哪个任务应该运行。常见的调度策略有:
- 时间片轮转调度: 任务按固定顺序依次执行,每个任务占用固定的时间片。
- 优先级调度: 任务根据优先级执行,高优先级任务可以抢占低优先级任务。
- 事件驱动调度: 任务在满足某些条件或触发事件时被执行。
状态机设计
逻辑多任务常通过状态机设计来实现任务间的非阻塞切换:
- 每个任务在运行过程中处于某个状态,例如初始化、运行、等待、完成等。
- 主程序(Super Loop)中依次检查各任务的状态,并根据状态决定是否调用任务的功能。
中断机制
中断是逻辑多任务的重要部分,用于处理高优先级或异步事件:
- 硬件中断:当硬件事件(如按键触发、UART 接收)发生时,中断服务程序(ISR)可以立即执行。
- 定时器中断:通过定时器产生周期性中断,用于触发任务切换。
任务的上下文保存与恢复
为了实现任务切换,逻辑多任务需要在切换时保存任务的上下文(包括寄存器、堆栈指针等),并在下次运行时恢复这些信息。裸机系统通常通过以下方式实现上下文切换:
- 手动保存和恢复:由程序员在任务切换时明确保存和恢复上下文。
- 自动保存和恢复:某些嵌入式架构(如 ARM Cortex-M)在中断时自动保存部分寄存器。
实现
任务定时
1 | // 定时任务 1ms 触发一次 |