FreeRTOS的时间管理

最近需要将在Linux上的代码移植到FreeRTOS上,许多系统函数运行不了,其中就包括gettimeofday,以及使用定时器的不同。

FreeRTOS添加计时器

首先,FreeRTOS的系统时钟节拍可以在配置文件 FreeRTOSConfig.h  里面设置:

#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )//配置系统时钟1KHz,即 1ms

在FreeRTOS中,系统时钟节拍的特点就是周期性中断,既然要产生中断那就需要定时器,所以在这里就是使用了一个24位的定时器,采用向下计数的方式,然后可以产生周期性的中断。

xTaskGetTickCount

TickType_t xTaskGetTickCount( void )

该函数用于获取系统当前运行的时钟节拍数。

注意:此函数用于在任务代码里面调用,如果在中断服务程序里面调用的话,需要使用函数 xTaskGetTickCountFromISR ,这两个函数切不可混用。

xTimerCreate

TimerHandle_t xTimerCreate(    const char * const pcTimerName,                // 名称,内核中不使用它,仅用于调试
                                const TickType_t xTimerPeriodInTicks,       // 时长 tick
                                const UBaseType_t uxAutoReload,          // 设置为pdTRUE表示该定时器为自动重载定时器,设置为pdFALSE该定时器为一次性定时器
                                void * const pvTimerID,               // 每个软件定时器都有一个ID值,由应用程序决定它的用途。pvTimerID表示该定时器ID的初始值
                                TimerCallbackFunction_t pxCallbackFunction )    // 回调函数指针

该函数用来创建一个定时器。

xTimerStart

#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
 
// 软件定时器打包命令与发送
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer,                   // 定时器的句柄
                    const BaseType_t xCommandID,
                    const TickType_t xOptionalValue,
                    BaseType_t * const pxHigherPriorityTaskWoken,
                    const TickType_t xTicksToWait )

该函数用于启动处于休眠态的软件定时器,或重置(重新启动)处于运行态的软件定时器。  xTimerStop() 用于停止处于运行态的软件计时器。 可以在启动调度程序之前调用 xTimerStart() ,但该操作会在调度程序启动之前启动定时器。
注意:不能在中断函数中调用 xTimerStart() ,中断安全版为 xTimerStartFromISR()  。

添加定时器样例

static void timer_1000ms_handler(TimerHandle_t xTimer)
{
    // (void)signum;
    (void)xTimer;

    loop_time = 0;
}

static int timer_init(void)
{
    TimerHandle_t xTimer = xTimerCreate("MyTimer", pdMS_TO_TICKS(1000), pdTRUE, 0, timer_1000ms_handler);
    if (xTimer != NULL) {
        xTimerStart(xTimer, 0);
    }
    else {
        perror("timer_settime failed");
        return errno;
    }
    return 0;
}

int main(void)
{
    timer_init();

vTaskStartScheduler();

while (1) {

}
return 0; }

vTaskDelay

void vTaskDelay( const TickType_t xTicksToDelay )

该函数用于task的延时,就是交出CPU一段时间,FreeRTOS延时的单位是tick,就是调度的基本单位,而不是毫秒。

使用方式:

while(1)
{
    //执行操作...
    vTaskDelay(1000 / portTICK_RATE_MS);//1000ms后重新执行操作
    // or
    vTaskDelay(pdMS_TO_TICKS(1000));
}

FreeRTOS的gettimeofday平替

gettimeofday介绍

#include<sys/time.h>

int gettimeofday(struct  timeval *tv,struct  timezone *tz )

在Linux平台上,使用函数该函数来得到精确时间。将得到的结果放入 struct timeval *tv 中,其结构为:

struct  timeval{
       long  tv_sec;      //
       long  tv_usec;    // 微秒
};

然而在FreeRTOS中并不提供该函数。

使用xTaskGetTickCount平替

 xTaskGetTickCount 函数返回的是当前系统的tick计数值,通过乘以 portTICK_PERIOD_MS (每个tick的毫秒数)可以得到以毫秒为单位的时间。
void getCurrentTime()
{
    TickType_t ticks = xTaskGetTickCount();
    uint32_t milliseconds = ticks * portTICK_PERIOD_MS;

    // 根据需要进行时间戳转换和处理
    // ...
    // 打印当前时间示例
    printf("Current Time: %lu ms\n", milliseconds);
}
posted @ 2023-10-10 11:31  ouyang_wsgwz  阅读(774)  评论(0编辑  收藏  举报