系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、开发环境准备
- 1. 硬件选择
- 2. 软件工具
- (1) STM32CubeMX
- (2) Keil MDK-ARM
- (3) ST-Link驱动
- 二、使用STM32CubeMX配置FreeRTOS
- 1. 新建项目
- 2. 配置时钟和外设
- (1) 配置RCC(时钟)
- (2) 配置SYS(系统)
- (3) 配置GPIO(LED引脚)
- 3. 开启FreeRTOS组件
- 三、FreeRTOS第一个任务创建
- 1. 任务的基本概念
- 2. 配置任务参数
- 3. 生成代码
- 四、编写LED闪烁任务代码
- 1. 打开Keil MDK项目
- 2. 编写任务函数
- 3. 任务函数编写规范
- 五、下载与运行
- 1. 编译项目
- 2. 下载到开发板
- 3. 观察运行效果
- 六、代码解析
- 1. main.c中的FreeRTOS初始化流程
- 2. 任务创建与调度分析
- 七、实践任务
- 八、总结
前言
上一篇文章中,我们了解了FreeRTOS的基本概念和优势,相信很多朋友已经跃跃欲试,想亲手搭建FreeRTOS环境并运行第一个程序了。今天,我们就来手把手教大家如何从0开始搭建FreeRTOS开发环境,并创建第一个任务——让开发板上的LED灯闪烁起来!
一、开发环境准备
1. 硬件选择
为了方便学习和演示,我们推荐使用以下硬件:
- 主控芯片:STM32F103C8T6(一款非常经典的Cortex-M3内核芯片,资源适中,价格便宜)
- 开发板:最小系统板(核心板,带USB转串口功能)
- 辅助工具:USB数据线(用于供电、下载和串口通信)
当然,如果你有其他STM32系列的开发板(如F4系列、F7系列),或者ESP32、NXP等其他品牌的开发板,也完全可以使用,操作步骤基本类似。
2. 软件工具
我们需要安装以下软件:
(1) STM32CubeMX
STM32CubeMX是ST公司官方推出的一款图形化配置工具,可以帮助我们快速配置STM32芯片的各种外设和中间件,包括FreeRTOS。
- 下载地址:ST官网STM32CubeMX下载页
- 安装步骤:下载后双击安装,按照提示完成即可。需要注意的是,安装过程中会要求安装Java运行环境(JRE),如果你的电脑上还没有安装JRE,需要先安装JRE。
(2) Keil MDK-ARM
Keil MDK是一款专业的ARM嵌入式开发工具,用于编写、编译和下载代码。
- 下载地址:Keil官网下载页
- 安装步骤:下载后双击安装,按照提示完成即可。需要注意的是,Keil MDK需要注册(可以申请免费的4KB代码限制版本,足够我们学习使用)。
(3) ST-Link驱动
用于将代码下载到STM32开发板上。
- 下载地址:ST官网ST-Link驱动下载页
- 安装步骤:下载后解压,运行安装程序即可。
二、使用STM32CubeMX配置FreeRTOS
1. 新建项目
- 打开STM32CubeMX软件,点击"Access to MCU Selector"(访问MCU选择器)。
- 在搜索框中输入"STM32F103C8T6",然后在搜索结果中选择该芯片,点击"Start Project"(开始项目)。
2. 配置时钟和外设
(1) 配置RCC(时钟)
- 点击左侧"System Core"(系统核心)→ “RCC”。
- 在右侧"High Speed Clock (HSE)“(高速时钟)选项中,选择"Crystal/Ceramic Resonator”(晶体/陶瓷谐振器)。
(2) 配置SYS(系统)
- 点击左侧"System Core"(系统核心)→ “SYS”。
- 在右侧"Debug"(调试)选项中,选择"Serial Wire"(串口线),这样我们才能使用ST-Link进行调试和下载。
(3) 配置GPIO(LED引脚)
- 点击左侧"System Core"(系统核心)→ “GPIO”。
- 在右侧芯片引脚图中,找到并点击"PC13"引脚(STM32F103C8T6最小系统板上的LED通常连接在PC13引脚上)。
- 在弹出的配置窗口中,选择"GPIO_Output"(GPIO输出)模式。
- 在下方"User Label"(用户标签)中输入"LED",方便后续代码中引用。
3. 开启FreeRTOS组件
点击左侧"Middleware"(中间件)→ “FreeRTOS”。
在右侧"Mode"(模式)选项中,选择"CMSIS_V1"(如果你的CubeMX版本较新,也可以选择CMSIS_V2,两者使用方法类似)。
点击"Tasks and Queues"(任务和队列)标签页,然后点击"Add"(添加)按钮,添加一个新任务。
三、FreeRTOS第一个任务创建
1. 任务的基本概念
在FreeRTOS中,任务是操作系统调度的基本单位,每个任务都有自己的堆栈和任务控制块(TCB)。简单来说,一个任务就是一个无限循环的函数,例如:
voidTaskFunction(void*pvParameters){while(1){// 任务代码}}2. 配置任务参数
在STM32CubeMX中,我们可以通过图形化界面来配置任务的参数:
- Task Name(任务名称):输入"Task_LED"。
- Priority(优先级):选择"osPriorityLow"(在cube中配置每个任务优先级时还是只能选择7种优先级,由低到高分别是:osPriorityIdle(空闲任务),osPriorityLow,osPriorityBelowNormal,osPriorityNormal,osPriorityAboveNormal,osPriorityHigh,osPriorityRealtime 。)。
- Stack Size(堆栈大小):输入"128"(单位为字,即128×4=512字节,足够我们的LED闪烁任务使用)。
- Entry Function(入口函数):自动生成为"StartTask_LED",我们可以在这个函数中编写任务代码。
- Code Generation Option(代码生成选项):保持默认即可。
配置完成后,点击"OK"按钮保存。
3. 生成代码
点击右上角"Project Manager"(项目管理器)标签页。
在"Project Name"(项目名称)中输入"FreeRTOS_LED"。
在"Project Location"(项目位置)中选择一个合适的文件夹。
在"Toolchain/IDE"(工具链/IDE)中选择"MDK-ARM"。
点击"Code Generator"(代码生成器)标签页,勾选"Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral"(为每个外设生成一对.c/.h文件)。
最后,点击右上角"GENERATE CODE"(生成代码)按钮,生成Keil MDK项目。
四、编写LED闪烁任务代码
1. 打开Keil MDK项目
代码生成完成后,点击"Open Project"(打开项目)按钮,或者在项目文件夹中找到"FreeRTOS_LED.uvprojx"文件,双击打开。
2. 编写任务函数
在Keil MDK中,展开"Application/User/core"文件夹,找到并双击打开"freertos.c"文件。在该文件中,我们可以找到自动生成的任务入口函数"StartTask_LED":
/* USER CODE BEGIN Header_StartTask_LED *//** * @brief Function implementing the Task_LED thread. * @param argument: Not used * @retval None *//* USER CODE END Header_StartTask_LED */voidStartTask_LED(voidconst*argument){/* USER CODE BEGIN StartTask_LED *//* Infinite loop */for(;;){HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);// 翻转LED引脚电平osDelay(1000);// 延时1秒}/* USER CODE END StartTask_LED */}我们需要在"/* USER CODE BEGIN StartTask_LED/“和”/USER CODE END StartTask_LED */"之间编写任务代码。上面的代码已经实现了LED闪烁功能:
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin):翻转LED引脚的电平状态osDelay(1000):FreeRTOS的延时函数,延时1000个时钟节拍(默认1ms/节拍,即延时1秒)
3. 任务函数编写规范
在编写FreeRTOS任务函数时,需要注意以下几点:
- 任务函数应该是一个无限循环,不能返回
- 任务函数内部应该有适当的延时,让其他任务有机会执行
- 任务函数的参数是一个void指针,可以用来传递参数
- 任务函数的命名应该清晰,表明任务的功能
五、下载与运行
1. 编译项目
- 在Keil MDK中,点击左上角"Rebuild"(重新编译)按钮,或者按下快捷键"F7"。
- 等待编译完成,如果没有错误,下方"Build Output"(编译输出)窗口会显示"0 Error(s), 0 Warning(s)."。
2. 下载到开发板
- 将ST-Link调试器连接到开发板上,然后将ST-Link的USB端连接到电脑。
- 在Keil MDK中,点击左上角"Download"(下载)按钮,或者按下快捷键"F8"。
- 等待下载完成,下方"Build Output"(编译输出)窗口会显示"Download completed successfully."。
3. 观察运行效果
- 下载完成后,开发板上的LED灯应该开始闪烁,大约每隔1秒闪烁一次(亮1秒,灭1秒)。
- 如果LED没有闪烁,可以检查一下接线是否正确,或者重新检查配置和代码。
rtos的led
六、代码解析
1. main.c中的FreeRTOS初始化流程
让我们来看一下main.c文件中的代码,了解FreeRTOS的初始化流程:
intmain(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Call init function for freertos objects (in freertos.c) */MX_FreeRTOS_Init();/* Start scheduler */osKernelStart();/* We should never get here as control is now taken by the scheduler *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}主要流程如下:
HAL_Init():初始化HAL库SystemClock_Config():配置系统时钟MX_GPIO_Init():初始化GPIO外设(包括LED引脚)MX_FreeRTOS_Init():初始化FreeRTOS对象(包括创建我们的LED任务)osKernelStart():启动FreeRTOS调度器
2. 任务创建与调度分析
在freertos.c文件中,我们可以找到MX_FreeRTOS_Init()函数,其中包含了任务创建的代码:
/* Init FreeRTOS */voidMX_FreeRTOS_Init(void){/* Create the thread(s) *//* definition and creation of Task_LED */osThreadDef(Task_LED,StartTask_LED,osPriorityNormal,0,128);Task_LEDHandle=osThreadCreate(osThread(Task_LED),NULL);}这里使用了CMSIS-RTOS的API函数来创建任务:
osThreadDef():定义一个任务,参数包括任务名称、任务入口函数、优先级、实例数和堆栈大小osThreadCreate():创建任务,并返回任务句柄
任务创建完成后,调用osKernelStart()启动调度器,FreeRTOS就会开始调度任务执行。我们的LED任务会每隔1秒翻转一次LED引脚的电平,实现闪烁效果。
七、实践任务
为了加深大家对FreeRTOS任务优先级的理解,我们可以做一个小实验:
- 在STM32CubeMX中,再创建一个任务
Task_LED2,优先级设置为2(比Task_LED的优先级1高)。 - 在
Task_LED2的任务函数中,同样实现LED闪烁功能,但延时时间改为500毫秒。 - 生成代码并下载到开发板,观察LED的闪烁频率有什么变化。
思考:为什么会出现这样的变化?这说明了FreeRTOS的什么调度特性?
八、总结
通过本文的学习,我们成功完成了以下内容:
- 搭建了FreeRTOS的开发环境(STM32CubeMX + Keil MDK)
- 配置了STM32F103C8T6的时钟、外设和FreeRTOS组件
- 创建了第一个FreeRTOS任务,实现了LED闪烁功能
- 下载并运行了程序,观察到了预期的效果
- 解析了FreeRTOS的初始化流程和任务调度机制
下一篇文章,我们将深入学习FreeRTOS的任务管理,包括任务的状态转换、优先级设置和调度策略等内容。敬请期待!
互动时间:你在搭建FreeRTOS环境时遇到过哪些问题?欢迎在评论区留言分享,我们一起讨论解决!如果这篇文章对你有帮助,记得点赞、转发哦!