- #define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL
-
- typedef CPU_INT32U CPU_SR;
-
- #if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
- #define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0
- #else
- #define CPU_SR_ALLOC()
- #endif
-
-
-
- #define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) (1)
- #define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) (2)
-
- #ifdef CPU_CFG_INT_DIS_MEAS_EN
-
- #define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \
- CPU_IntDisMeasStart(); } while (0)
-
- #define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \
- CPU_INT_EN(); } while (0)
-
- #else
-
- #define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0)
- #define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0)
- #endif
1. 当CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN时
这种方式最简单,即直接使用处理器的开中断和关中断指令来实现宏。但是不推荐使用这种方式,因为不支持中断嵌套,但是考虑到有些处理器或者编译器仅支持这种方式,不得不选择这种方式。
2. 当CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN时
这种方法稍复杂些,但可使CPU中断使能标志的状态在临界段前和临界段后不发生变化。
进入临界段前:
(1) Push/save 中断状态保存到堆栈中
(2) Disable 关闭中断
退出临界段:
(3) Pop/restore 恢复中断标志
3. 当CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL时
这种方法的前提是,用户使用的C编译器具有扩展功能。用户可获得程序状态字的值,这样就可把该值保存在C函数的局部变量中,而不必压到堆栈里。上面的宏定义就是采用的这种方式,也就是(1),(2)注释的地方。
4. 关于临界段,在文件os.h中也有几个相关的宏定义,这几个宏定义的含义会在后面跟大家讲
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN> 0u && defined(CPU_CFG_INT_DIS_MEAS_EN)
#define OS_SCHED_LOCK_TIME_MEAS_START() OS_SchedLockTimeMeasStart()
#else
#define OS_SCHED_LOCK_TIME_MEAS_START()
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u && defined(CPU_CFG_INT_DIS_MEAS_EN)
#define OS_SCHED_LOCK_TIME_MEAS_STOP() OS_SchedLockTimeMeasStop()
#else
#define OS_SCHED_LOCK_TIME_MEAS_STOP()
#endif
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u /* Deferred ISR Posts */
/* Lock the scheduler */
#define OS_CRITICAL_ENTER() \
do { \
CPU_CRITICAL_ENTER(); \
OSSchedLockNestingCtr++; \
if(OSSchedLockNestingCtr == 1u) { \
OS_SCHED_LOCK_TIME_MEAS_START(); \
} \
CPU_CRITICAL_EXIT(); \
} while (0)
/* Lock the scheduler but re-enable interrupts*/
#define OS_CRITICAL_ENTER_CPU_EXIT() \
do { \
OSSchedLockNestingCtr++; \
\
if(OSSchedLockNestingCtr == 1u) { \
OS_SCHED_LOCK_TIME_MEAS_START(); \
} \
CPU_CRITICAL_EXIT(); \
} while (0)
/* Scheduling occurs only if an interruptoccurs */
#define OS_CRITICAL_EXIT() \
do { \
CPU_CRITICAL_ENTER(); \
OSSchedLockNestingCtr--; \
if(OSSchedLockNestingCtr == (OS_NESTING_CTR)0) { \
OS_SCHED_LOCK_TIME_MEAS_STOP(); \
if(OSIntQNbrEntries > (OS_OBJ_QTY)0) { \
CPU_CRITICAL_EXIT(); \
OS_Sched0(); \
} else { \
CPU_CRITICAL_EXIT(); \
} \
} else { \
CPU_CRITICAL_EXIT(); \
} \
} while (0)
#define OS_CRITICAL_EXIT_NO_SCHED() \
do { \
CPU_CRITICAL_ENTER(); \
OSSchedLockNestingCtr--; \
if(OSSchedLockNestingCtr == (OS_NESTING_CTR)0) { \
OS_SCHED_LOCK_TIME_MEAS_STOP(); \
} \
CPU_CRITICAL_EXIT(); \
} while (0)
#else /* Direct ISR Posts */
#define OS_CRITICAL_ENTER() CPU_CRITICAL_ENTER()
#define OS_CRITICAL_ENTER_CPU_EXIT()
#define OS_CRITICAL_EXIT() CPU_CRITICAL_EXIT()
#define OS_CRITICAL_EXIT_NO_SCHED() CPU_CRITICAL_EXIT()
#endif