在实时操作系统中,任务调度是系统实现多任务并发执行的核心机制。但在某些场景下,我们需要临时关闭任务调度,以确保某段代码在执行过程中不被打断。下面将详细介绍这两个接口的应用场景及实现原理。
1. 关闭调度的应用场景
关闭任务调度的主要目的是确保某些关键代码在执行过程中不被其他任务中断,从而保证代码执行的原子性和数据的一致性。常见的应用场景包括:
1.1 临界区保护
在访问共享资源,如全局变量、外设硬件等,关闭调度可以防止其他任务,在当前任务未完对共享资源成操作之前访问这些资源。
1.2 时序完整性
在读写外部硬件设备时,需要连续执行一系列操作且不应被中断,关闭调度可以确保整个操作序列的完整性,以正确读写设备。
1.3 数据的一致性
在对一些关键数据结构进行修改时,关闭调度可以避免数据被其他任务读取或修改,确保数据的一致性。
2. 关闭调度接口OSSchedLock
2.1 OSSchedLock接口流程
- 防止从中断服务程序(ISR)中调用:在使用
OS_CFG_CALLED_FROM_ISR_CHK_EN
配置项使能时,OSSchedLock
会检查是否在ISR中调用,如果是,则返回错误码OS_ERR_SCHED_LOCK_ISR
。- 检查系统状态:确保系统已经启动,如果系统尚未启动,则返回错误码
OS_ERR_OS_NOT_RUNNING
。- 防止嵌套溢出:
OSSchedLock
会检查嵌套计数器OSSchedLockNestingCtr
,防止其值超过250。- 进入临界区:使用
CPU_CRITICAL_ENTER
关闭中断,增加OSSchedLockNestingCtr
的值,并启动调度锁时间测量(如果使能了该功能),退出临界区。
2.2 OSSchedLock接口流程图
3. OSSchedUnlock
打开调度接口
3.1 OSSchedUnlock接口流程
- 防止从ISR中调用:与
OSSchedLock
类似,OSSchedUnlock
也会检查是否在ISR中调用,如果是,则返回错误码OS_ERR_SCHED_UNLOCK_ISR
。- 检查系统状态:确保系统已经启动,如果系统尚未启动,则返回错误码
OS_ERR_OS_NOT_RUNNING
。- 检查调度器锁定状态:如果调度器未锁定,则返回错误码
OS_ERR_SCHED_NOT_LOCKED
。- 进入临界区:使用
CPU_CRITICAL_ENTER
关闭中断,减少OSSchedLockNestingCtr
的值。如果OSSchedLockNestingCtr
值大于0,说明调度器仍然被锁定,返回错误码OS_ERR_SCHED_LOCKED
。- 调度解锁:如果
OSSchedLockNestingCtr
值为0,调用OSSched
函数重新启用任务调度,并返回错误码OS_ERR_NONE
。
3.2 OSSchedUnlock接口流程图
4. 注意事项
- 必须成对调用:必须确保
OSSchedLock
和OSSchedUnlock
成对调用,以避免系统调度器状态不一致。 - 避免长时间锁定:避免长时间锁定调度器,以防止其他任务无法得到执行,影响系统实时性。
- 嵌套深度控制:注意控制调度器锁定的嵌套深度,防止过度使用导致系统调度问题。
5. 总结
在实时操作系统中,关闭和打开任务调度是确保系统执行关键代码时保持原子性和数据一致性的重要手段。通过正确使用 OSSchedLock 和 OSSchedUnlock 接口,我们可以有效地控制任务调度,实现高效、稳定的实时系统。