本文为随笔,更多细节可关注微信公众号:emOsprey
uCOS II
MAX_SYSCALL_INTERRUPT_PRIORITY EQU 3 ; 屏蔽低于优先级 2 的中断,即抢占优先级设置为 0~2 将被屏蔽,3不屏蔽 OS_CPU_SR_SaveMRS R0, BASEPRI ; 读取 PRIMASK 到R0,R0为返回值 MOV R1, #(MAX_SYSCALL_INTERRUPT_PRIORITY << 6) ; 优先级分组为 2 , 共四位优先级 MSR BASEPRI, R1 ; 关闭中断BX LR ; 返回;MRS R0, PRIMASK ; 读取PRIMASK到R0,R0为返回值 ;CPSID I ; PRIMASK = 1,关中断( NMI 和硬件 FAULT 可以响应);BX LR OS_CPU_SR_RestoreMSR BASEPRI, R0 ; 读取 R0 到 PRIMASK 中,R0为参数BX LR ; 返回;MSR PRIMASK, R0 ; 读取 R0 到 PRIMASK 中,R0为参数;BX LR ; 返回
FreeRTOS
An aside: FreeRTOS API functions that are safe to be called from an interrupt use BASEPRI to implement interrupt safe critical sections. BASEPRI is set to configMAX_SYSCALL_INTERRUPT_PRIORITY when the critical section is entered, and 0 when the critical section is exited. Many bug reports are received that claim BASEPRI should be returned to its original value on exit, and not just set to zero, but the Cortex-M NVIC will never accept an interrupt that has a priority below that of the currently executing interrupt - no matter what BASEPRI is set to. An implementation that always sets BASEPRI to zero will result in faster code execution than an implementation that stores, then restores, the BASEPRI value (when the compiler’s optimiser is turned on).
另外:可以安全地从中断调用的FreeRTOS API函数使用BASEPRI来实现中断安全的关键部分。输入临界区时BASEPRI设置为configMAX_SYSCALL_INTERRUPT_PRIORITY,退出临界区时设置为0。收到许多错误报告声称BASEPRI应该在退出时返回其原始值,而不仅仅设置为零,但Cortex-M NVIC永远不会接受优先级低于当前正在执行的中断的中断 - 无论是BASEPRI的目标是什么。始终将BASEPRI设置为零的实现将导致比存储然后恢复BASEPRI值的实现更快的代码执行(当编译器的优化器打开时)。
修改优先级(4 bit 优先级)
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 5