UCOSII系统时间管理[通俗易懂]

UCOSII系统时间管理[通俗易懂]一,UCOSII的定时中断绝大多数的内核要求提供定时中断,以实现延时与超时控制等功能。这个定时中断叫做时钟节拍。时钟的中断子程序ISR和时钟节拍函数OSTimeTick()该函数通知UCOSII,发生了时钟节拍中断。二,UCOSII系统时钟函数1,任务延时函数,OSTimeDly(INT16Uticks)实现申请该服务的任务可以延时一段时间这个系统服务的函数叫做OSTimeDly(),这段时间的长短是用时钟节拍的数目来确定的。调用该函数会使µC/OS-Ⅱ进行一次任务调度,并且执行下一个优

大家好,又见面了,我是你们的朋友全栈君。

一,UCOSII的定时中断

绝大多数的内核要求提供定时中断,以实现延时与超时控制等功能。这个定时中断叫做时钟节拍。时钟的中断子程序ISR和时钟节拍函数OSTimeTick()该函数通知UCOSII,发生了时钟节拍中断。

二,UCOSII系统时钟函数

1,任务延时函数, OSTimeDly(INT16U ticks)
实现申请该服务的任务可以延时一段时间这个系统服务的函数叫做 OSTimeDly(),这段时间的长短是用时钟节拍的数目来确定的。调用该函数会使µC/OS-Ⅱ进行一次任务调度,并且执行下一个优先级最高的就绪态任务。

void  OSTimeDly (INT32U ticks)
{
    INT8U      y;
#if OS_CRITICAL_METHOD == 3u  /* Allocate storage for CPU status register  */
    OS_CPU_SR  cpu_sr = 0u;
#endif
 
    if (OSIntNesting > 0u) 
    {                     /* See if trying to call from an ISR */
        return;
    }
    if (OSLockNesting > 0u) 
    {                    /* See if called with scheduler locked*/
        return;
    }
    if (ticks > 0u) 
    {              /* 0 means no delay!  */
        OS_ENTER_CRITICAL();
        y  =  OSTCBCur->OSTCBY; /* Delay current task  */
        OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0u) 
        {
            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
        }
        OSTCBCur->OSTCBDly = ticks;  /* Load ticks in TCB */
        OS_EXIT_CRITICAL();
        OS_Sched();    /* Find next task to run! */
    }
}

(1)任务调用 OSTimeDly()后,一旦规定的时间期满或者有其它的任务通过调用 OSTimeDlyResume()取消了延时,它就会马上进入就绪状态。

(2)参数分析:ticks:代表的是多少个时钟周期节拍

(3)实现过程:
把相应任务的就绪表中的位图的位置清零。把需要执行的等待节拍进行处理。
最后进行任务调度,寻找下一个这个时刻最高优先级的任务。

(4)在OS_TCB的结构体当中的Ticks填写相应的数字的时候通过OSTimeTick()函数可以把任务从就绪态变为等待的状态

void  OSTimeTick (void)
{
    OS_TCB    *ptcb;
 
    if (OSRunning == OS_TRUE) {
#if OS_TICK_STEP_EN > 0u
        switch (OSTickStepState) {                         /* Determine whether we need to process a tick  */
            case OS_TICK_STEP_DIS:                         /* Yes, stepping is disabled                    */
                 step = OS_TRUE;
                 break;
 
            case OS_TICK_STEP_WAIT:                        /* No,  waiting for uC/OS-View to set ...       */
                 step = OS_FALSE;                          /*      .. OSTickStepState to OS_TICK_STEP_ONCE */
                 break;
 
            case OS_TICK_STEP_ONCE:                        /* Yes, process tick once and wait for next ... */
                 step            = OS_TRUE;                /*      ... step command from uC/OS-View        */
                 OSTickStepState = OS_TICK_STEP_WAIT;
                 break;
 
            default:                                       /* Invalid case, correct situation              */
                 step            = OS_TRUE;
                 OSTickStepState = OS_TICK_STEP_DIS;
                 break;
        }
        if (step == OS_FALSE) {                            /* Return if waiting for step command           */
            return;
        }
#endif
 
//此处为此任务运行的核心的代码:
 
        ptcb = OSTCBList;                                  /* Point at first TCB in TCB list               */
        while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) {     /* Go through all TCBs in TCB list              */
            OS_ENTER_CRITICAL();
            if (ptcb->OSTCBDly != 0u) {                    /* No, Delayed or waiting for event with TO     */
                ptcb->OSTCBDly--;                          /* Decrement nbr of ticks to end of delay       */
                if (ptcb->OSTCBDly == 0u) {                /* Check for timeout                            */
 
                    if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
                        ptcb->OSTCBStat  &= (INT8U)~(INT8U)OS_STAT_PEND_ANY;          /* Yes, Clear status flag   */
                        ptcb->OSTCBStatPend = OS_STAT_PEND_TO;                 /* Indicate PEND timeout    */
                    } else {
                        ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
                    }
 
                    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?       */
                        OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready          */
                        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
                    }
                }
            }
            ptcb = ptcb->OSTCBNext;                        /* Point at next TCB in TCB list                */
            OS_EXIT_CRITICAL();
        }
    }
}

2,按时分秒延时函数 OSTimeDlyHMSM( INT8U hours, INT8U minutes, INT8U seconds, INT16U milli):

调用 OSTimeDlyHMSM()函数也会使µC/OS-Ⅱ进行一次任务调度,并且执行下一个优先级最高的就绪态任务。任务调用 OSTimeDlyHMSM()后,一旦规定的时间期满或者有其它的任务通过调用 OSTimeDlyResume()取消了延时,它就会马上处于就绪态。只有当该任务在所有就绪态任务中具有最高的优先级时,它才会立即运行。若将时钟频率(OS_TICKS_PER_SEC)设置成 100Hz(10ms),4ms 的延时不会产生任何延时!而 5ms 的延时就等于延时 10ms。µC/OS-Ⅱ支持的延时最长为 65,535 个节拍。要想支持更长时间的延时,OSTimeDlyHMSM()确定了用户想延时多少次超过 65,535 个节拍的数目和剩下的节拍数,超过的节拍数会被分为几次去延时。由于OSTimeDlyHMSM()的具体实现方法,用户不能结束延时调用 OSTimeDlyHMSM()要求延时超过 65535 个节拍的任务。

3,恢复延时的任务:OSTimeDlyResume():把那个全局的时间计数器变量设置为0

INT8U  OSTimeDlyResume (INT8U prio)
{
    OS_TCB    *ptcb;
 
    if (prio >= OS_LOWEST_PRIO) {
        return (OS_ERR_PRIO_INVALID);
    }
    OS_ENTER_CRITICAL();
    ptcb = OSTCBPrioTbl[prio];                                 /* Make sure that task exist            */
    if (ptcb == (OS_TCB *)0) {
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_NOT_EXIST);                        /* The task does not exist              */
    }
    if (ptcb == OS_TCB_RESERVED) {
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_NOT_EXIST);                        /* The task does not exist              */
    }
    if (ptcb->OSTCBDly == 0u) {                                /* See if task is delayed               */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TIME_NOT_DLY);                          /* Indicate that task was not delayed   */
    }
 
    ptcb->OSTCBDly = 0u;                                       /* 清除任务计数器       */
    if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
        ptcb->OSTCBStat     &= ~OS_STAT_PEND_ANY;              /* Yes, Clear status flag               */
        ptcb->OSTCBStatPend  =  OS_STAT_PEND_TO;               /* Indicate PEND timeout                */
    } else {
        ptcb->OSTCBStatPend  =  OS_STAT_PEND_OK;
    }
    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?                   */
        OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready                      */
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OS_EXIT_CRITICAL();
        OS_Sched();                                            /* See if this is new highest priority  */
    } else {
        OS_EXIT_CRITICAL();                                    /* Task may be suspended                */
    }
    return (OS_ERR_NONE);
}

4,让处在延时期的任务结束延时:OSTimeDlyResume( INT8U prio)
  延时的任务可以不等待延时期满,而是通过其它任务取消延时来使自己处于就绪态。实际上,OSTimeDlyResume()也可以唤醒正在等待事件。

5,系统时间, OSTimeGet()函数和 OSTimeSet()函数:在访问 OSTime 的时候中断是关掉的。这是因为在大多数 8 位处理器上增加和拷贝一个 32位的数都需要数条指令,这些指令一般都需要一次执行完毕,而不能被中断等因素打断。
无论时钟节拍何时发生, µCOSⅡ会将一个 32 位的计数器加 1。这个计数器在用户调用 OSStart()初始化多任务和 4,294,967,295 个节拍执行完一遍的时候从 0 开始计数。在时钟节拍的频率等于 100Hz 的时候,这个 32 位的计数器每隔 497 天就重新开始计数。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/136895.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Python实现排列组合算法

    Python实现排列组合算法实现组合算法C(n,k),可以用递归实现:importcopy#实现list的深复制defcombine(lst,l):result=[]tmp=[0]*llength=len(lst)defnext_num(li=0,ni=0):ifni==l:result.append…

    2022年10月20日
  • windows ftp 被动模式_通常ftp用主动还是被动模式

    windows ftp 被动模式_通常ftp用主动还是被动模式环境:windowsserver2012R2FTPclientFileZilla3.7.3windowsserver2012服务器搭建完毕后默认为主动式(测试发现windows10搭建完毕默认为被动式)由于开发人员所做视频推流不支持主动式故需要更改为被动式主动式:有客户端N端口发起连接到服务器端21端口传输数据时由服务器端20端…

  • 一文教你检测MOS管好坏的五大诀窍「建议收藏」

    MOS管是金属—氧化物-半导体场效应晶体管,或者称是金属—绝缘体—半导体。MOS管因导通压降下,导通电阻小,栅极驱动不需要电流,损耗小,价格便宜等优点在电子行业深受人们的喜爱与追捧,随着电子行业飞跃式的发展,MOS管的需求量也越来越大,就在此时一批批MOS管生产厂家如雨后春笋般涌现到我们的眼前,他们的出现瞬间使得MOS管的质量的急速下滑,由于这些厂家的技术不成熟,而且当中也掺杂了许多山寨的MOS管…

  • c语言getchar()的用法_c=getchar()

    c语言getchar()的用法_c=getchar()文章目录getchar()函数定义函数返回值注意区分getchar和scanfgetchar的使用实例getchar()函数定义getchar()-字符输入函数,没有参数,从输入缓冲区里面读取一个字符-「一次只能读取一个字符」EOF(-1)-endoffile文件结束标志-键盘上用ctrl+z实现先查一下文档函数返回值该函数以无符号char强制转换为int的形式返回读取的字符,如果到达文件末尾或发生读取错误,则返回EOF(-1

    2022年10月18日
  • 教你读懂蛋白质数据库文件(PDB文件)

    教你读懂蛋白质数据库文件(PDB文件)回答网友提问:什么是HETATM?  并教你读懂蛋白质的PDB文件  作者:小米HETATM非标准基团原子坐标,这个是PDB数据库原子坐标的一种记录格式。如HETATM460PPO4100-2.5027.5874.2251.0024.59PHETATM461O1PO4100-3.3206.5325.0031.00

  • Redis和Memcached的区别

    Redis和Memcached的区别

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号