1. 临界段代码,也叫临界区,是指那些必须完整连续运行,不可被打断的代码段。在uC/OS-III中存在大量的临界段代码。

  2. 中断处理程序和任务都会访问的临界段代码,需要使用关中断的方法加以保护;仅由任务访问的临界段代码,可以通过给调度器上锁的方法来保护。

  3. 在uC/OS-III中,使用宏OS_CRITICAL_ENTER()进入临界区;使用宏OS_CRITICAL_EXIT()和OS_CRITICAL_EXIT_NO_SCHED()退出临界区。
    注:上面的三个宏是uC/OS-III内部的定义,外部的任务不能使用。

  4. uC/OS-III可以使用两种方式保护临界段代码:关中断或锁定调度器。
    OS_CFG_ISR_POST_DEFERRED_EN为0,使用关中断的方式;OS_CFG_ISR_POST_DEFERRED_EN为1,使用锁定调度器方式。
    注:OS_CFG_ISR_POST_DEFERRED_EN在os_cfg.h文件中定义

5.有关保护临界段代码的宏定义的代码位于os.h文件中,87行 - 141行

#if OS_CFG_ISR_POST_DEFERRED_EN > 0u                           // 延迟发布模式,采用锁定调度器方式

// 进入临界区
#define  OS_CRITICAL_ENTER()                                       
         do {                                                      
             CPU_CRITICAL_ENTER();                                 
             OSSchedLockNestingCtr++;                              
             if (OSSchedLockNestingCtr == 1u) {                    
                 OS_SCHED_LOCK_TIME_MEAS_START();                  
             }                                                     
             CPU_CRITICAL_EXIT();                                  
         } while (0)
// 进入临界区且中断已关闭
#define  OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT()                     
         do {                                                      
             OSSchedLockNestingCtr++;                              
             if (OSSchedLockNestingCtr == 1u) {                    
                 OS_SCHED_LOCK_TIME_MEAS_START();                  
             }                                                     
             CPU_CRITICAL_EXIT();                                  
         } while (0)
// 退出临界区
#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                                                           // 直接发布模式,采用关中断方式

#define  OS_CRITICAL_ENTER()              CPU_CRITICAL_ENTER()  // 进入临界区
#define  OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT()                  // 进入临界区
#define  OS_CRITICAL_EXIT()               CPU_CRITICAL_EXIT()   // 退出临界区
#define  OS_CRITICAL_EXIT_NO_SCHED()      CPU_CRITICAL_EXIT()   // 退出临界区

#endif
  1. 再深入研究一下
    `
    #define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) // 保存CPU的状态寄存器并禁止中断
    #define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) // 恢复CPU状态寄存器的值

#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



7. 说明 
上面的代码中涉及到计算中断关闭时间或锁定调度器时间的部分,这里不再做详细说明,以后用到之后再详细解释。

8. 注意 
在使用进入临界区和退出临界区的宏定义时,需要在使用前声明一个宏CPU_SR_ALLOC(),该宏的定义位于cpu.h文件中,295行 - 299行

#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)

#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 // 声明cpu_sr变量,临时存储CPU的状态寄存器的值

#else

#define CPU_SR_ALLOC()

#endif
`


来源:https://blog.csdn.net/linuxweiyh/java/article/details/72724121