首先了解一下和中断有关的三个寄存器
ucos临界段
CPU_CRITICAL_ENTER(); 关闭中断
CPU_CRITICAL_EXIT(); 打开中断
OS_CFG_ISR_POST_DEFERRED_EN == 1
OSSchedLockNestingCtr 用于中断嵌套
由于OSSchedLockNestingCtr 属于共享资源 保证原子性 , 在进行操作之前需要进行关闭中断
OS_CRITICAL_ENTER()
进入临界段代码 锁调度器 , 仍能中断 。主要保护任务间的共享资源
OS_CRITICAL_EXIT() 退出临界段
OS_CFG_ISR_POST_DEFERRED_EN == 0
#define OS_CRITICAL_ENTER() CPU_CRITICAL_ENTER() 通关开关中断的方式实现对代码保护
中断和任务间的共享资源不能通过关调度器的方式 ,需采用关中断的方式 。
当然最好选择队列。
freeRTOS临界段
是向―寄存器BASEPRI写入宏, 低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断就会被屏蔽
freeRTOS 中断服务程序要调用freeRTOS的内核API接口则中断
优先级低于配置宏(configMAX_SYSCALL_INTERRUPT_PRIORITY)
的值。 高于宏的中断不能调用内核API接口。 freeRTOS不允许临界
区无法屏蔽的中断调用系统API,防止低优先级的中断嵌套
为什么两种机制有这么大的不同呢?
两个线程如果同时处理内核对象 ,则系统可能发生紊乱(中断也算作一个线程) 。
FreeRTOS :
内核API在处理链表操作时会进入临界段,屏蔽低优先级的中断,线程和中断不可能同时调用内核API,所以低优先级的中断可以调用(末尾带有ISR),而高优先级不能调用。 高优先级处理类似于一个前后台系统。低configMAX_SYSCALL_INTERRUPT_PRIORITY的中断之间不会嵌套以保证系统API的操作的”原子性“。
UCOS :
内核对象API中在操作链表时进入关闭中断 CPU_CRITICAL_ENTER()
此时不能响应中断。 所以中断和线程不会同时操作内核对象 。任务和中断的内核对象API无差别。