【UCOSIII】【中断管理、时间管理】OS_CRITICAL_ENTER()、OS_CRITICAL_EXIT()、OSTimeDlyHMSM

中断管理

2种方式:直接发布、延时发布

OS_CFG_ISR_POST_DEFERRED_EN = 1 延时发布 中断消息  defer ISR POST En使能

OS_CFG_ISR_POST_DEFERRED_EN = 0 直接发布 中断消息

1.延时发布

#if OS_CFG_ISR_POST_DEFERRED_EN > 0u                             /* Deferred ISR Posts ------------------------------ */
                                                                 /* Lock the scheduler                                */
/*if:如果采用 延迟发布 中断处理*/
//访问全局资源OSSchedLockNestingCtr 
//才 关中断CPU_CRITICAL_ENTER() 打开中断CPU_CRITICAL_EXIT()
//对临界段代码的保护还是采用调度器加锁的方式

//进入临界区 给 调度器上锁
#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_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)

2.直接发布

/*else: 直接发布 中断服务程序 */
//关中断 保护临界代码区
	//CPU_CRITICAL_ENTER()    最终调用  CPU_SR_Save()  在cpu_a.asm 用汇编定义
#define  OS_CRITICAL_ENTER()                    CPU_CRITICAL_ENTER()	

//开中断 退出
	//CPU_CRITICAL_EXIT()	最终调用 CPU_SR_Restore()  在cpu_a.asm 用汇编定义
#define  OS_CRITICAL_EXIT()                     CPU_CRITICAL_EXIT()

#endif

时间管理

1. OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);

    hour:0-99

    minutes:0-59

    seconds:0-59

    milli:0-999

    opt:OS_OPT_TIME_HMSM_STRICT

#if OS_CFG_TIME_DLY_HMSM_EN > 0u
/* 任务延时函数 */
void  OSTimeDlyHMSM (CPU_INT16U   hours,	//0-99
                     CPU_INT16U   minutes,	//0-59
                     CPU_INT16U   seconds,	//0-59
                     CPU_INT32U   milli,	//0-999
                     OS_OPT       opt,		//OS_OPT_TIME_HMSM_STRICT严格参数
                     OS_ERR      *p_err)
{
#if OS_CFG_ARG_CHK_EN > 0u
    CPU_BOOLEAN  opt_invalid;
    CPU_BOOLEAN  opt_non_strict;
#endif
    OS_OPT       opt_time;
    OS_RATE_HZ   tick_rate;
    OS_TICK      ticks;
    CPU_SR_ALLOC();

#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
    if (OSIntNestingCtr > (OS_NESTING_CTR)0u) {             /* Not allowed to call from an ISR                        */
       *p_err = OS_ERR_TIME_DLY_ISR;
        return;
    }
#endif

    if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) {       /* Can't delay when the scheduler is locked               */
       *p_err = OS_ERR_SCHED_LOCKED;
        return;
    }

    opt_time = opt & OS_OPT_TIME_MASK;                      /* Retrieve time options only.                            */
    switch (opt_time) {
        case OS_OPT_TIME_DLY:
        case OS_OPT_TIME_TIMEOUT:
        case OS_OPT_TIME_PERIODIC:
             if (milli == (CPU_INT32U)0u) {                 /* Make sure we didn't specify a 0 delay                  */
                 if (seconds == (CPU_INT16U)0u) {
                     if (minutes == (CPU_INT16U)0u) {
                         if (hours == (CPU_INT16U)0u) {
                            *p_err = OS_ERR_TIME_ZERO_DLY;
                             return;
                         }
                     }
                 }
             }
             break;

        case OS_OPT_TIME_MATCH:
             break;

        default:
            *p_err = OS_ERR_OPT_INVALID;
             return;
    }

#if OS_CFG_ARG_CHK_EN > 0u                                  /* Validate arguments to be within range                  */
    opt_invalid = DEF_BIT_IS_SET_ANY(opt, ~OS_OPT_TIME_OPTS_MASK);
    if (opt_invalid == DEF_YES) {
       *p_err = OS_ERR_OPT_INVALID;
        return;
    }

    opt_non_strict = DEF_BIT_IS_SET(opt, OS_OPT_TIME_HMSM_NON_STRICT);
    if (opt_non_strict != DEF_YES) {
         if (milli   > (CPU_INT32U)999u) {
            *p_err = OS_ERR_TIME_INVALID_MILLISECONDS;
             return;
         }
         if (seconds > (CPU_INT16U)59u) {
            *p_err = OS_ERR_TIME_INVALID_SECONDS;
             return;
         }
         if (minutes > (CPU_INT16U)59u) {
            *p_err = OS_ERR_TIME_INVALID_MINUTES;
             return;
         }
         if (hours   > (CPU_INT16U)99u) {
            *p_err = OS_ERR_TIME_INVALID_HOURS;
             return;
         }
    } else {
         if (minutes > (CPU_INT16U)9999u) {
            *p_err = OS_ERR_TIME_INVALID_MINUTES;
             return;
         }
         if (hours   > (CPU_INT16U)999u) {
            *p_err = OS_ERR_TIME_INVALID_HOURS;
             return;
         }
    }
#endif

                                                            /* Compute the total number of clock ticks required..     */
                                                            /* .. (rounded to the nearest tick)                       */
    //默认 系统时钟节拍:200Hz 5ms
	tick_rate = OSCfg_TickRate_Hz;
    ticks     = ((OS_TICK)hours * (OS_TICK)3600u + (OS_TICK)minutes * (OS_TICK)60u + (OS_TICK)seconds) * tick_rate
              + (tick_rate * ((OS_TICK)milli + (OS_TICK)500u / tick_rate)) / (OS_TICK)1000u;

    if (ticks > (OS_TICK)0u) {
        OS_CRITICAL_ENTER();
        OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY;
        OS_TickListInsert(OSTCBCurPtr,
                          ticks,
                          opt_time,
                          p_err);
        if (*p_err != OS_ERR_NONE) {
             OS_CRITICAL_EXIT_NO_SCHED();
             return;
        }
        OS_RdyListRemove(OSTCBCurPtr);                      /* Remove current task from ready list                    */
        OS_CRITICAL_EXIT_NO_SCHED();
        OSSched();                                          /* Find next task to run!                                 */
       *p_err = OS_ERR_NONE;
    } else {
       *p_err = OS_ERR_TIME_ZERO_DLY;
    }
}
#endif

2. OSTimeDly()

void  OSTimeDly (OS_TICK   dly,
                 OS_OPT    opt,
                 OS_ERR   *p_err)

你可能感兴趣的:(UCOSIII)