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

STM32 FreeRTOS基础

FreeRTOS 核心 API 函数详解:从任务管理到定时器控制

介绍 FreeRTOS 中几个最常用的核心 API 函数,包括任务管理、延时控制和定时器操作等关键功能。

任务管理核心函数

xTaskCreate:创建任务

xTaskCreate是 FreeRTOS 中创建任务的基础函数,用于在系统中创建一个新任务并将其添加到就绪列表中。

BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, // 任务函数指针const char *const pcName, // 任务名称(调试用)const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小void *pvParameters, // 传递给任务的参数UBaseType_t uxPriority, // 任务优先级(0~configMAX_PRIORITIES-1)TaskHandle_t *pxCreatedTask // 任务句柄(可用于后续操作)
);

参数说明

  • pvTaskCode:任务函数,必须是一个无限循环结构,不能返回
  • pcName:任务名称,仅用于调试识别,最大长度由configMAX_TASK_NAME_LEN定义
  • usStackDepth:任务栈大小,单位是字 (不是字节),与处理器架构有关
  • pvParameters:传递给任务函数的参数,可以为 NULL
  • uxPriority:任务优先级,数值越大优先级越高
  • pxCreatedTask:输出参数,用于接收创建的任务句柄,可设为 NULL

返回值

  • pdPASS:任务创建成功
  • errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:内存不足,任务创建失败

vTaskDelete:删除任务

vTaskDelete用于永久删除一个任务,被删除的任务将从所有就绪、阻塞、挂起等列表中移除。

void vTaskDelete(TaskHandle_t xTaskToDelete);

参数说明

  • xTaskToDelete:要删除的任务句柄,若为 NULL 则删除当前任务

注意事项

  • 被删除任务所占用的内存 (栈和 TCB) 只有在使用动态内存管理时才会自动释放
  • 不能删除空闲任务和定时器服务任务
  • 删除其他任务时要确保该任务不再被使用,避免悬空句柄

vTaskSuspend:挂起任务

vTaskSuspend用于将指定任务挂起,挂起的任务不会被调度器选中运行,直到被恢复。

void vTaskSuspend(TaskHandle_t xTaskToSuspend);

参数说明

  • xTaskToSuspend:要挂起的任务句柄,若为 NULL 则挂起当前任务

特点

  • 挂起操作可以嵌套,即多次挂起需要相同次数的恢复操作
  • 挂起不会释放任务已获取的资源
  • 处于任何状态的任务都可以被挂起

vTaskResume:恢复任务

vTaskResume用于恢复被挂起的任务,使其重新进入调度队列。

void vTaskResume(TaskHandle_t xTaskToResume);

参数说明

  • xTaskToResume:要恢复的任务句柄,不能为 NULL

使用示例

// 挂起任务vTaskSuspend(xHandle);// 一段时间后恢复任务vTaskResume(xHandle);

延时函数

vTaskDelay:相对延时

vTaskDelay提供相对延时功能,使当前任务进入阻塞状态指定的时间。

void vTaskDelay(const TickType_t xTicksToDelay);

参数说明

  • xTicksToDelay:延时的节拍数,系统节拍由configTICK_RATE_HZ配置

特点

  • 相对延时:从调用时刻开始计算延时时间
  • 延时期间任务进入阻塞状态,CPU 可以调度其他任务
  • 实际延时时间可能大于等于指定时间,受系统调度影响

使用示例

// 延时100个节拍,如果configTICK_RATE_HZ=1000,则约为100msvTaskDelay(100);// 延时1秒的跨平台写法vTaskDelay(pdMS_TO_TICKS(1000));

定时器控制函数

xTimerCreate:创建软件定时器

xTimerCreate用于创建一个软件定时器,软件定时器是基于系统节拍的定时机制。

TimerHandle_t xTimerCreate(const char *const pcTimerName, // 定时器名称const TickType_t xTimerPeriodInTicks, // 定时器周期(节拍数)const UBaseType_t uxAutoReload, // 是否自动重载void *pvTimerID, // 定时器IDTimerCallbackFunction_t pxCallbackFunction // 回调函数
);

参数说明

  • pcTimerName:定时器名称,仅用于调试
  • xTimerPeriodInTicks:定时器周期,单位为节拍
  • uxAutoReload:pdTRUE表示自动重载 (周期性触发),pdFALSE表示一次性触发
  • pvTimerID:定时器 ID,可用于在回调函数中区分不同定时器
  • pxCallbackFunction:定时器超时回调函数

返回值

  • 成功:返回创建的定时器句柄
  • 失败:返回 NULL (通常是内存不足)

xTimerStart:启动定时器

xTimerStart用于启动一个已创建的定时器,使其开始计时。

BaseType_t xTimerStart(TimerHandle_t xTimer, TickType_t xTicksToWait);

参数说明

  • xTimer:要启动的定时器句柄
  • xTicksToWait:等待时间,若定时器命令队列满,最多等待的节拍数

返回值

  • pdPASS:启动成功
  • errQUEUE_FULL:失败,通常是命令队列满

xTimerStop:停止定时器

xTimerStop用于停止一个正在运行的定时器。

BaseType_t xTimerStop(TimerHandle_t xTimer, TickType_t xTicksToWait);

参数说明

  • xTimer:要停止的定时器句柄
  • xTicksToWait:等待时间,若定时器命令队列满,最多等待的节拍数

返回值

  • pdPASS:停止成功
  • errQUEUE_FULL:失败,通常是命令队列满

例子:

创建两个任务,一个是普通任务,一个是定时器任务

  • 普通任务通过xTaskCreate创建,xTimerStart 和 xTimerStop 开启和关闭定时器任务。
  • 定时器任务通过xTimerCreate创建 ,vTaskSuspend 和 vTaskResume 挂起和恢复普通任务。

// Task priorities
#define START_TASK_PRIO		1
#define LED_TASK_PRIO		2// Task stack sizes
#define START_STK_SIZE 		128
#define LED_STK_SIZE 		128// Task handles
TaskHandle_t StartTask_Handler;
TaskHandle_t LedTask_Handler;
TimerHandle_t PrintTimer_Handler;// Task functions
void start_task(void *pvParameters);
void led_task(void *pvParameters);// Timer callback function
void TimerCallback(TimerHandle_t xTimer);int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // Set system interrupt priority group 4delay_init(168);            // Initialize delay functionuart_init(115200);          // Initialize serial portLED_Init();                 // Initialize LED portprintf("System initialization completed, preparing to start FreeRTOS...\r\n");// Create the start taskxTaskCreate((TaskFunction_t )start_task,(const char*    )"start_task",(uint16_t       )START_STK_SIZE,(void*          )NULL,(UBaseType_t    )START_TASK_PRIO,(TaskHandle_t*  )&StartTask_Handler);vTaskStartScheduler();      // Start task scheduling// If the program executes to this point, it means the scheduler failed to startwhile(1);
}// Start task - Create other tasks and delete itself
void start_task(void *pvParameters)
{BaseType_t xResult;printf("Start task is executing, creating LED and OLED tasks...\r\n");// Create the LED taskxResult = xTaskCreate((TaskFunction_t )led_task,(const char*    )"led_task",(uint16_t       )LED_STK_SIZE,(void*          )NULL,(UBaseType_t    )LED_TASK_PRIO,(TaskHandle_t*  )&LedTask_Handler);if(xResult != pdPASS) {printf("Failed to create LED task!\r\n");}// Create the timer, set to triggerPrintTimer_Handler = xTimerCreate("PrintTimer",          // Timer namepdMS_TO_TICKS(1000),   // Timer period in tickspdTRUE,                // Auto-reload timer(void*) 0,             // Timer IDTimerCallback          // Timer callback function);if(PrintTimer_Handler != NULL) {// Start the timerif(xTimerStart(PrintTimer_Handler, 0) != pdPASS) {printf("Failed to start timer!\r\n");}} else {printf("Failed to create timer!\r\n");}// Delete the start taskvTaskDelete(NULL);
}
// LED task - Control LED blinking
void led_task(void *pvParameters)
{int nCount = 0;while(1){nCount++;if (nCount == 10){printf("[LED Task] nCount = %d, Stop Timer\r\n", nCount);xTimerStop(PrintTimer_Handler, 0);}else if (nCount == 20){printf("[LED Task] nCount = %d, Start Timer\r\n", nCount);xTimerStart(PrintTimer_Handler, 0);}LED0 = ~LED0;  // Toggle LED stateprintf("[LED Task] LED state toggled, state: %d, nCount = %d\r\n", LED0, nCount);vTaskDelay(pdMS_TO_TICKS(500));}
}// Timer callback function
void TimerCallback(TimerHandle_t xTimer)
{static u16 count = 0;TickType_t currentTickCount = xTaskGetTickCount();printf("[Timer Task] Current TickCount: %lu, count = %d\r\n", (unsigned long)currentTickCount, count);count++;if(count == 10){printf("[Timer Task] Suspend LED Task, count: %d\r\n", count);vTaskSuspend(LedTask_Handler);        }else if(count == 20){printf("[Timer Task] Resume LED Task, count: %d\r\n", count);vTaskResume(LedTask_Handler);count = 0;}}

http://www.lryc.cn/news/600441.html

相关文章:

  • 垃圾回收算法与垃圾收集器
  • cacti的命令执行和回显
  • JVM参数
  • 学习游戏制作记录(剑投掷技能)7.26
  • Flutter开发实战之原生平台集成
  • 暑期算法训练.9
  • 如何查找php配置文件php.ini
  • ICMPv6报文类型详解表
  • 面条式代码(Spaghetti Code)
  • 编程与数学 03-002 计算机网络 06_网络层职责
  • RK3568笔记九十三:基于RKNN Lite的YOLOv5目标检测
  • 【Spring AI】SiliconFlow-硅基流动
  • MySQL操作进阶
  • 备份一下我的 mac mini 的环境变量配置情况
  • Android Studio Profiler工具使用流程
  • MyBatis_3
  • 零基础学后端-PHP语言(第二期-PHP基础语法)(通过php内置服务器运行php文件)
  • 【安全漏洞】防范未然:如何有效关闭不必要的HTTP请求方法,保护你的Web应用
  • Java中List集合对象去重及按属性去重
  • linux内核电源管理
  • Java同步锁性能优化:15个高效实践与深度解析
  • [spring6: Mvc-函数式编程]-源码解析
  • 栈----2.最小栈
  • 【VLLM】open-webui部署模型全流程
  • JavaWeb(苍穹外卖)--学习笔记11(Filter(过滤器) 和 Interceptor(拦截器))
  • JavaScript中.splice()的用法
  • 从压缩到加水印,如何实现一站式图片处理
  • 动态SQL标签
  • 【动态规划-斐波那契数列模型】理解动态规划:斐波那契数列的递推模型
  • 【深度之眼机器学习笔记】04-01-决策树简介、熵,04-02-条件熵及计算举例,04-03-信息增益、ID3算法