当前位置: 首页 > article >正文

FreeRTOS 时间管理

1. 系统时钟节拍:FreeRTOS 的心跳

FreeRTOS 的时间管理基于系统时钟节拍(tick),它就像是 FreeRTOS 的心跳,为系统提供了最基本的时间单位。这个节拍由硬件定时器(通常是 SysTick)产生,FreeRTOS 会根据配置的节拍率(configTICK_RATE_HZ)来设置定时器的中断频率。例如,如果 configTICK_RATE_HZ 设置为 1000,那么系统时钟节拍的周期就是 1 毫秒。

在 FreeRTOS 中,有一个全局变量 xTickCount,它记录了系统自启动以来的时钟节拍数每次时钟节拍中断发生时,xTickCount 的值就会加 1

这个变量是 FreeRTOS 时间管理的核心,许多时间相关的函数都依赖于它

2. 任务延时:

FreeRTOS 提供了两种主要的任务延时函数:

2.1 vTaskDelay 函数

vTaskDelay 函数用于让任务进入阻塞状态一段时间,以实现延时功能。

比如说,你有一个任务是每隔一段时间就去读取一下传感器的数据。那这个任务就可以在读完数据后,给自己安排一段 “小憩” 时光,也就是调用任务延迟函数。函数会告诉 FreeRTOS:“我要休息 X 个时间滴答啦,这段时间不能干活。” 这样,在这 X 个时间滴答内,这个任务就会乖乖地 “睡觉”,把 CPU 资源让给其他需要工作的任务。

延时的时间以 FreeRTOS 的时钟节拍为单位。例如:

vTaskDelay(pdMS_TO_TICKS(1000));  // 延时 1000 毫秒

在这个函数中,pdMS_TO_TICKS(1000) 将 1000 毫秒转换为对应的时钟节拍数。

2.2 vTaskDelayUntil 函数

vTaskDelayUntil 函数用于设置任务的周期性执行,它在指定的绝对时间执行任务,而不是相对于当前时间的相对延时。例如:

TickType_t xLastWakeTime = xTaskGetTickCount();

for (;;)
{
    // 任务执行的代码

    // 等待下一个周期
    vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(1000));
}

在这个例子中,xLastWakeTime 记录了任务上次唤醒的时间,vTaskDelayUntil 会根据这个时间计算下一个唤醒时间。

3. 获取系统时间:时间的“眼睛”

FreeRTOS 提供了 xTaskGetTickCount 函数,用于获取系统自启动以来的时钟节拍数。例如:

c复制

TickType_t currentTickCount = xTaskGetTickCount();

此外,xTaskGetTickCountFromISR 函数用于在中断服务例程(ISR)中获取时钟节拍数。

4. 软件定时器:时间管理的“瑞士军刀”

FreeRTOS 的软件定时器是一种更灵活的时间管理工具,可以用于周期性执行任务或在一段时间后触发事件。

比如说,你想让某个设备每隔 10 秒就自动执行一次清理操作,这时候软件定时器就派上用场了。你可以创建一个软件定时器,设置好定时时间,再指定一个回调函数(也就是到时间后要执行的操作)。一旦定时器启动,它就会默默倒计时,时间一到,就会立刻触发回调函数。

4.1 创建定时器

使用 xTimerCreate 函数创建定时器,并指定回调函数。例如:

c复制

TimerHandle_t xTimer = xTimerCreate(
    "MyTimer",               // 定时器名称
    pdMS_TO_TICKS(1000),     // 周期为 1000 毫秒
    pdTRUE,                  // 自动重载
    NULL,                    // 定时器ID
    vTimerCallback);         // 回调函数
4.2 启动定时器

使用 xTimerStart 函数启动定时器:

c复制

if (xTimer != NULL)
{
    xTimerStart(xTimer, 0);
}
4.3 定时器回调函数

在回调函数中,可以执行相应的操作。例如:

c复制

void vTimerCallback(TimerHandle_t xTimer)
{
    printf("Timer expired!\n");
}

5. 时间片轮转:任务的“公平分配”

FreeRTOS 支持时间片轮转功能,通过 vApplicationTickHook 回调函数实现。用户需要在 FreeRTOSConfig.h 文件中将 configUSE_TICK_HOOK 宏定义为 1。时间片的长度由 configTICK_RATE_HZ 宏定义。

例如,以下代码展示了如何使用时间片轮转来统计系统运行时间:

c复制

uint32_t TickNum = 0;

void vApplicationTickHook(void)
{
    TickNum++;
}

void vTaskPrint(void * pvParameters)
{
    uint32_t TickNum_Minute = 0;
    uint32_t TickNum_old = 0;
    while(1)
    {
        if (TickNum/configTICK_RATE_HZ != 0 && TickNum_old != TickNum/configTICK_RATE_HZ)
        {
            TickNum_old = TickNum/configTICK_RATE_HZ;
            if (TickNum_old > 59)
            {
                TickNum_Minute += 1;
                TickNum_old = 0;
                TickNum -= 60*configTICK_RATE_HZ;
            }
            printf("The current system runs for %d minute %d second\n\r", TickNum_Minute, TickNum/configTICK_RATE_HZ);
        }
    }
}

6. 实际应用案例:LED 闪烁与按键检测

以下是一个综合应用示例,展示了如何使用 FreeRTOS 的时间管理功能实现 LED 闪烁和按键检测:

c复制

void vTaskLED3(void * pvParameters)
{
    while(1)
    {
        for (uint8_t j=0; j<10; j++)
        {
            R_LED(ON);
            vTaskDelay(300/portTICK_RATE_MS);
            R_LED(OFF);
            vTaskDelay(300/portTICK_RATE_MS);
        }
    }
}

void vTaskKEY4(void * pvParameters)
{
    while(1)
    {
        if (Key_GetNum() == 1)
        {
            printf("Idle tasks run %d times\n\r", IdleNumber);
        }
        if (Key_GetNum() == 2)
        {
            printf("Delay of %d system beats\n\r", DataDelay);
        }
        if (Key_GetNum() == 3)
        {
            printf("DelayUntil of %d system beats\n\r", DataDelayUntil);
        }
        vTaskDelay(100/portTICK_RATE_MS);
    }
}

http://www.kler.cn/a/560946.html

相关文章:

  • 数据库面试题(基础常考!!!)
  • 深入理解 CSS pointer-events: none:穿透点击的魔法
  • Centos中将UTC的时区改为CTS时区
  • 【数据库】【MySQL】索引
  • STM32CUBEIDE FreeRTOS操作教程(十三):task api 任务访问函数
  • 目标检测之FAST RCNN论文简读
  • AIGC技术助力空军招飞,近屿智能开启智能人才培育新征程
  • SSTI知识点汇总
  • docker离线安装记录
  • Vulnhun靶机-kioptix level 4-sql注入万能密码拿到权限ssh连接利用mysql-udf漏洞提权
  • 05C语言——数组
  • 95.【C语言】解析预处理(3)
  • 【安装及调试旧版Chrome + 多版本环境测试全攻略】
  • [特殊字符] Elasticsearch 双剑合璧:HTTP API 与 Java API 实战整合指南
  • 塔能科技构建智慧隧道生态系统——城市升级改造的协同创新典范
  • 【Java项目】基于Spring Boot的简历系统
  • 电脑没声音了怎么恢复正常?一键恢复电脑声音
  • 使 Windows 呈现 macOS 风格的多功能桌面美化软件
  • 连锁管理系统的五大核心设计及 PHP 源码分享
  • 【深度解析:基于 C 语言实现含 IP 城市地址因素的抖音式简化推荐算法】