STM32 FreeRTOS 创建任务(STM32CubeMX / IDE CMSIS-RTOS V2)

一、CubeIDE\CubeMX中创建

任务选项
  • Task Name  :用于设置线程名。
  • Priority  :用于设置线程优先级。
  • Stack Size(Words)  :用于设置线程栈大小(堆栈使用溢出会卡死)。
  • Entry Function  :用于设置线程函数名。
  • Code Generation Option  :代码的生成方式选项,可选择以 形式生成。
  • Parameter  :线程函数参数
  • Allocation  :选择使用动态内存分配的还是静态内存的方式创建线程。
  • Buffer Name  :当使用静态内存创建线程,使用的栈地址名。
  • Control Block Name :当使用静态内存创建线程,创建的线程控制块变量名。
生成代码后:
1、 freertos.c 中 声明了任务控制块(TCB)指针变量:
// 定义一个操作系统线程ID变量,用于运行指示处理线程
osThreadId_t runIndicateHandle;

// 定义运行指示处理线程的属性
const osThreadAttr_t runIndicate_attributes = {
  .name = "runIndicate",      // 线程名称
  .stack_size = 512 * 4,      // 线程堆栈大小,单位是字节
  .priority = (osPriority_t) osPriorityNormal, // 线程优先级,设置为正常优先级
};
2、 freertos.c 中  声明了任务的执行函数:
这里函数没有参数值,因为设置的 Parameter  :线程函数参数为NULL
void StartDefaultTask(void *argument);
3、 main.c 中  任务创建
main.c调用 freertos.c MX_FREERTOS_Init() 函数初始化任务
// 创建并启动一个默认任务线程
// 该线程用于执行初始化和默认操作
// 参数说明:
// - StartDefaultTask: 线程执行的函数入口
// - NULL: 线程函数的参数,这里不需要传递参数
// - &runIndicate_attributes: 指向线程属性结构体的指针,用于配置线程属性
runIndicateHandle = osThreadNew(StartDefaultTask, NULL, &runIndicate_attributes);
对应函数API文档: 线程管理API
4、实现对应的任务函数内容:
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
    /* Infinite loop */
    printf("into StartDefaultTask...");
    for (;;) {
        osDelay(500);
        led(ON);
        osDelay(500);
        led(OFF);
    }
  /* USER CODE END StartDefaultTask */
}
函数代码已经是生成的,只需要在里面实现功能即可。

二、自己使用 CMSIS-RTOS API创建

1、创建自己的任务管理文件
    创建taskManager.c\.h 管自己代码创建的任务。添加头文件。
#include "cmsis_os2.h"
2、声明任务控制块(TCB)指针变量 任务句柄注意创建多个任务时 .priority 设置一样会出现调度问题,优先级不要设置一样。
osThreadId_t myTestTaskHandle_0;                // 定义一个操作系统线程ID变量
const osThreadAttr_t myTestTask0_attributes = { // 定义运行指示处理线程的属性
        .name = "myTestTask0",                       // 线程名称
        .stack_size = 512 * 4,                       // 线程堆栈大小,单位是字节
        .priority = (osPriority_t) osPriorityNormal, // 线程优先级,设置为正常优先级
};
3、 声明、创建任务的执行函数:
void myTestTask0_Func(void *argument) {
    while (1) {
        osDelay(1000);
        printf("myTestTask0_Func running...\n");
    }
}
4、创建初始函数,并在 MX_FREERTOS_Init()调用该初始化:
//任务初始化函数
void taskInit(void);
/**
* 任务初始化函数taskInit
*/
void taskInit(void) {
    myTestTaskHandle_0 = osThreadNew(myTestTask0_Func, NULL, &myTestTask0_attributes);
}
可以使用的任务优先级:
typedef enum {
  osPriorityNone          =  0,         ///< No priority (not initialized).
  osPriorityIdle          =  1,         ///< Reserved for Idle thread.
  osPriorityLow           =  8,         ///< Priority: low
  osPriorityLow1          =  8+1,       ///< Priority: low + 1
  osPriorityLow2          =  8+2,       ///< Priority: low + 2
  osPriorityLow3          =  8+3,       ///< Priority: low + 3
  osPriorityLow4          =  8+4,       ///< Priority: low + 4
  osPriorityLow5          =  8+5,       ///< Priority: low + 5
  osPriorityLow6          =  8+6,       ///< Priority: low + 6
  osPriorityLow7          =  8+7,       ///< Priority: low + 7
  osPriorityBelowNormal   = 16,         ///< Priority: below normal
  osPriorityBelowNormal1  = 16+1,       ///< Priority: below normal + 1
  osPriorityBelowNormal2  = 16+2,       ///< Priority: below normal + 2
  osPriorityBelowNormal3  = 16+3,       ///< Priority: below normal + 3
  osPriorityBelowNormal4  = 16+4,       ///< Priority: below normal + 4
  osPriorityBelowNormal5  = 16+5,       ///< Priority: below normal + 5
  osPriorityBelowNormal6  = 16+6,       ///< Priority: below normal + 6
  osPriorityBelowNormal7  = 16+7,       ///< Priority: below normal + 7
  osPriorityNormal        = 24,         ///< Priority: normal
  osPriorityNormal1       = 24+1,       ///< Priority: normal + 1
  osPriorityNormal2       = 24+2,       ///< Priority: normal + 2
  osPriorityNormal3       = 24+3,       ///< Priority: normal + 3
  osPriorityNormal4       = 24+4,       ///< Priority: normal + 4
  osPriorityNormal5       = 24+5,       ///< Priority: normal + 5
  osPriorityNormal6       = 24+6,       ///< Priority: normal + 6
  osPriorityNormal7       = 24+7,       ///< Priority: normal + 7
  osPriorityAboveNormal   = 32,         ///< Priority: above normal
  osPriorityAboveNormal1  = 32+1,       ///< Priority: above normal + 1
  osPriorityAboveNormal2  = 32+2,       ///< Priority: above normal + 2
  osPriorityAboveNormal3  = 32+3,       ///< Priority: above normal + 3
  osPriorityAboveNormal4  = 32+4,       ///< Priority: above normal + 4
  osPriorityAboveNormal5  = 32+5,       ///< Priority: above normal + 5
  osPriorityAboveNormal6  = 32+6,       ///< Priority: above normal + 6
  osPriorityAboveNormal7  = 32+7,       ///< Priority: above normal + 7
  osPriorityHigh          = 40,         ///< Priority: high
  osPriorityHigh1         = 40+1,       ///< Priority: high + 1
  osPriorityHigh2         = 40+2,       ///< Priority: high + 2
  osPriorityHigh3         = 40+3,       ///< Priority: high + 3
  osPriorityHigh4         = 40+4,       ///< Priority: high + 4
  osPriorityHigh5         = 40+5,       ///< Priority: high + 5
  osPriorityHigh6         = 40+6,       ///< Priority: high + 6
  osPriorityHigh7         = 40+7,       ///< Priority: high + 7
  osPriorityRealtime      = 48,         ///< Priority: realtime
  osPriorityRealtime1     = 48+1,       ///< Priority: realtime + 1
  osPriorityRealtime2     = 48+2,       ///< Priority: realtime + 2
  osPriorityRealtime3     = 48+3,       ///< Priority: realtime + 3
  osPriorityRealtime4     = 48+4,       ///< Priority: realtime + 4
  osPriorityRealtime5     = 48+5,       ///< Priority: realtime + 5
  osPriorityRealtime6     = 48+6,       ///< Priority: realtime + 6
  osPriorityRealtime7     = 48+7,       ///< Priority: realtime + 7
  osPriorityISR           = 56,         ///< Reserved for ISR deferred thread.
  osPriorityError         = -1,         ///< System cannot determine priority or illegal priority.
  osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
} osPriority_t;
MX_FREERTOS_Init()中:
完成:
完整代码:
taskManager.c
//
// Created by Leaf on 2024/11/28.
//

#include "taskManager.h"
#include "cmsis_os2.h"

osThreadId_t myTestTaskHandle_0;                // 定义一个操作系统线程ID变量
const osThreadAttr_t myTestTask0_attributes = { // 定义运行指示处理线程的属性
        .name = "myTestTask0",                       // 线程名称
        .stack_size = 512 * 4,                       // 线程堆栈大小,单位是字节
        .priority = (osPriority_t) osPriorityNormal, // 线程优先级,设置为正常优先级
};

void myTestTask0_Func(void *argument) {
    while (1) {
        osDelay(1000);
        printf("myTestTask0_Func running...\n");
    }
}


/**
* 任务初始化函数taskInit
*/
void taskInit(void) {
    myTestTaskHandle_0 = osThreadNew(myTestTask0_Func, NULL, &myTestTask0_attributes);
}


void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName) {
    // 打印任务名称,及其任务句柄
    printf("任务溢出: %s (Task Handle: %p)\n", pcTaskName, xTask);
}
taskManager.h
//
// Created by Leaf on 2024/11/28.
//

#ifndef STM32F407VET6_FREERTOS_TIMERMANAGER_H
#define STM32F407VET6_FREERTOS_TIMERMANAGER_H

#include "global.h"

// 软件定时器初始化创建
void timerInit(void);

#endif //STM32F407VET6_FREERTOS_TIMERMANAGER_H
注意创建多个任务时 .priority 设置一样会出现调度问题,优先级不要设置一样。
例如:
osThreadId_t myTestTaskHandle_0;                // 定义一个操作系统线程ID变量
const osThreadAttr_t myTestTask0_attributes = { // 定义运行指示处理线程的属性
        .name = "myTestTask0",                       // 线程名称
        .stack_size = 512 * 4,                       // 线程堆栈大小,单位是字节
        .priority = (osPriority_t) osPriorityNormal, // 线程优先级,设置为正常优先级
};

osThreadId_t myTestTaskHandle_1;                // 定义一个操作系统线程ID变量
const osThreadAttr_t myTestTask1_attributes = { // 定义运行指示处理线程的属性
        .name = "myTestTask1",                       // 线程名称
        .stack_size = 512 * 4,                       // 线程堆栈大小,单位是字节
        .priority = (osPriority_t) osPriorityNormal, // 线程优先级,设置为正常优先级
};


void myTestTask0_Func(void *argument) {
    while (1) {
        osDelay(1000);
        printf("myTestTask0_Func running...\n");
    }
}

void myTestTask1_Func(void *argument) {
    while (1) {
        osDelay(1000);
        printf("myTestTask1_Func running...\n");
    }
}

/**
* 任务初始化函数taskInit
*/
void taskInit(void) {
    myTestTaskHandle_0 = osThreadNew(myTestTask0_Func, NULL, &myTestTask0_attributes);
    myTestTaskHandle_1 = osThreadNew(myTestTask1_Func, NULL, &myTestTask1_attributes);
}
输出:
[19:18:17.391]收←◆myTestTask0_Func running...
[19:18:18.385]收←◆myTestTask1_Func running...
[19:18:19.380]收←◆myTestTask0_Func running...
[19:18:20.375]收←◆myTestTask1_Func running...
[19:18:21.369]收←◆myTestTask0_Func running...
[19:18:22.363]收←◆myTestTask1_Func running..
不再是每个线程间隔一秒输出。设置不同优先级解决。
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐