ucos 软定时器

一、定时器的建立:

        定时器是在我们的应用程序中建立的,

OS_TMR  *OSTmrCreate (INT32U           dly,

                      INT32U           period,

                      INT8U           opt,

                      OS_TMR_CALLBACK  callback,

                      void            *callback_arg,

                      INT8U           *pname,

                      INT8U           *perr)

想使用定时器那些函数要在os_cfg.h中定义OS_TMR_EN

返回值是os_tmr结构体(定义在ucos_ii.h中)。

typedef  struct  os_tmr {

INT8U            OSTmrType;                      

OS_TMR_CALLBACK  OSTmrCallback;                  

void            *OSTmrCallbackArg;               

void            *OSTmrNext;                     

    void           *OSTmrPrev;

INT32U           OSTmrMatch;                OSTmrTime == OSTmrMatch定时器到时间了。  

INT32U           OSTmrDly;                       

INT32U           OSTmrPeriod;                    

#if OS_TMR_CFG_NAME_EN > 0u

INT8U           *OSTmrName;                     

#endif

INT8U            OSTmrOpt;                      

INT8U            OSTmrState;                                                                                                              

} OS_TMR;

OSTmrType类型定义在ucos_ii.h中:OS_TMR_TYPE

OS_ARG_CHK_EN要在os_cfg.h中定义一下,来确定要不要一些功能。

OS_TMR_CFG_NAME_EN要你自己在os_cfg.h中定义,来控制要不要用OSTmrName

OSTmrStateucos_ii.h中有以下几种类型:

       OS_TMR_STATE_UNUSED  不存在这个定时器                                    

       OS_TMR_STATE_RUNNING 这个定时器正在运行 

          OS_TMR_STATE_COMPLETED这个定时器已经跑完了                                 

       OS_TMR_STATE_STOPPED  这个定时器停止了  

参数:

1、  Dly           定时时间,如果是这个定时器只用一次,那么就用这个,如果定时器要反复用那么它是第一次时用,以后用period

2、  Period      定时器从复用时会用到这个作定时时间。

3、  Opt          这里有两种选项,告诉我们是只用一次还是反复使用。只用一次OS_TMR_OPT_ONE_SHOT,反复使用OS_TMR_OPT_PERIODIC。这些定义在ucos_ii.h中。

定时器选项有五种

#define  OS_TMR_OPT_NONE                   0u   没有选择

#define  OS_TMR_OPT_ONE_SHOT               1u   定时器不会自动重复使用

#define  OS_TMR_OPT_PERIODIC                  2u   定时器会自动重装

#define  OS_TMR_OPT_CALLBACK                 3u   OSTmrStop()中使用,调用回调函数,但不带参数

#define  OS_TMR_OPT_CALLBACK_ARG           4u    也是OSTmrStop()中使用,调用回调函数,但有参数。

4、  Callback   指向回调函数的指针,这个函数这样声明,void mycallback(OS_TMR *ptmr,  void p_arg );

5、  Callback_arg     参数给callback的。

6、  Pname     定时器的名字

7、  Perr     错误指针*         OS_ERR_NONE                          没有错误

                               OS_ERR_TMR_INVALID_DLY                无效的定时时间

                               OS_ERR_TMR_INVALID_PERIOD             无效的周期

                          OS_ERR_TMR_INVALID_OPT                                 无效的选项

                               OS_ERR_TMR_ISR                        在中断中调用

                              OS_ERR_TMR_NON_AVAIL                 空的定时器用光了,这个和task一样意思。

用到的函数OSTmr_Alloc()得到一个定时器结构体。

 

二、OSTmrStart

会调用OSTmr_Link,OSTmr_Link代码如下

#if OS_TMR_EN > 0u
static  void  OSTmr_Link (OS_TMR  *ptmr,
                          INT8U    type)
{
    OS_TMR       *ptmr1;
    OS_TMR_WHEEL *pspoke;
    INT16U        spoke;


    ptmr->OSTmrState = OS_TMR_STATE_RUNNING;
    if (type == OS_TMR_LINK_PERIODIC) {                            /* Determine when timer will expire                */
        ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
    } else {
        if (ptmr->OSTmrDly == 0u) {
            ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
        } else {
            ptmr->OSTmrMatch = ptmr->OSTmrDly    + OSTmrTime;
        }
    }
    spoke  = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE);
    pspoke = &OSTmrWheelTbl[spoke];

    if (pspoke->OSTmrFirst == (OS_TMR *)0) {                       /* Link into timer wheel                           */
        pspoke->OSTmrFirst   = ptmr;
        ptmr->OSTmrNext      = (OS_TMR *)0;
        pspoke->OSTmrEntries = 1u;
    } else {
        ptmr1                = pspoke->OSTmrFirst;                 /* Point to first timer in the spoke               */
        pspoke->OSTmrFirst   = ptmr;
        ptmr->OSTmrNext      = (void *)ptmr1;
        ptmr1->OSTmrPrev     = (void *)ptmr;
        pspoke->OSTmrEntries++;
    }
    ptmr->OSTmrPrev = (void *)0;                                   /* Timer always inserted as first node in list     */
}
#endif

 

三、OSTmr_Task()

用于在定时器到时间后,执行定时器创建时候的回调函数,代码如下:

static  void  OSTmr_Task (void *p_arg)
{
    INT8U            err;
    OS_TMR          *ptmr;
    OS_TMR          *ptmr_next;
    OS_TMR_CALLBACK  pfnct;
    OS_TMR_WHEEL    *pspoke;
    INT16U           spoke;


    p_arg = p_arg;                                               /* Prevent compiler warning for not using 'p_arg'    */
    for (;;) {
        OSSemPend(OSTmrSemSignal, 0u, &err);                     /* Wait for signal indicating time to update timers  */
        OSSchedLock();
        OSTmrTime++;                                             /* Increment the current time                        */
        spoke  = (INT16U)(OSTmrTime % OS_TMR_CFG_WHEEL_SIZE);    /* Position on current timer wheel entry             */
        pspoke = &OSTmrWheelTbl[spoke];
        ptmr   = pspoke->OSTmrFirst;
        while (ptmr != (OS_TMR *)0) {
            ptmr_next = (OS_TMR *)ptmr->OSTmrNext;               /* Point to next timer to update because current ... */
                                                                 /* ... timer could get unlinked from the wheel.      */
            if (OSTmrTime == ptmr->OSTmrMatch) {                 /* Process each timer that expires                   */
                OSTmr_Unlink(ptmr);                              /* Remove from current wheel spoke                   */
                if (ptmr->OSTmrOpt == OS_TMR_OPT_PERIODIC) {
                    OSTmr_Link(ptmr, OS_TMR_LINK_PERIODIC);      /* Recalculate new position of timer in wheel        */
                } else {
                    ptmr->OSTmrState = OS_TMR_STATE_COMPLETED;   /* Indicate that the timer has completed             */
                }
                pfnct = ptmr->OSTmrCallback;                     /* Execute callback function if available            */
                if (pfnct != (OS_TMR_CALLBACK)0) {
                    (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg);
                }
            }
            ptmr = ptmr_next;
        }
        OSSchedUnlock();
    }
}
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值