FreeRTOS-临界区代码保护及调度器挂起与恢复

临界区代码保护

临界区是指那些必须完整运行的区域,在临界区中的代码必须完整运行,不能被打断。对于临界区,FreeRTOS使用taskENTER_CRITICAL() 、 taskENTER_CRITICAL_FROM_ISR() 、 taskEXIT_CRITICAL() 、
taskEXIT_CRITICAL_FROM_ISR(x)四个宏来保护临界区。这些宏通常会通过修改BASEPRI寄存器来禁用中断,从而确保在临界区执行时,不会有更高优先级的中断打断。

/* 进入临界区 */
#define taskENTER_CRITICAL() portENTER_CRITICAL()
#define portENTER_CRITICAL() vPortEnterCritical()
/* 中断中进入临界区 */
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
/* 退出临界区 */
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
#define portEXIT_CRITICAL() vPortExitCritical()
/* 中断中退出临界区 */
#define taskEXIT_CRITICAL_FROM_ISR(x) portCLEAR_INTERRUPT_MASK_FROM_ISR(x)
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
  1. 任务级:在任务级进入临界区时,会关闭中断,确保在执行期间不会进行任务切换。该临界区是可以嵌套的,即在程序中可以重复地进入临界区,只要后续重复退出相同次数的临界区即可。
  2. 中断级:在中断级进入临界区时,同 样 是 将 BASEPRI 寄 存 器 设 置 为 宏configMAX_SYSCALL_INTERRUPT_PRIORITY 的值,以达到关闭中断的效果,但与从任务进入临界区不同的是,从中断进入临界区时不支持嵌套。

使用格式示例:

taskENTER_CRITICAL() ;
{
        … …	/* 临界区 */
}
taskEXIT_CRITICAL()	;
uint32_t  save_status;
save_status  = taskENTER_CRITICAL_FROM_ISR(){
        … …	/* 临界区 */
}
taskEXIT_CRITICAL_FROM_ISR(save_status );

注意:

  1. 确保每次调用 进入临界区的函数必须配对退出临界区的函数,以避免中断状态不正确的情况。
  2. 若taskENTER_CRITICAL()是用于从非中断中进入临界区,不能在中断服务函数中调用函数taskENTER_CRITICAL(),否则就会通过断言报错。
  3. 尽量缩短临界区的执行时间,避免长时间禁止任务调度,这样可以减少对系统响应性的影响。
  4. 中断级进入临界区时不支持嵌套调用,注意保持中断的状态一致性,避免由于多次禁用中断而导致的状态混乱。

调度器挂起与恢复

在执行临界区代码时,FreeRTOS还需要管理任务调度器的状态。调用taskENTER_CRITICAL()时,FreeRTOS会暂时挂起任务调度,这意味着在临界区内不会进行任务切换,以避免因任务调度导致的数据不一致。一旦临界区代码执行完毕,调用taskEXIT_CRITICAL()恢复调度器。这时,调度器会检查是否有高优先级任务需要运行,从而确保系统能在完成临界区的操作后,及时响应其他任务。

函数描述
vTaskSuspendAll()挂起任务调度器
xTaskResumeAll()恢复任务调度器

使用格式示例:

vTaskSuspendAll() ;
{
        … …	/* 内容 */
}
xTaskResumeAll()	;

特点:

  1. 与临界区不同的是,挂起任务调度器不关闭中断,仅防止任务之间的资源争夺,中断依旧可以响应。
  2. 挂起调度器的方式,适用于临界区位于任务与任务之间;既不用去延时中断,又可以做到临界区的安全。

注意:

  1. 尽量缩短挂起时间:挂起调度器的时间应尽量短,以免影响系统的实时性能和响应能力。
  2. 嵌套调用:可以多次调用 vTaskSuspendAll(),但需要确保每次都对应调用 xTaskResumeAll() 来恢复调度。
  3. 避免死锁:确保在挂起调度器时,不会导致其他任务或中断依赖于当前执行的任务,从而引发死锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值