[应用相关] STM32(HAL库)FreeRTOS的创建与使用

[复制链接]
86|0
Xiashiqi 发表于 2025-11-6 15:22 | 显示全部楼层 |阅读模式
一、FreeRTOS介绍


FreeRTOS 是市场领先的嵌入式系统 RTOS,支持 40+ 处理器架构,内存占用小,执行时间快,具有尖端的 RTOS 功能和库,包括对称多处理 (SMP)、支持 IPv6 的线程安全 TCP 堆栈,以及与云服务的无缝集成。它是开源的,并得到积极支持和维护。

源代码可以在官方网址:https://www.freertos.org/,在里面进行下载,我是通过STM32CubeMX进行创建,就不通过移植和解释和了解内核了,有兴趣的可以自己去查资料,本文主要记录FreeRTOS的调用。

二、使用STM32CubeMX创建FreeRTOS项目
首先使用STM32CubeMX创建新项目,选择自己需要使用的芯片,我使用的是STM32C8T6

44858690c1e5e1767d.png

RCC按我设置就行

59327690c1e590506e.png

SYS设置,如果使用stlink下载或者调试,debug选择Serial Wire,时钟尽量不要选择SysTick和TIM1,SysTick是ARM Cortex-M内核自带的一个简易定时器,像一个“心脏起搏器”,每隔固定时间(通常是1ms)产生一次中断,当使用FreeRTOS后会被系统接管。SysTick作用很重要,一为HAL库提供时间基准二为操作系统提供心跳。而TIM1是高级寄存器,用来作为HAL的计时太过浪费。时基源尽量冲另外的TIm中使用,我选择的是TIM3。

89164690c1e5404a64.png

然后更根据自己的使用情况配置相关的引脚

57024690c1e4ebaef3.png

在左侧找到Middleware and Software Packs,选择FreeRTOS,如图所示:

69421690c1e4acff16.png

我主频设置的最高,以最高速率运行。大家有需要更具自己的应用场景选择

24880690c1e44a062d.png

然后设置一些基础,我就不过多介绍了,可以看我上片文章:https://blog.csdn.net/qq_52684099/article/details/153901792?spm=1011.2124.3001.6209

16351690c1e3d8064c.png

7137690c1e396195a.png

最后点击右上角的GENERATE CODE生成代码,然后如图直接打开项目就行了:

59169690c1e33537f0.png

然后点击编译,基本是0错误0警告

49939690c1e2d9aaba.png

三、FreeRTOS的简单使用和部分代码解释
1. 任务定义
/* Definitions for defaultTask */

osThreadId_t defaultTaskHandle; // 任务句柄,用于引用和控制这个任务

const osThreadAttr_t defaultTask_attributes = { // 任务的属性配置

  .name = "defaultTask",        // 任务名,调试时有用

  .stack_size = 128 * 4,       // 任务栈大小:128字 * 4字节/字 = 512字节

  .priority = (osPriority_t) osPriorityNormal, // 任务优先级:普通优先级

}

(一)其中关于常用优先级结构体定义,后续添加任务更具需求使用,一般使用最多的优先级为以下几个,其他优先级可以去cmsis_os.h文件中看详细的解释。

priority = osPriorityLow;        // 最常用的低优先级,一般用于后台任务、数据记录、统计信息

priority = osPriorityNormal;     // 默认优先级,最常用,一般用于大部分普通任务、常规功能处理

priority = osPriorityHigh;        // 高优先级任务,一般用于用户交互、通信处理、紧急事件

priority = osPriorityRealtime;    // 最高优先级,慎用,一般用于电机控制、安全关键功能

(二)任务栈的大小的选择

更具自己的使用场景需要进行大小设置,此展示的为一般大小,已经可以满足大部分场合了。

2、任务添加和任务使用
以下为其中一个示例,比如在一个基础上添加一个led示例:

osThreadId_t ledTaskHandle;  

const osThreadAttr_t ledTask_attributes = {

  .name = "LedTask",         

  .stack_size = 128 * 4,     

  .priority = (osPriority_t) osPriorityNormal,  

};

在初始化中添加相关任务

void MX_FREERTOS_Init(void) {

  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);//原有任务

  /* 创建LED闪烁任务 */

  ledTaskHandle = osThreadNew(StartLedTask, NULL, &ledTask_attributes);

  // ... 其他代码

}

记得在最后添加多任务函数,一定要记得将函数在init前声明,

void StartLedTask(void *argument)

{



  /* 任务主循环 */

  for(;;)

  {

    osDelay(1000);  // 延时1秒

  }

}

3、freertos.h完整代码示例:

#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
#include "tim.h"


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

osThreadId_t ledTaskHandle;  
const osThreadAttr_t ledTask_attributes = {
  .name = "LedTask",        
  .stack_size = 128 * 4,     
  .priority = (osPriority_t) osPriorityNormal,  
};

void StartDefaultTask(void *argument);
void StartLedTask(void *argument);  

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */


void MX_FREERTOS_Init(void) {
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

    ledTaskHandle = osThreadNew(StartLedTask, NULL, &ledTask_attributes);

}


void StartDefaultTask(void *argument)
{

  for(;;)
  {
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 1500);
    osDelay(1);
  }

}

void StartLedTask(void *argument)
{

  for(;;)
  {
    osDelay(1000);  
  }
}

45816690c1e1d031fc.png

(如有问题请指正)
————————————————
版权声明:本文为CSDN博主「爱学习嵌入式的小白」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_52684099/article/details/154174386

您需要登录后才可以回帖 登录 | 注册

本版积分规则

105

主题

310

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部