uCOS-III笔记之定时器

uCOS-III笔记之定时器

说到定时器,就先来说说它有什么用,定时器和时间是不一样的也就是timer和time,我们是为了等一段时间后去完成某一个操作。

一、初始化

要用定时器首先要做的就是初始化定时器,ucos中初始化定时器使用的函数是 void  OS_TmrInit (OS_ERR  *p_err),初始化中主要做了什么呢。

1、初始化一个全局的一个定时器的存放处也就是这个TmrWheel,下面我就来看一下这个定时器的轮盘。可以看到这就是一个OS_TMR的一个指针。(另外还初始化了其他的一些计数器)

   
typedef  struct  os_tmr_spoke        OS_TMR_SPOKE;

struct  os_tmr_spoke {

    OS_TMR              *FirstPtr;                          
    /* Pointer to first timer in linked list                  */

    OS_OBJ_QTY           NbrEntries;

    OS_OBJ_QTY           NbrEntriesMax;

};

OS_TMR_SPOKE   OSCfg_TmrWheel      [OS_CFG_TMR_WHEEL_SIZE];

       2、创建一个定时器任务:OS_TmrTask,也就是这个任务管理着我们所有的定时器有序的运行完成我们的预期目标。

             注意<这个任务其实优先级很低通过源码可以看到 :#define  OS_CFG_TMR_TASK_PRIO      (OS_CFG_PRIO_MAX - 2u),如果要求高优先级高实时的的事件还是要考虑好再使用>。

     让我们看一下这个任务到底做了什么,从代码中可以看到这个任务就是在轮询上面提到的定时器管理的轮子,判断match是否到达,然后对到达的定时器做了相关的操作,然后运行我们的回到函数CallbackPtr程序。

... 
while (DEF_ON) {
    (void)OSTaskSemPend((OS_TICK )0,                         /* Wait for signal indicating     time to update tmrs    */
        (OS_OPT  )OS_OPT_PEND_BLOCKING,
        (CPU_TS *)&ts,
        (OS_ERR *)&err);
    OSSchedLock(&err);
    ts_start = OS_TS_GET();
    OSTmrTickCtr++;                                          
    /* Increment the current time                        */
    spoke    = (OS_TMR_SPOKE_IX)(OSTmrTickCtr % OSCfg_TmrWheelSize);
    p_spoke  = &OSCfg_TmrWheel[spoke];
    p_tmr    = p_spoke->FirstPtr;
    done     = DEF_FALSE;   
    while (done == DEF_FALSE) {
    if (p_tmr != (OS_TMR *)0) {
        p_tmr_next = (OS_TMR *)p_tmr->NextPtr;           
        /* Point to next tmr to update because current ...   */
                                                                 
        /* ... timer could get unlinked from the wheel.      */
        if (OSTmrTickCtr == p_tmr->Match) {              
            /* Process each timer that expires                   */
            OS_TmrUnlink(p_tmr);                         
            /* Remove from current wheel spoke                   */
            if (p_tmr->Opt == OS_OPT_TMR_PERIODIC) {
                OS_TmrLink(p_tmr,
                            OS_OPT_LINK_PERIODIC);       
                 /* Recalculate new position of timer in wheel        */
                } else {
                    p_tmr->State = OS_TMR_STATE_COMPLETED;   
                    /* Indicate that the timer has completed             */
                }
                p_fnct = p_tmr->CallbackPtr;                 
                /* Execute callback function if available            */
                if (p_fnct != (OS_TMR_CALLBACK_PTR)0) {
                    (*p_fnct)((void *)p_tmr,
                    p_tmr->CallbackPtrArg);
                }
                p_tmr = p_tmr_next;                          
                /* See if next timer matches                         */
                } else {
                    done  = DEF_TRUE;
                }
            } else {
                done = DEF_TRUE;
            }
        }
}
...

二、使用定时器

定时器已经完成了初始化,也已经把定时器管理的大轮子转起来了,接下来就是我们如何把我们的定时器事件插到这个飞速旋转的轮子上。

1、创建定时器

使用OSTmrCreate,创建定时器指针,然后初始化这个定时器:名称,时间,回调函数。

函数里面有一个‘’OSTmrQty++‘’用来记录定时器个数正好与OSTmrDel函数内的“OSTmrQty--”相互对应。

void  OSTmrCreate (OS_TMR               *p_tmr,
                   CPU_CHAR             *p_name,
                   OS_TICK               dly,
                   OS_TICK               period,
                   OS_OPT                opt,
                   OS_TMR_CALLBACK_PTR   p_callback,
                   void                 *p_callback_arg,
                   OS_ERR               *p_err)

2、启动定时器

启动定时器,其实就是将定时器指针放入到我们的定时管理的轮子上。

CPU_BOOLEAN  OSTmrStart (OS_TMR  *p_tmr,
                         OS_ERR  *p_err)

这start这个函数里用到了几个重要的函数,一个是link将定时器加入链表中,一个是unlink将定时器从链表中删除。这样我们的定时器就可以进入任务调度的大军中了。

void  OS_TmrLink (OS_TMR  *p_tmr,
                  OS_OPT   opt)

void  OS_TmrUnlink (OS_TMR  *p_tmr)

三、定时器的停止删除

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值