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

freertos.c解析 - 教程

一,代码解析

/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */

版权信息

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

初始化的头文件

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "user_TasksInit.h"
/* USER CODE END Includes */

用户自定义任务初始化头文件

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */

这些部分都是 STM32CubeMX 预留的用户代码区。目前它们是空的,但用户可以在其中添加自己的类型定义、宏、常量或全局变量。

/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};

defaultTaskHandle : 这是一个 osThreadId_t 类型的变量,用于在任务创建后存储该任务的句柄。通过这个句柄,可以在程序中的其他地方引用并控制这个任务(例如暂停、恢复、删除等)。

defaultTask_attributes : 这是一个 osThreadAttr_t 结构体,定义了 defaultTask 的属性:
.name = “defaultTask”: 给任务一个字符串名称,在调试工具(如 FreeRTOS 的任务查看器)中会显示这个名称,方便识别。

.stack_size = 128 * 4: 定义任务的堆栈大小。

.priority = (osPriority_t) osPriorityNormal: 设置任务的执行优先级。osPriorityNormal 是 CMSIS-RTOS 定义的一个标准优先级。FreeRTOS 调度器总是执行处于就绪态的最高优先级任务。

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
void MX_FREERTOS_Init(void);
/* (MISRA C 2004 rule 8.1) */
/* Hook prototypes */
void vApplicationIdleHook(void);
void vApplicationTickHook(void);
/* USER CODE BEGIN 2 */
void vApplicationIdleHook( void )//空闲任务钩子(作用:当没有任何其他任务可以运行时,FreeRTOS 的空闲任务(Idle Task)会被调度执行,而 vApplicationIdleHook() 会在空闲任务的每次迭代中被调用。)
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
}
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
void vApplicationTickHook( void )时钟节拍钩子(作用:这个函数会在每个 FreeRTOS 时钟节拍中断发生时被调用。时钟节拍中断是 FreeRTOS 调度器的心跳,用于时间管理和任务调度。)
{
/* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
TaskTickHook();
}
/* USER CODE END 3 */
/**
* @brief FreeRTOS initialization
* @param None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
User_Tasks_Init();
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}

这是 FreeRTOS 的主初始化函数,通常在 main() 函数中通过 MX_FREERTOS_Init(); 调用。
User_Tasks_Init(): 这是用户自定义任务的初始化函数,它会在 defaultTask 创建之前被调用。这意味着用户可以在这个函数中创建其他应用所需的任务。这体现了模块化的设计,将用户自定义任务的创建逻辑与 freertos.c 的骨架分离。
RTOS_MUTEX / SEMAPHORES / TIMERS / QUEUES / THREADS / EVENTS: 这些都是 STM32CubeMX 生成的用户代码区。它们预留了位置,供用户通过 CMSIS-RTOS API 创建:
互斥量 (Mutexes) : 用于保护共享资源,防止多个任务同时访问导致数据不一致。
信号量 (Semaphores) : 用于任务同步或资源计数。
软件定时器 (Timers) : 用于周期性执行代码或在一定时间后执行一次代码。
消息队列 (Queues) : 用于任务间传递数据。
其他线程 (Threads) : 除了 defaultTask,用户可以在这里创建更多自己的任务。
事件标志组 (Events) : 用于任务之间发送和接收事件信号。
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);: 这是实际创建 defaultTask 的代码。
StartDefaultTask: 是该任务的入口函数。
NULL: 表示没有参数传递给 StartDefaultTask 函数。
&defaultTask_attributes: 使用前面定义的任务属性。

/* USER CODE BEGIN Header_StartDefaultTask */
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;
;
)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
osDelay(500);
}
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */

这是默认任务执行的代码

二,总结

首先是定义了defaultask的句柄,通过defaultTask_attributes定义了defaulttask的属性(名字,栈的大小,优先级),在MX_FREERTOS_Init(void) 中调用User_Tasks_Init()。最后定义了默认任务

http://www.hskmm.com/?act=detail&tid=14480

相关文章:

  • 从缺陷管理到质量协作:现代Bug工具的范式升级
  • 【html组件】简易漫画阅读器
  • ubuntu安装mysql2
  • 高并发系统核心指标
  • 工程化知识管理新范式:DevOps驱动下的智能文档体系建设实践
  • 从零开始学Flink:数据转换的艺术
  • java创建线程池去实现某个任务(多线程)
  • 20250827_黔西南网信杯_丢失的数据
  • 敏捷已死?2025年项目管理软件支持的混合管理模式正成为新主流!
  • 螺旋矩阵-leetcode
  • 【第十一章】Python 调用 MySQL 全面指南:从基础到实践​ - 实践
  • 开源中国社区:AI驱动下的开发者生态革命
  • 日志清理脚本模板 - 一叶舟
  • 11.备库出现gap处理方法
  • [原创]《C#高级GDI+实战:从零开发一个流程图》第10章:鼠标拖动完成连线、拖动时实时显示半透明虚线连线效果、自定义连接点样式
  • 修改Abp中Auto API Controllers中 默认生成的 Put、Delete请求
  • 电阻-温度数据拟合工具(最小二乘法)
  • delphi clientdataset 中文过滤问题
  • 基于 systemd 的 Go 应用自动化部署完整指南
  • 马来西亚股票数据API对接文档
  • [OpenGL]相机环境
  • 指令流水线的影响因素
  • Gitee本土化创新实践:中国企业研发效能提升的新引擎
  • 画面拼接后推流/64路画面同时拼接到一路流/指定程序窗口采集推流/另一种解决方案
  • Markdown的基本语法
  • 工业级CAD数据优化工具:PiXYZ Studio 2025 图文安装指南
  • BIM建模利器 Tekla Structures 2025 全流程安装指南
  • containerd离线安装
  • (转)使用 Embarcadero Delphi FMX 应用程序实现多点触控
  • 百度云服务ubtuntu安装docker