uc/os:时间管理

uc/os与时间管理有关的函数在os_time.c这个文件里面,包含操作系统时间的设置及获取,对任务的延时,任务按时分秒毫秒延时,取消任务的延时共5个系统调用,其中对任务的延时是uC/OS时间管理最主要的功能,如下图:

 

 

uc/os中的延时不同于单片机不带系统时的延时函数,单片机延时函数大多情况下CPU是在执行无意义的指令,降低了CPU的效率,而在uc/os中是在调用系统延时的任务的任务控制块中写入一个延时数ticks,然后将该任务挂起进行任务调度,释放cpu控制权交给其他任务,这提高了cpu的使用效率。当系统时钟中断来临时,系统会将所有任务的任务控制块的ticks数减1然后检查ticks是否为0,如果ticks大于0该任务就继续被挂起等待,如果等于0就将其加入就续表中。下面贴出使用最多的OSTimeDly()源码及注释。

 

void  OSTimeDly (OS_TICK   dly,
                 OS_OPT    opt,
                 OS_ERR   *p_err)
{
    CPU_SR_ALLOC();//为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//检查是否允许在ISR中调用系统函数(除了POST)
    if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { // OSIntNestingCtr是中断嵌套数           /* 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;
    }

    switch (opt) {
        case OS_OPT_TIME_DLY:
        case OS_OPT_TIME_TIMEOUT:
        case OS_OPT_TIME_PERIODIC:
             if (dly == (OS_TICK)0u) {                      /* 0 means no delay!                                      */
                *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);                          /* Remove current task from ready list                    */
    OS_CRITICAL_EXIT_NO_SCHED();
    OSSched();                                              /* Find next task to run!                                 */
   *p_err = OS_ERR_NONE;
}

 

posted on 2018-12-20 11:14  heartflying  阅读(524)  评论(0编辑  收藏  举报

导航