#进入临界段方式:OS_CRITICAL_METHOD==?
//OS_CRITICAL_METHOD = 1 :
//OS_CRITICAL_METHOD = 2 :
//OS_CRITICAL_METHOD = 3 :
#define OS_CRITICAL_METHOD 3
#if OS_CRITICAL_METHOD == 3
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
#endif
##方式1:
直接用处理器开关中断指令开关中断,这种没有现场保护的方式造成无法进行临界区嵌套,如果有两层临界区,那么里层退出保护时候直接开了中断,而外层的临界区还没有结束。(关几次中断都是关中断,开一次中断就全开了)
##方式2:
这种方式先把中断状态压入堆栈保存起来,然后关中断。恢复中断时,直接恢复栈中的中断状态。但是很少使用,看了下面这篇博文的理解是编译器很可能无法很好的处理在临界段内使用堆栈造成的冲突。
http://www.cnblogs.com/shafei/p/3524919.html?utm_source=tuicool&utm_medium=referral
但是又产生了新的疑惑,中断嵌套等完好的堆栈操作对于编译器是怎么优化处理的。待解决
##方式3:
把中断状态保存在一个局部变量中,当退出临界态时候直接恢复局部变量,但是需要内核支持对寄存器的直接读写。
#OS_CPU_SR_Save()与OS_CPU_SR_Restore()
OS_CPU_SR_Save
MRS R0, PRIMASK ;把PRIMASK的装填读取到R0中。
CPSID I ;关中断
BX LR ;返回
OS_CPU_SR_Restore
MSR PRIMASK, R0 ;把R0的值写入到寄存器PRIMASK中
BX LR ;返回
CPSID CPSIE 快速的开关中断指令
CPSID CPSIE 用于快速的开关中断。UCOSII中在
指令 参数 寄存器值 行为
CPSID I PRIMASK=1, ;关中断
CPSIE I PRIMASK=0, ;开中断
CPSID F FAULTMASK=1, ;关异常
CPSIE F FAULTMASK=0, ;开异常
注:I:IRQ ; F:FIQ。在Cortex内核中没有FIQ中断,都按IRQ处理。