news 2026/2/7 0:21:44

FreeRTOS环境搭建与第一个任务创建

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FreeRTOS环境搭建与第一个任务创建

系列文章目录


文章目录

  • 系列文章目录
    • 前言
    • 一、开发环境准备
      • 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. 新建项目

  1. 打开STM32CubeMX软件,点击"Access to MCU Selector"(访问MCU选择器)。
  2. 在搜索框中输入"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任务函数时,需要注意以下几点:

  1. 任务函数应该是一个无限循环,不能返回
  2. 任务函数内部应该有适当的延时,让其他任务有机会执行
  3. 任务函数的参数是一个void指针,可以用来传递参数
  4. 任务函数的命名应该清晰,表明任务的功能

五、下载与运行

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 */}

主要流程如下:

  1. HAL_Init():初始化HAL库
  2. SystemClock_Config():配置系统时钟
  3. MX_GPIO_Init():初始化GPIO外设(包括LED引脚)
  4. MX_FreeRTOS_Init():初始化FreeRTOS对象(包括创建我们的LED任务)
  5. 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任务优先级的理解,我们可以做一个小实验:

  1. 在STM32CubeMX中,再创建一个任务Task_LED2,优先级设置为2(比Task_LED的优先级1高)。
  2. Task_LED2的任务函数中,同样实现LED闪烁功能,但延时时间改为500毫秒。
  3. 生成代码并下载到开发板,观察LED的闪烁频率有什么变化。

思考:为什么会出现这样的变化?这说明了FreeRTOS的什么调度特性?

八、总结

通过本文的学习,我们成功完成了以下内容:

  1. 搭建了FreeRTOS的开发环境(STM32CubeMX + Keil MDK)
  2. 配置了STM32F103C8T6的时钟、外设和FreeRTOS组件
  3. 创建了第一个FreeRTOS任务,实现了LED闪烁功能
  4. 下载并运行了程序,观察到了预期的效果
  5. 解析了FreeRTOS的初始化流程和任务调度机制

下一篇文章,我们将深入学习FreeRTOS的任务管理,包括任务的状态转换、优先级设置和调度策略等内容。敬请期待!


互动时间:你在搭建FreeRTOS环境时遇到过哪些问题?欢迎在评论区留言分享,我们一起讨论解决!如果这篇文章对你有帮助,记得点赞、转发哦!

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

32、虚拟专用网络协议与证书颁发机构的配置管理

虚拟专用网络协议与证书颁发机构的配置管理 1. 虚拟专用网络协议常见问题解答 虚拟专用网络(VPN)协议在网络连接和安全访问方面发挥着重要作用。以下是一些常见问题及解答: |问题编号|问题描述|答案|解释| | ---- | ---- | ---- | ---- | |1|VPN 的作用有哪些?|A, B, …

作者头像 李华
网站建设 2026/2/4 9:33:59

44、网络安全事件响应与攻击类型解析

网络安全事件响应与攻击类型解析 在当今数字化时代,网络安全至关重要。当网络出现漏洞被利用时,及时且恰当的响应是保障网络安全的关键。以下将详细介绍网络安全事件的应对措施以及常见的攻击类型。 安全事件的响应步骤 发现安全事件 当发现网络存在被利用的漏洞时,需要…

作者头像 李华
网站建设 2026/2/3 15:59:31

最近做AI Agent的十条经验总结

随着AI技术的不断发展,AI Agent(智能代理)已经开始在各行各业中发挥重要作用。无论是客服、医疗、教育,还是创意写作、数据分析等领域,AI Agent都在帮助人们提高工作效率、节省时间、解决复杂问题。然而,开…

作者头像 李华
网站建设 2026/2/7 13:51:23

《灵足之脑:大模型驱动双足机器人全栈技术实战系列》第 0 篇:开启具身智能的“奥德赛” —— 前言与通识

第 0 篇:开启具身智能的“奥德赛” —— 前言与通识 1. 写作背景:当“大脑”遇见“身体” 在人工智能的长河中,我们经历了从逻辑符号化到大规模统计学习的跨越。2023 年起,以 GPT 为代表的大语言模型(LLM)赋…

作者头像 李华
网站建设 2026/2/5 4:04:53

数据结构——链表自实现

❀保持低旋律节奏->个人主页 专栏链接&#xff1a;《C学习》、《Linux学习》 文章目录头文件实现测试文件实现易错汇总头文件实现 #pragma once #include<stdio.h> #include<stdlib.h> // 补充bool类型头文件&#xff08;C语言需手动定义或包含stdbool.h&#…

作者头像 李华
网站建设 2026/2/6 9:33:03

告别Java开发碎片化!全流程智能平台让需求直转可执行项目

在Java企业级开发场景中&#xff0c;研发人员普遍面临工作流程割裂的核心痛点&#xff1a;从需求分析、接口定义、数据建模到代码实现&#xff0c;需在多款工具与不同开发上下文间频繁切换&#xff0c;不仅直接限制研发效率&#xff0c;还易引发设计不一致与细节遗漏问题。针对…

作者头像 李华