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

【FreeRTOS】创建一个任务的详细流程

目录

这三个函数的作用:

1. osKernelInitialize()

2. MX_FREERTOS_Init()

3. osKernelStart()

为什么这是必须的?

在 FreeRTOS 中创建新任务的详细流程

完整创建新任务的步骤

步骤 1: 在 freertos.c 中定义任务函数

步骤 2: 定义任务句柄和属性

步骤 3: 在 MX_FREERTOS_Init 中创建任务

步骤 4: 实现任务函数

关键概念解释

调试建议


必须在 main 函数中加入调度器的初始化、FreeRTOS 对象初始化和调度器启动代码,FreeRTOS 才能对任务进行调度。

/* Init scheduler */
osKernelInitialize();  // 初始化 FreeRTOS 内核/* Call init function for freertos objects (in cmsis_os2.c) */
MX_FREERTOS_Init();    // 创建任务、队列、信号量等 FreeRTOS 对象/* Start scheduler */
osKernelStart();       // 启动调度器,开始任务调度

这三个函数的作用:

1. osKernelInitialize()

  • 初始化 FreeRTOS 内核

  • 设置内核所需的数据结构和变量

  • 不启动任务调度,只是为调度做准备

2. MX_FREERTOS_Init()

  • 创建任务(如您的 defaultTask

  • 创建队列、信号量、互斥量等同步对象

  • 设置定时器等

  • 这个函数是 STM32CubeMX 自动生成的,包含了您通过图形界面配置的所有 FreeRTOS 对象

3. osKernelStart()

  • 启动任务调度器

  • 开始按照优先级调度任务

  • 从此控制权交给 FreeRTOS,main 函数中此后的代码不会执行

为什么这是必须的?

  1. 没有调度器,任务不会运行:即使创建了任务,如果没有启动调度器,这些任务只是存在于内存中,不会被执行。

  2. 执行顺序很重要:

    1. 必须先初始化内核 (osKernelInitialize)

    2. 然后创建任务和其他对象 (MX_FREERTOS_Init)

    3. 最后启动调度器 (osKernelStart)

  3. 控制权转移:osKernelStart() 是一个不会返回的函数(除非发生错误),它将 CPU 的控制权完全交给 FreeRTOS 调度器。

在 FreeRTOS 中创建新任务的详细流程

作为刚接触 RTOS 的小白,我来为您详细讲解创建新任务的完整流程。以您现有的代码为基础,我会用最简单的方式说明。

完整创建新任务的步骤

步骤 1: 在 freertos.c 中定义任务函数

首先创建一个新的任务函数,比如叫 TaskA

/* USER CODE BEGIN FunctionPrototypes */
// 声明任务函数
void StartTaskA(void *argument);
/* USER CODE END FunctionPrototypes */

步骤 2: 定义任务句柄和属性

在变量定义区域添加:

/* USER CODE BEGIN Variables */
/* Definitions for TaskA */
osThreadId_t taskAHandle;  // 任务句柄
const osThreadAttr_t taskA_attributes = {.name = "TaskA",          // 任务名称.stack_size = 128 * 4,    // 栈大小(字节).priority = (osPriority_t) osPriorityNormal,  // 优先级
};
/* USER CODE END Variables */

步骤 3: 在 MX_FREERTOS_Init 中创建任务

在初始化函数中找到创建任务的地方,添加新任务的创建代码:

void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init *//* USER CODE END Init */// ... 其他初始化代码 .../* Create the thread(s) *//* creation of defaultTask */defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);/* creation of TaskA */taskAHandle = osThreadNew(StartTaskA, NULL, &taskA_attributes);  // 添加这行/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS */
}

步骤 4: 实现任务函数

在文件末尾实现任务函数的具体逻辑:

/* USER CODE BEGIN Application */
// 实现 TaskA 任务函数
void StartTaskA(void *argument)
{/* 任务初始化代码 */log_i("TaskA started");/* 无限循环 - 这是RTOS任务的标准模式 */for(;;){log_i("TaskA is running");HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);  // 示例:切换LED状态osDelay(500);  // 延迟500ms}
}
/* USER CODE END Application */

关键概念解释

  1. 任务句柄 (osThreadId_t):就像任务的身份证,用来标识和管理任务

  2. 任务属性 (osThreadAttr_t):

    1. name:任务名称,调试时有用

    2. stack_size:任务栈大小,根据任务需求调整

    3. priority:任务优先级,数字越大优先级越高

  3. osThreadNew():创建新任务的函数

    1. 参数1:任务函数指针

    2. 参数2:传递给任务的参数

    3. 参数3:任务属性

  4. 任务函数格式:必须包含无限循环,否则任务执行一次就会结束

调试建议

  1. 使用 log_i() 输出信息查看任务运行情况

  2. 如果任务没有运行,检查优先级设置

  3. 确保栈大小足够,避免栈溢出

现在已经成功创建了两个任务:defaultTaskTaskA。FreeRTOS 调度器会自动根据优先级调度这两个任务。


文章转载自:

http://0RFdEKO1.xqjrg.cn
http://4fG7gmsv.xqjrg.cn
http://b4WRgqZy.xqjrg.cn
http://ovv7kd8O.xqjrg.cn
http://hiTtQWIO.xqjrg.cn
http://ZvJoxEx7.xqjrg.cn
http://yyR3T1dS.xqjrg.cn
http://9jo2RwRd.xqjrg.cn
http://HRc3kaTh.xqjrg.cn
http://nBM4sS0B.xqjrg.cn
http://wIKwPmGj.xqjrg.cn
http://cjemt0Az.xqjrg.cn
http://MUdDUG8A.xqjrg.cn
http://h3fe1B76.xqjrg.cn
http://nnOahN5W.xqjrg.cn
http://JzOY08EK.xqjrg.cn
http://Ut8ELz9T.xqjrg.cn
http://NTpaF4Eo.xqjrg.cn
http://sIwdbC0U.xqjrg.cn
http://xNwceTea.xqjrg.cn
http://hdoLEQRK.xqjrg.cn
http://LiLFIJ5Z.xqjrg.cn
http://3WKlCqbg.xqjrg.cn
http://to6Lx64X.xqjrg.cn
http://vvRHL8yf.xqjrg.cn
http://aeY2vXB7.xqjrg.cn
http://8QY6DyIu.xqjrg.cn
http://iOQ8uv7X.xqjrg.cn
http://kWh3WuQm.xqjrg.cn
http://iRO3cGCN.xqjrg.cn
http://www.dtcms.com/a/387131.html

相关文章:

  • CKA06--storageclass
  • 宝塔安装以及无法打开时的CA证书配置全攻略
  • wend看源码-Open_Deep_Research(LangChain)
  • 摄像头文档识别与透视变化技术和背景建模技术(追踪)
  • 123、【OS】【Nuttx】【周边】效果呈现方案解析:find 格式化打印
  • DC-4靶机渗透
  • 大模型在线对话平台集锦(持续更新ing...)
  • JavaScript中 i++ 与 ++i
  • 【cookie】JavaScript操作增删改查
  • OC-AFNetworking
  • Java全栈学习笔记35
  • kylin v10 系统 上 qt 5.15.17版本构建及使用
  • Linux:基于环形队列的生产者消费模型
  • Nginx 配置 Vue 项目 Hash/History 模式路由跳转错误的解决方案
  • Linux Makefile与进度条
  • 硬件驱动——I.MX6ULL裸机启动(3)(按键设置及中断设置
  • 深度学习基本模块:RNN 循环神经网络
  • 【深度学习】PixelShuffle处理操作
  • 10.1 - 遗传算法(旅行商问题C#求解)
  • Java 集合入门:从基础到实战的完整知识指南
  • 《过山车大亨3 完整版》PSXbox版下月推出 预告片赏
  • P1107题解
  • 多目标数据关联算法MATLAB实现
  • 战略推理AI Agents:组装LLM+因果推断+SHAP
  • 【CVPR 2016】基于高效亚像素卷积神经网络的实时单幅图像与视频超分辨率
  • 基于STM32的LED实战 -- 流水灯、呼吸灯、流水呼吸灯
  • 【数据结构】——队列,栈(基于链表或数组实现)
  • 任天堂官网更新!“任亏券”不支持兑换NS2专用游戏
  • 大模型数据整理器打包及填充、Flash Attention 2解析(97)
  • 48v转12v芯片48v转5v电源芯片AH7691D