加入收藏 在线留言 联系我们
关注微信
手机扫一扫 立刻联系商家
全国服务热线15915421161

SIEMENS山东省济宁市 西门子代理商——西门子华北一级总代理

更新时间
2024-07-04 07:00:00
价格
请来电询价
西门子总代理
PLC
西门子一级代
驱动
西门子代理商
伺服电机
联系电话
15903418770
联系手机
15915421161
联系人
张经理
立即询价

详细介绍
3.2.1 获取当前时间并决定是否切换列表

























  • static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ){    TickType_t xTimeNow;    /*静态变量 记录上一次调用时系统节拍值*/    PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U;    /*获取本次调用节拍结束器值*/    xTimeNow = xTaskGetTickCount();
       /*判断节拍计数器是否溢出过*/    if( xTimeNow < xLastTime )    {        /*发生溢出,处理当前链表上所有定时器并切换管理链表*/        prvSwitchTimerLists();        *pxTimerListsWereSwitched = pdTRUE;    }    else    {        *pxTimerListsWereSwitched = pdFALSE;    }    /*更新时间记录*/    xLastTime = xTimeNow;
       return xTimeNow;}

    可以看到, 该函数每次调用都会记录当前系统节拍时间(TickCount), 下一次调用,通过比较相邻两次调用的值判断节拍计数器是否溢出。当系统节拍计数器溢出, 必须切换计时器列表。如果当前计时器列表中仍然引用任何计时器,那么它们一定已经过期,应该在切换列表之前进行处理。

    切换列表的具体内容如下:


















































  • static void prvSwitchTimerLists( void ){    TickType_t xNextExpireTime, xReloadTime;    List_t *pxTemp;    Timer_t *pxTimer;    BaseType_t xResult;
       /* 列表非空,循环处理,直至将该列表处理完 */    while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )    {        xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
           /* 从列表中移除软件定时器 */        pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );        ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );        traceTIMER_EXPIRED( pxTimer );
           /*执行回调函数*/        pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
           /*对于周期定时器*/        if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )        {            /*计算重新加载值:下个溢出时间 + 定时周期*/            xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );            /*如果重新加载值>下个溢出时间,应该将计时器重新插入当前列表,以便在此循环中再次处理它*/            if( xReloadTime > xNextExpireTime )            {                listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );                listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );                vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );            }            else/*否则,应该发送一个命令来重新启动计时器,以确保它只插入到列表之后列表已被交换*/            {                xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );                configASSERT( xResult );                ( void ) xResult;            }        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }
       pxTemp = pxCurrentTimerList;    pxCurrentTimerList = pxOverflowTimerList;    pxOverflowTimerList = pxTemp;}

    (切换列表这里还没完全弄明白)

    下面来看一下如何处理到时(或超时)的定时器:

    3.2.2 处理超时的定时器




































  • /* 处理超时的定时器 */static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ){    BaseType_t xResult;    /* 获取Zui近的超时定时器 */    Timer_t *const pxTimer = ( Timer_t * )listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );     /* 将Zui近的超时定时器从活跃列表中移除 */    (void)uxListRemove( &( pxTimer->xTimerListItem ) );    traceTIMER_EXPIRED(pxTimer);     /* 周期定时 */    if( pxTimer->uxAutoReload == ( UBaseType_t )pdTRUE )    {        /* 重新计算超时时间并加入活跃列表,如果下一次超时时间都已经过了 */        if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE )        {            /* 通知守护任务来处理(将定时器插入活跃列表) */            xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );            configASSERT( xResult );            ( void )xResult;        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        mtCOVERAGE_TEST_MARKER();    }     /* 调用回调函数 */    pxTimer->pxCallbackFunction( ( TimerHandle_t )pxTimer );}



    相关产品

    联系方式

    • 电  话:15903418770
    • 联系人:张经理
    • 手  机:15915421161
    • 微  信:15915421161