FreeRTOS 软件定时器

一.简介

         相等于闹钟功能。

        其由vTaskStartScheduler()函数开启任务调度的时候,同时创建一个用于管理软件定时器的任务,叫做软件定时器服务任务。

        软件定时器与硬件定时器对比:

        硬件定时器在裸机项目中是由外设提供的功能。

        优点:

                数量不限,可以创建多个。硬件定时器数量有限

                使用简单,成本低

        缺点:

                精度不够硬件定时器高。(软件定时器以系统时钟为基准,系统时钟中断优先级较低,容易被打断)

                在软件定时器的回调中不可以使用会导致阻塞的api,因为软件定时器回调函数本身不是任务

                

二.软件定时器的命令队列

        FreeRTOS 提供了许多软件定时器相关的API函数,这些API函数大多都是往定时器的队列中写入消息(发送命令),这个队列叫做软件定时器命令队列,是提供给FreeRTOS中的软件定时器使用的,用户是不能直接访问的。

        

三.api
//创建
TimerHandle_t xTimerCreate(	    const char * const pcTimerName,		
								const TickType_t xTimerPeriodInTicks,
								const UBaseType_t uxAutoReload,
								void * const pvTimerID,
								TimerCallbackFunction_t pxCallbackFunction )


TimerHandle_t xTimerCreateStatic(	    const char * const pcTimerName,
										const TickType_t xTimerPeriodInTicks,
										const UBaseType_t uxAutoReload,
										void * const pvTimerID,
										TimerCallbackFunction_t pxCallbackFunction,
										StaticTimer_t *pxTimerBuffer )

//开启
xTimerStart( xTimer, xTicksToWait )
xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken )

//停止
xTimerStop( xTimer, xTicksToWait )
xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken )

//重置
xTimerReset( xTimer, xTicksToWait )
xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken )

//更改周期时间
xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait )
xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken )

四.软件定时器服务任务

  

       //任务开启流程

vTaskStartScheduler()----->
    xTimerCreateTimerTask()----->
        prvCheckForValidListAndQueue();----->创建两个列表一个队列,当前定时器列表与溢出列表
            //两个列表
            vListInitialise( &xActiveTimerList1 );
            vListInitialise( &xActiveTimerList2 );
            //一个命令队列
            xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
        //创建任务
        xTaskCreate(	prvTimerTask, configTIMER_SERVICE_TASK_NAME, configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );

        //任务处理

        

        //从pxCurrentTimerList列表头部获取下一个定时器

        xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );

prvProcessTimerOrBlockTask()

//获取当前时间
1 prvSampleTimeNow()
//判断是否超时
2 if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
    //超时处理
    2.1 prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
        //从列表移除
        2.1.1 uxListRemove( &( pxTimer->xTimerListItem ) );
        //判断是否是周期定时器
        2.1.2 if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
        //如果是周期定时器则重新装载
        2.1.3 if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE )
        //如果不是周期定时器则改变timer状态
        2.3.4 pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
    //未超时处理,判断溢出列表是否为空
    2.2 xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList );
    //把当前定时器任务加入到等待列表中,等待消息
    2.3 vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty );

    

        需要注意的是,当定时器任务加入到等待列表之后,无法接收队列消息,只有等待系统时间片到达唤醒时,才可以调用prvProcessReceivedCommands()函数进行队列消息接收处理。

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值