news 2026/7/5 13:47:46

STM32之freeRTOS的使用基本方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32之freeRTOS的使用基本方法

freeRTOS打开方法

middleware and software, interface:CMSIS V2. 打开以后修改HAL时基,避免HAL与freeRTOS抢sysTick,随便选一个不用的就可以。

可以看到TIM10已经变成不可用状态,配置都是灰色的

TASK建立

打开Tasks and Queues,点击add

参数含义你该怎么填
Task Name任务名字自己起名,比如motor_xm_ololedTaskadcTask。建议用英文、数字、下划线
Priority任务优先级决定谁先运行。优先级高的任务会抢占优先级低的任务
Stack Size (Words)任务栈大小,单位是wordSTM32 是 32 位 MCU,1 word = 4 字节,所以 128 words = 512 字节
Entry Function任务入口函数名这个任务真正执行的函数,比如StartTask02
Code Generation Option代码生成方式一般保持Default就行
Parameter传给任务函数的参数不需要传参就填NULL
Allocation任务内存分配方式Dynamic动态分配,简单方便;Static静态分配,更可控
Buffer Name静态分配时用的栈缓冲区名只有Allocation = Static时才需要
Control Block Name静态分配时用的任务控制块名只有Allocation = Static时才需要

在Core/Src/目录下的freertos.c文件里面,可以看到我在cubeMX里面添加的几个任务

条件触发TASK的编写

在当前项目中,我计划是一些按键对应一个task,另一些按键对应另一个task。也就是需要flag来标记,单个任务中的不同程序。其中一个task,是通过按键触发电机的手动移动,思路是按键按下对应移动方向的按键以后,在中断回调函数里面修改标志位,任务监测到标志位变化后执行task内相对应的代码。目前的移动方向有四个,在freertos.c这里添加代码

/* USER CODE END Header_move_manualT */ void move_manualT(void *argument) { /* USER CODE BEGIN move_manualT */ uint32_t flags; /* Infinite loop */ for(;;) { flags = osThreadFlagsWait( FLAG_XM | FLAG_XP | FLAG_YM | FLAG_YP, osFlagsWaitAny, osWaitForever ); if (flags & FLAG_XM) { motor_move_XM_OL(1000); } if (flags & FLAG_XP) { motor_move_XP_OL(1000); } if (flags & FLAG_YM) { motor_move_YM_OL(1000); } if (flags & FLAG_YP) { motor_move_YP_OL(1000); } } /* USER CODE END move_manualT */ }

然后在main.c里面写按键的中断回调函数

/* USER CODE BEGIN 4 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static uint32_t last_tick = 0; uint32_t now = HAL_GetTick(); if (now - last_tick < 20) return; last_tick = now; if (GPIO_Pin == GPIO_PIN_15) { //X- osThreadFlagsSet(move_manualHandle, FLAG_XM); } else if (GPIO_Pin == GPIO_PIN_10) { //X+ osThreadFlagsSet(move_manualHandle, FLAG_XP); } else if (GPIO_Pin == GPIO_PIN_11) { //Y- osThreadFlagsSet(move_manualHandle, FLAG_YM); } else if (GPIO_Pin == GPIO_PIN_12) { //Y+ osThreadFlagsSet(move_manualHandle, FLAG_YP); } else if (GPIO_Pin == GPIO_PIN_13) { //Z+ } else if (GPIO_Pin == GPIO_PIN_13) { //Z- } };

另外标志位是两个c文件都要读取的,我们另开一个flags.h文件,并在main.c和freertos.c里面都include它

#ifndef _FLAGS_H_ #define _FLAGS_H_ #define FLAG_XM (1U << 0) #define FLAG_XP (1U << 1) #define FLAG_YM (1U << 2) #define FLAG_YP (1U << 3) #endif

main.c里面的osThreadFlagsSet函数中的的第一个参数 是freertos.c里面task的句柄,同样需要另外建立一个user_freertos.h文件,来重新声明一下这些句柄,加上extern。

#ifndef __APP_FREERTOS_H #define __APP_FREERTOS_H #include "cmsis_os.h" extern osThreadId_t oled_dispHandle; extern osThreadId_t move_manualHandle; extern osThreadId_t move_autoHandle; extern osThreadId_t ESPtransferHandle; extern osThreadId_t USBtransferHandle; #endif

互斥任务的设置

在当前的应用场景中,手动控制电机移动的任务和自动控制电机按程序移动的任务是分开的。另外USB和ESP8266读写SPI flash的程序也是分开的。因此需要对这几个task做互斥。首先在cubeMX里面的freertos-mutexes 点击add,参数先选dynamic。

生成代码以后进入freertos.c文件可以看到生成了一个新的句柄,

/* Definitions for motor_mutex */ osMutexId_t motor_mutexHandle; const osMutexAttr_t motor_mutex_attributes = { .name = "motor_mutex" };

函数结构如下

void StartTask1(void *argument) { for (;;) { osThreadFlagsWait(FLAG_TASK1, osFlagsWaitAny, osWaitForever); osMutexAcquire(allMotorMutexHandle, osWaitForever); Task1_Function(); osMutexRelease(allMotorMutexHandle); } }

可以看到增加了两个函数,这俩函数就是互斥锁,第一个函数是用来上锁,第二个函数用来解锁。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 13:46:34

在macOS上完美使用Xbox控制器:360Controller开源驱动终极指南

在macOS上完美使用Xbox控制器&#xff1a;360Controller开源驱动终极指南 【免费下载链接】360Controller TattieBogle Xbox 360 Driver (with improvements) 项目地址: https://gitcode.com/gh_mirrors/36/360Controller 你是否曾经在Mac上连接Xbox控制器&#xff0c;却…

作者头像 李华
网站建设 2026/7/5 13:44:39

八、Kafka 原理与常见应用场景

一、什么是 Kafka Apache Kafka 是一个开源的分布式流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;2011 年开源。它不仅仅是一个消息队列&#xff0c;更是一个集消息发布/订阅、持久化存储、实时流处理于一体的分布式系统。 简单来说&#xff0c;Kafka 就像是分布式…

作者头像 李华
网站建设 2026/7/5 13:40:18

Obsidian 同步到底怎么选?2026 年主流方案实测对比

一、一个被忽略的现实&#xff1a;每台设备的“角色”不一样很多 Obsidian 用户在配置多端同步时&#xff0c;会默认把所有设备当成“平等设备”来对待。但真实使用场景往往是这样的&#xff1a;电脑负责主力写作、整理目录、管理附件&#xff1b;手机负责阅读、查找笔记、偶尔…

作者头像 李华
网站建设 2026/7/5 13:40:14

linux文件权限

文件的类型- 普通文件 d 目录l 链接文件b 块设备文件--------一般为硬件设备等c 字符设备文件------一般为硬件设备等p 管道文件s 套接字文件查看目录的属性时加参数-d-----> ll -d权限针对的对象owner文件所有者&#xff0c;ugroup所属组&#xff0c…

作者头像 李华