liteos 中timer 的创建和运行

liteos中的timer相关的API主要有创建一个定时任务,刚创建时这个定时任务并没有启动,需要丢用另一个API LOS_SwtmrStart来启动这个timer。具体举例如下:
UINT32 Example_swTimer(VOID)
{
    UINT16 id1;
    UINT16 id2;// timer id
    UINT32 uwRet = LOS_OK;
#创建一个定时任务,这个定时任务的运行周期是1000,回调函数是Timer1_Callback, 
    uwRet = LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1);

    if (LOS_OK != uwRet)
    {
        dprintf("create Timer1 failed\n");
    }
    else
    {
        dprintf("create Timer1 success\n");
    }
#根据LOS_SwtmrCreate 返回的id1 来启动这个timer
    uwRet = LOS_SwtmrStart(id1);
    if (LOS_OK != uwRet)
    {
        dprintf("start Timer1 failed\n");
    }
    else
    {
        dprintf("start Timer1 sucess\n");
    }
#延迟200
    (VOID)LOS_TaskDelay(200);
#停止这个timer
    uwRet = LOS_SwtmrStop(id1);
    if (LOS_OK != uwRet)
    {
        dprintf("stop Timer1 failed\n");
    }
    else
    {
        dprintf("stop Timer1 sucess\n");
    }

    return LOS_OK;
}
下来我们先看看创建定时任务的函数LOS_SwtmrCreate
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 uwInterval, UINT8 ucMode, SWTMR_PROC_FUNC pfnHandler, UINT16 *pusSwTmrID, UINT32 uwArg
                    )
{
    SWTMR_CTRL_S  *pstSwtmr;
    UINTPTR  uvIntSave;

      uvIntSave = LOS_IntLock();
    if (NULL == m_pstSwtmrFreeList)
    {
        LOS_IntRestore(uvIntSave);
        return LOS_ERRNO_SWTMR_MAXSIZE;
    }
#可以看到所有timer的都是添加到m_pstSwtmrFreeList这个列表中,这个列表是在osSwTmrInit中通过LOS_MemAlloc来申请
#空间并赋初值,剩下主要就是给pstSwtmr赋初值
    pstSwtmr = m_pstSwtmrFreeList;
    m_pstSwtmrFreeList = pstSwtmr->pstNext;
    LOS_IntRestore(uvIntSave);
    pstSwtmr->pfnHandler    = pfnHandler;
    pstSwtmr->ucMode        = ucMode;
    pstSwtmr->uwInterval    = uwInterval;
    pstSwtmr->pstNext       = (SWTMR_CTRL_S *)NULL;
    pstSwtmr->uwCount       = 0;
    pstSwtmr->uwArg         = uwArg;
    pstSwtmr->ucState       = OS_SWTMR_STATUS_CREATED;
    *pusSwTmrID = pstSwtmr->usTimerID;

    return LOS_OK;
}
到这里周期性任务就创建好了,可以知道所有的周期性任务都是添加到m_pstSwtmrFreeList这个全局的list中。
创建完周期性任务后,就可以通过LOS_SwtmrStart 来开始运行这个timer
LITE_OS_SEC_TEXT VOID osSwTmrStart(SWTMR_CTRL_S *pstSwtmr)
{
    SWTMR_CTRL_S *pstPrev = (SWTMR_CTRL_S *)NULL;
    SWTMR_CTRL_S *pstCur = (SWTMR_CTRL_S *)NULL;

    pstSwtmr->uwCount = pstSwtmr->uwInterval;


    pstCur = m_pstSwtmrSortList;
#根据到期时间将周期性任务插入到另外一个全局性列表中m_pstSwtmrSortList
#从这里可以知道这个链表中的周期性任务都是按照到期时间严格排序
    while (pstCur != NULL)
    {
        if (pstCur->uwCount > pstSwtmr->uwCount)
        {
            break;
        }

        pstSwtmr->uwCount -= pstCur->uwCount;
        pstPrev = pstCur;
        pstCur = pstCur->pstNext;
    }
#设置这个周期性任务的状态为运行
    pstSwtmr->ucState = OS_SWTMR_STATUS_TICKING;

    return;,这是一个
}
那具体是谁来调用m_pstSwtmrSortList中的周期性任务呢?
最后是在osSwtmrScan来调用的,而osSwtmrScan是由osTickHandler。这个是时间戳的中断函数,我们重点看看osSwtmrScan
LITE_OS_SEC_TEXT UINT32 osSwtmrScan(VOID)
{
    if (m_pstSwtmrSortList != NULL)
    {
#到期时间自检,为零后,标志对应的周期事件到期,调用osSwTmrTimeoutHandle来执行回调函数
        if (--(m_pstSwtmrSortList->uwCount) == 0)
        {
            osSwTmrTimeoutHandle();
        }
    }
    return LOS_OK;
看看osSwTmrTimeoutHandle的实现
LITE_OS_SEC_TEXT static VOID osSwTmrTimeoutHandle(VOID)
{
    SWTMR_CTRL_S *pstSwtmr = m_pstSwtmrSortList;
    SWTMR_HANDLER_ITEM_S stSwtmrHandler;

    while (pstSwtmr != NULL && pstSwtmr->uwCount == 0)
    {
        m_pstSwtmrSortList = pstSwtmr->pstNext;
#得到本次到期的周期事件的回调函数和参数
        stSwtmrHandler.pfnHandler = pstSwtmr->pfnHandler;
        stSwtmrHandler.uwArg = pstSwtmr->uwArg;
#开始执行本次到期事件的回调函数,这里将到期事件转成一个task,放到queue中运行
        (VOID)LOS_QueueWriteCopy(m_uwSwTmrHandlerQueue, &stSwtmrHandler, sizeof(SWTMR_HANDLER_ITEM_S), LOS_NO_WAIT);
#根据这个周期时间是period还是onshot 来处理
        if (pstSwtmr->ucMode == LOS_SWTMR_MODE_ONCE)
        {
            osSwtmrDelete(pstSwtmr);
            if (pstSwtmr->usTimerID < OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)
                pstSwtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT;
            else
                pstSwtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT;
        }
        else if ( pstSwtmr->ucMode == LOS_SWTMR_MODE_PERIOD)
        {
            osSwTmrStart(pstSwtmr);
        }
        else if (pstSwtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE)
        {
            pstSwtmr->ucState = OS_SWTMR_STATUS_CREATED;
        }

        pstSwtmr = m_pstSwtmrSortList;
    }
}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值