uC/OS-III之时间管理

本文详细解析了uC/OS-III操作系统中OSTimeDly()和OSTimeDlyHMSM()两个时间管理函数的工作原理及源代码实现细节。介绍了这两个函数如何通过更改任务状态、调整任务调度来实现任务延时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.uC/OS-III的时间管理函数的主要工作是改变当前任务的状态,把任务添加到时钟节拍轮中,同时把任务从任务就绪表中删除,最后执行调度程序。

2.OSTimeDly()函数
OSTimeDly()函数的源代码位于os_time.c文件,79行 - 138行

void  OSTimeDly (OS_TICK   dly,          // 延时长度
                 OS_OPT    opt,          // 选项:相对模式、周期模式、绝对模式
                 OS_ERR   *p_err)        // 函数返回的错误代码
{
    CPU_SR_ALLOC();                      // 宏定义,声明变量cpu_sr,用来存储CPU的状态寄存器的值

#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) {        // 不允许从ISR中调用该函数
       *p_err = OS_ERR_TIME_DLY_ISR;
        return;
    }
#endif

    if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) {  // 在锁定调度器的情况下,不允许延时
       *p_err = OS_ERR_SCHED_LOCKED;
        return;
    }

    switch (opt) {
        case OS_OPT_TIME_DLY:
        case OS_OPT_TIME_TIMEOUT:
        case OS_OPT_TIME_PERIODIC:
             if (dly == (OS_TICK)0u) {                 // 0表示不延时
                *p_err = OS_ERR_TIME_ZERO_DLY;
                 return;
             }
             break;
        case OS_OPT_TIME_MATCH:
             break;
        default:
            *p_err = OS_ERR_OPT_INVALID;
             return;
    }

    OS_CRITICAL_ENTER();                         // 进入临界区
    OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY;  // 更改当前任务的状态
    OS_TickListInsert(OSTCBCurPtr,               // 把当前任务添加到时钟节拍轮中
                      dly,
                      opt,
                      p_err);
    if (*p_err != OS_ERR_NONE) {
         OS_CRITICAL_EXIT_NO_SCHED();            // 退出临界区
         return;
    }
    OS_RdyListRemove(OSTCBCurPtr);               // 从任务就绪表中删除当前任务
    OS_CRITICAL_EXIT_NO_SCHED();                 // 退出临界区
    OSSched();                                   // 执行任务调度
   *p_err = OS_ERR_NONE;
}

3.OSTimeDlyHMSM()函数
OSTimeDlyHMSM()函数的源代码位于os_time.c文件,198行 - 323行

#if OS_CFG_TIME_DLY_HMSM_EN > 0u                       // 允许该函数
void  OSTimeDlyHMSM (CPU_INT16U  hours,
                     CPU_INT16U  minutes,
                     CPU_INT16U  seconds,
                     CPU_INT32U  milli,
                     OS_OPT      opt,
                     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();                                    // 宏定义,声明变量cpu_sr,用来临时存储CPU状态寄存器的值

#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) {        // 不允许在ISR中调用该函数
       *p_err = OS_ERR_TIME_DLY_ISR;
        return;
    }
#endif

    if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) {  // 当调度器锁定的时候不允许延时
       *p_err = OS_ERR_SCHED_LOCKED;
        return;
    }

    opt_time = opt & OS_OPT_TIME_MASK;                 // 这里检索的仅仅是时间
    switch (opt_time) {
        case OS_OPT_TIME_DLY:
        case OS_OPT_TIME_TIMEOUT:
        case OS_OPT_TIME_PERIODIC:
             if (milli == (CPU_INT32U)0u) {            // 确保时间不为0
                 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                           // 允许参数检测
    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) {           // 毫秒(milli)不允许超过999
            *p_err = OS_ERR_TIME_INVALID_MILLISECONDS;
             return;
         }
         if (seconds > (CPU_INT16U)59u) {            // 秒(seconds)不允许超过59
            *p_err = OS_ERR_TIME_INVALID_SECONDS;
             return;
         }
         if (minutes > (CPU_INT16U)59u) {            // 分钟(minutes)不允许超过59
            *p_err = OS_ERR_TIME_INVALID_MINUTES;
             return;
         }
         if (hours   > (CPU_INT16U)99u) {            // 小时(hours)不允许超过99
            *p_err = OS_ERR_TIME_INVALID_HOURS;
             return;
         }
    } else {                                         // 不严格的参数检测
         if (minutes > (CPU_INT16U)9999u) {          // 分钟(minutes)不允许超过9999
            *p_err = OS_ERR_TIME_INVALID_MINUTES;
             return;
         }
         if (hours   > (CPU_INT16U)999u) {           // 小时(hours)不允许超过999
            *p_err = OS_ERR_TIME_INVALID_HOURS;
             return;
         }
    }
#endif

    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);               // 从任务就绪表中删除该任务
        OS_CRITICAL_EXIT_NO_SCHED();                 // 退出临界区
        OSSched();                                   // 执行任务调度
       *p_err = OS_ERR_NONE;
    } else {
       *p_err = OS_ERR_TIME_ZERO_DLY;
    }
}
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值