关于FreeRTOS中定时器创建的一个错误

问题

有两种创建定时器的方式,刚开始我把定时器作为局部变量来使用。
后来出于业务需求,需要把定时器作为全局变量来使用,就出现了下面的问题。

// 创建周期性定时器,周期为1s(手动)
TimerHandle_t countdown_timer;
countdown_timer = xTimerCreate("CountdownTimer", pdMS_TO_TICKS(1000), pdTRUE, (void *)0, CountdownTimerCallback);

void Ctrl_Task_Func(void *argument)
{
    while(1)
    {
    }
}

这样就报错:

…\App\task_ctrl.c(13): error: #77-D: this declaration has no storage class or type specifier

…\App\task_ctrl.c(13): error: #147: declaration is incompatible with “TimerHandle_t countdown_timer” (declared at line 12)

…\App\task_ctrl.c(13): error: #59: function call is not allowed in a constant expression

解决

// 创建周期性定时器,周期为1s(手动)
TimerHandle_t countdown_timer;

void Ctrl_Task_Func(void *argument)
{
    countdown_timer = xTimerCreate("CountdownTimer", pdMS_TO_TICKS(1000), pdTRUE, (void *)0, CountdownTimerCallback);

    while(1)
    {
    }
}

像这样,把定时器创建放在任务函数中,就没有任何错误。这是为啥呢?
查阅资料发现:

  • xTimerCreate() 是 FreeRTOS 中的 API,用于创建定时器。它不能在全局作用域中调用。FreeRTOS 的定时器需要与 RTOS 的调度和内存管理配合工作,而它在调用时需要保证任务调度环境已经初始化好(如系统时钟、调度器等),而这些通常只在任务调度启动之后才可用。

  • countdown_timer 是在全局作用域声明的,但如果它在声明时直接调用 xTimerCreate(),编译器会把 xTimerCreate() 当成一个不符合全局变量声明规则的函数调用,因为它应该在任务或初始化阶段进行,而不是在全局声明部分。

因此,不要在全局作用域中调用 xTimerCreate(),应该在任务中进行调用。

### FreeRTOS 软件定时器使用方法 #### 创建软件定时器 创建一个软件定时器可以通过调用 `xTimerCreate` 函数完成。此函数允许指定定时器名称、周期时间、是否自动重载以及回调函数。 ```c TimerHandle_t xTimer; const TickType_t xTimerPeriodInTicks = pdMS_TO_TICKS(100); // 100ms 周期 // 创建一个周期性的软件定时器 xTimer = xTimerCreate( "Timer", /* 定时器名字 */ xTimerPeriodInTicks, /* 周期时间 (ticks) */ pdTRUE, /* 自动重装载 */ (void *)0, /* 定时器ID */ vTimerCallback /* 回调函数 */ ); ``` #### 启动和停止定时器 一旦创建定时器,就可以通过 `xTimerStart` 和 `xTimerStop` 来控制其启动与停止状态。 ```c if (xTimer != NULL) { // 启动定时器 if (xTimerStart(xTimer, 0) != pdPASS) { // 处理启动失败的情况 } // ... 运行一段时间 ... // 停止定时器 if (xTimerStop(xTimer, 0) != pdPASS) { // 处理停止失败的情况 } } ``` #### 删除定时器 当不再需要某个定时器时,应该调用 `vTimerDelete` 将其删除以释放资源。 ```c if (xTimer != NULL) { vTimerDelete(xTimer); } ``` #### 设置定时器行为 FreeRTOS 的软件定时器支持多种配置选项,比如设置为一次性触发还是重复触发等特性[^4]。 ```c // 修改已存在的定时器属性 configTIMER_ENABLE_AUTO_RELOAD; // 开启/关闭自动重载模式 ``` #### 错误处理机制 为了确保系统的稳定性,在每次调用 API 函数之后都应该检查返回值并采取相应的措施来应对潜在的问题。 ```c BaseType_t xReturn; xReturn = xTimerChangePeriod(xTimer, newPeriod, portMAX_DELAY); if (xReturn == pdFAIL) { // 执行错误恢复逻辑... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值