FreeRTOS项目工程完善指南:STM32F103C8T6系列

news2025/4/18 5:28:39

FreeRTOS项目工程完善指南:STM32系列

本文是FreeRTOS + STM32开发系列教程的一部分。我们将完善之前移植的FreeRTOS工程,添加串口功能并优化配置文件。

更多优质资源,请访问我的GitHub仓库:https://github.com/Despacito0o/FreeRTOS

准备工作

首先,我们需要准备以下文件:

  1. FreeRTOS配置文件(FreeRTOSConfig.h)
  2. 串口初始化文件(usart.h和usart.c)

准备文件

📝 准备工作说明:这些文件是构建完整FreeRTOS工程的基础。FreeRTOSConfig.h用于配置RTOS的核心参数,而串口文件则提供了与PC通信的接口,这对于调试和监控系统运行状态至关重要。

关键文件解析

usart.h文件核心部分

这个文件定义了STM32串口通信所需的宏和函数声明。以下是文件的核心部分:

#ifndef __USART_H
#define	__USART_H

#include "stm32f10x.h"
#include <stdio.h>

/** 
  * 串口宏定义,不同的串口挂载的总线和IO不一样,移植时需要修改这几个宏
  * 1-修改总线时钟的宏,uart1挂载到apb2总线,其他uart挂载到apb1总线
  * 2-修改GPIO的宏
  */
	
// 串口1-USART1
#define  DEBUG_USARTx                   USART1
#define  DEBUG_USART_CLK                RCC_APB2Periph_USART1
#define  DEBUG_USART_APBxClkCmd         RCC_APB2PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200

// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd
    
#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_9
#define  DEBUG_USART_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_10

// 其他串口配置...

void USART_Config(void);
#endif /* __USART_H */

🔍 注意:上述代码只展示了部分内容,完整的串口配置支持USART1~USART5,可以根据自己的需求选择使用。完整代码请访问我的GitHub仓库获取。

📝 串口配置详解

  1. 时钟配置:USART1使用APB2总线,其他USART使用APB1总线,这决定了时钟频率和性能
  2. GPIO配置:定义了TX和RX引脚的具体位置,便于硬件连接
  3. 波特率设置:115200是常用的调试波特率,可以根据需要调整
  4. 中断配置:通过NVIC配置实现串口中断处理,提高通信效率

usart.c文件核心部分

此文件实现了串口初始化和重定向printf函数的功能:

#include "usart.h"

/**
  * @brief  配置嵌套向量中断控制器NVIC
  * @param  无
  * @retval 无
  */
static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

// 更多串口初始化和重定向函数...

🚀 提示:完整代码包含了USART_Config函数以及C标准库printf函数的重定向实现。这使得你可以在FreeRTOS项目中轻松使用printf进行调试输出。

📝 中断配置详解

  1. 优先级分组:使用NVIC_PriorityGroup_2,将4位优先级分为2位抢占优先级和2位子优先级
  2. 中断优先级:抢占优先级1和子优先级1的设置确保了串口中断的及时响应
  3. 中断使能:通过NVIC_Init使能中断,使系统能够响应串口事件

FreeRTOSConfig.h文件核心部分

FreeRTOSConfig.h是FreeRTOS的核心配置文件,通过修改这些宏定义,可以灵活调整RTOS的行为:

/**
 * @file FreeRTOSConfig.h
 * @author Despacito (https://github.com/Despacito0o/FreeRTOS)
 * @brief FreeRTOS配置文件
 */

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
 
#include "stm32f10x.h"  // 设备头文件
 
// 调度器配置
#define configUSE_PREEMPTION                    1  // 启用抢占式调度器
#define configUSE_TICKLESS_IDLE                 1  // 启用低功耗无滴答模式
 
// 时钟配置
#define configCPU_CLOCK_HZ                      (SystemCoreClock)  // CPU 时钟频率
#define configTICK_RATE_HZ                      ( ( TickType_t ) 1000 )  // 系统节拍频率
#define configUSE_16_BIT_TICKS                  0  // 使用 32 位节拍计数器

// 更多配置项...

⚙️ 配置说明:这个FreeRTOSConfig.h文件比之前移植时使用的配置文件更加完整和详细,添加了许多有用的配置项和注释。完整的配置文件可在GitHub仓库中获取,里面包含了60+的配置选项,覆盖了从内存管理到中断优先级的各个方面。

📝 配置详解

  1. 抢占式调度:启用抢占式调度器,允许高优先级任务抢占低优先级任务
  2. 低功耗模式:启用Tickless模式,在系统空闲时降低功耗
  3. 时钟配置:使用系统时钟作为基准,确保时间精度
  4. 节拍配置:1000Hz的节拍频率提供了良好的任务调度粒度

工程完善步骤

1. 准备新工程

复制003动态创建工程模板并重命名为005,这将作为我们新的工程模板:

复制工程

📝 步骤说明:创建新工程模板的目的是为了保持原有工程结构的同时,添加新的功能。这样可以避免破坏原有功能,同时方便进行功能扩展。

2. 替换FreeRTOSConfig.h文件

打开005工程,导航到...\Despacito\005\FreeRTOS目录,更换我们准备好的FreeRTOSConfig.h文件:

替换配置文件

📝 步骤说明:替换配置文件是为了使用更完整的FreeRTOS配置选项。新的配置文件提供了更多的可配置项,使系统更加灵活和可定制。

3. 创建驱动文件夹

导航到...\Desktop\Despacito\005,新建一个Driver文件夹:

创建Driver文件夹

📝 步骤说明:创建Driver文件夹是为了更好地组织代码结构,将硬件驱动相关的代码集中管理。这种组织方式使代码结构更清晰,便于维护和扩展。

4. 添加串口文件

在Driver文件夹中新建一个usart文件夹,用来存放串口初始化文件,并将usart.c和usart.h这两个文件放进该目录下:

添加串口文件

📝 步骤说明:添加串口文件是为了实现与PC的通信功能。这些文件包含了串口初始化和配置的代码,是实现调试和监控功能的基础。

5. 配置工程包含路径

打开工程,点击魔法棒->C/C++(AC6)->Include Paths->…添加如下路径,点击OK->OK:

配置包含路径1

配置包含路径2

📝 步骤说明:配置包含路径是为了让编译器能够找到新添加的头文件。这是确保代码能够正确编译的重要步骤。

6. 添加Driver组和串口文件

添加Driver组以及串口初始化文件,并整理一下点击OK:

添加Driver组

📝 步骤说明:在工程中添加Driver组是为了在keil中更好地组织和管理驱动相关的文件。这使项目结构更清晰,便于开发和维护。

7. 修改main.c

在main.c中添加#include "usart.h"头文件,并调用串口初始化函数USART_Config();

修改main.c

📝 步骤说明:修改main.c是为了初始化串口功能。通过调用USART_Config()函数,系统可以正确配置串口参数,为后续的调试输出做好准备。

8. 处理静态内存分配问题

编译后发现有错误,这是因为我们开启了静态内存分配但没有实现相关函数。有两种解决方法:

  1. configSUPPORT_STATIC_ALLOCATION改为0
  2. 自己实现相关函数

编译错误

我们选择方法2,从004项目中复制静态任务创建函数:

StaticTask_t        IdleTaskTCB;
StackType_t         IdleTaskStack[configMINIMAL_STACK_SIZE];
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                   StackType_t ** ppxIdleTaskStackBuffer,
                                   uint32_t * pulIdleTaskStackSize )
{
    * ppxIdleTaskTCBBuffer = &IdleTaskTCB;
    * ppxIdleTaskStackBuffer = IdleTaskStack;
    * pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

添加静态内存函数

📝 步骤说明:处理静态内存分配是为了解决编译错误。通过实现vApplicationGetIdleTaskMemory函数,我们为FreeRTOS的空闲任务提供了静态内存分配的支持。这种方法比动态分配更可靠,适合在资源受限的嵌入式系统中使用。

9. 优化SysTick中断处理

前面我们在FreeRTOSConfig.h中注释了xPortSysTickHandler的定义,现在我们需要规范化SysTick中断处理:

SysTick处理

  1. 打开port.c,找到xPortSysTickHandler函数
  2. 在stm32f10x_it.c中修改SysTick_Handler函数,加入FreeRTOS调度相关代码:
#include "stm32f10x_it.h"
#include "FreeRTOS.h"
#include "task.h"

// ...

void SysTick_Handler(void)
{
    #if(INCLUDE_xTaskGetSchedulerState==1)
    if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    #endif
    {
        xPortSysTickHandler();
    }
}

port.c文件

📝 步骤说明:优化SysTick中断处理是为了确保FreeRTOS的调度器能够正常工作。通过修改SysTick_Handler函数,我们实现了与FreeRTOS调度器的正确集成,确保任务调度的时间精度和可靠性。

10. 最终编译

完成以上步骤后,我们的工程就可以方便地使用宏配置和printf打印信息了:

编译成功

📝 步骤说明:最终编译成功标志着我们的工程已经完成了所有必要的配置和修改。现在系统具备了完整的调试输出功能,可以通过串口实时监控系统运行状态。

总结

通过本文的步骤,我们成功完善了FreeRTOS工程,添加了:

  1. 完整的FreeRTOSConfig.h配置文件
  2. 串口通信功能
  3. printf调试输出功能
  4. 更规范的中断处理方式

这些改进使得我们的FreeRTOS工程更加健壮和实用,为后续开发复杂应用奠定了良好基础。

📚 获取完整代码和更多示例
完整的工程代码、配置文件以及更多示例请访问我的GitHub仓库:https://github.com/Despacito0o/FreeRTOS

如果这篇文章对你有帮助,请给我的GitHub仓库点个Star!你的支持是我持续更新的动力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2332239.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论坛系统(测试报告)

文章目录 一、项目介绍二、设计测试用例三、自动化测试用例的部分展示用户名或密码错误登录成功编辑自己的帖子成功修改个人信息成功回复帖子信息成功 四、性能测试总结 一、项目介绍 本平台是用Java开发&#xff0c;基于SpringBoot、SpringMVC、MyBatis框架搭建的小型论坛系统…

【汽车产品开发项目管理——端到端的汽车产品诞生流程】

MPU&#xff1a;集成运算器、寄存器和控制器的中央处理器芯片 MCU&#xff1a;微控制单元&#xff0c;将中央处理器CPU、存储器ROM/RAM、计数器、IO接口及多种外设模块集成在单一芯片上的微型计算机系统。 汽车产品开发项目属性&#xff1a;临时性、独特性、渐进明细性、以目标…

从零到有的游戏开发(visual studio 2022 + easyx.h)

引言 本文章适用于C语言初学者掌握基本的游戏开发&#xff0c; 我将用详细的步骤引领大家如何开发属于自己的游戏。 作者温馨提示&#xff1a;不要认为开发游戏很难&#xff0c;一些基本的游戏逻辑其实很简单&#xff0c; 关于游戏的开发环境也不用担心&#xff0c;我会详细…

【C++初阶】--- vector容器功能模拟实现

1.什么是vector&#xff1f; 在 C 里&#xff0c;std::vector 是标准模板库&#xff08;STL&#xff09;提供的一个非常实用的容器类&#xff0c;它可以看作是动态数组 2.成员变量 iterator _start;&#xff1a;指向 vector 中第一个元素的指针。 iterator _finish;&#x…

Elasticsearch 学习规划

Elasticsearch 学习规划 明确学习目标与动机 场景化需求分析 - **S**&#xff1a;掌握Elasticsearch架构体系&#xff0c;熟练使用Elasticsearch 进行数据分析,Elasticsearch结合java 项目落地案例 - **M**&#xff1a;搜索和Elasticsearch相关GitHub项目 - **A**&#xff1a;每…

LVM 扩容详解

目录 一、LVM扩容 1. 查看磁盘分区情况&#xff1a; 2. 查看pv、vg、lv 情况 3. 将新硬盘分区初始化 4. 将初始化后的分区添加到VG中 5. 查看逻辑卷的设备路径 6. VG分配给lv 二、扩展文件系统 1.确认文件系统类型 三、检验 一、LVM扩容 1. 查看磁盘分区情况&#xff1a; …

STM32 低功耗模式下 RTC唤醒 和 PA0唤醒 的配合使用

STM32 低功耗模式不同唤醒源的配合使用 by 矜辰所致前言 关于 STM32 如何实现低功耗模式&#xff0c;我之前写过一篇文章&#xff1a; STM32 使用 STM32CubeMX HAL库实现低功耗模式 各种休眠模式如何实现文中已经讲得很清楚了&#xff0c;但是作为教学文章&#xff0c;文…

QML 弹窗控件:Popup的基本用法与样式

目录 引言相关阅读Popup基本属性工程结构示例实现Main.qml - 主界面SimplePopup.qml - 简单弹窗ModalPopup.qml - 模态弹窗CustomPopup.qml - 自定义样式弹窗AnimatedPopup.qml - 带动画的弹窗 总结工程下载 引言 在现代图形用户界面(GUI)开发中&#xff0c;弹窗(Popup)是一种…

NSS#Round30 Web

小桃的PHP挑战 <?php include jeer.php; highlight_file(__FILE__); error_reporting(0); $A 0; $B 0; $C 0;//第一关 if (isset($_GET[one])){$str $_GET[str] ?? 0;$add substr($str, 0, 1); $add;if (strlen($add) > 1 ) {$A 1;} else {echo $one; } } else…

Multisim 仿真 DC Sweep 双源嵌套扫描嵌套

Multisim仿真工具箱里头有DC Sweep分析方法&#xff0c;分析中可以对两个源参数扫描分析 类似于编程的循环嵌套&#xff1a; for( Source 2 : start value; Increment; Source 2 : stop value;) {for( Source 1 : start value; Increment; Source 2 : stop value;){... //…

Python | 绘制黑底的水平空间分布图

写在前面 记录一下之前为了做PPT汇报画的一张图&#xff0c;虽然最后也没怎么用上。为了方面以后再需要&#xff0c;这里把代码和数据整理放到GitHub上。有兴趣的也可以玩玩 需要的数据 风场数据可以从ERA5的官网下载 https://cds.climate.copernicus.eu/datasets/reanalys…

京东与喜茶关系破裂:切断所有合作 禁止进入办公场所

快科技4月10日消息&#xff0c;据报道&#xff0c;京东集团近日被曝出内部下发全员禁令&#xff0c;全面封杀喜茶产品进入办公区域。 据知情人士透露&#xff0c;京东人力行政部门发布的通知明确规定&#xff1a;全国各职场禁止与喜茶品牌开展任何形式的合作&#xff1b;员工不…

stm32开发(一)之创建工程与第一个程序

ps&#xff1a; 开发模式 1.基于库函数&#xff08;标准库&#xff09; 推荐 2.基于HAL库 图形化 3.基于寄存器 最直接 一、创建工程 1、打开keil5 new Project->路径->命名->保存 2、选择型号&#xff1a;stm32f103c8 初始创建工程我们不使用快捷项目建设 …

【电商】基于LangChain框架将多模态大模型连接数据库实现精准识别

1. LangChain框架 LangChain是一个用于构建基于大语言模型的应用框架&#xff0c;通过模块化设计简化了LLM与外部工具&#xff0c;数据源和复杂逻辑的集成。 连接能力 将多个LLM调用&#xff0c;工具调用或者数据处理步骤串联成工作流 数据感知 外部数据集成 支持连接数据…

鸿蒙HarmonyOS埋点SDK,ClkLog适配鸿蒙埋点分析

ClkLog埋点分析系统&#xff0c;是一种全新的、开源的洞察方案&#xff0c;它能够帮助您捕捉每一个关键数据点&#xff0c;确保您的决策基于最准确的用户行为分析。技术人员可快速搭建私有的分析系统。 ClkLog鸿蒙埋点SDK通过手动埋点的方式实现HarmonyOS 原生应用的前端数据采…

湘西的未来交响曲

故事摘要 在中国湖南湘西的未来&#xff0c;苗族文化与高科技完美融合&#xff0c;构建出一个既传统又现代的世界。晨曦中的沱江&#xff0c;悬浮的吊脚楼面带着品位独特的织锦纹样&#xff0c;展示了令人惊叹的未来建筑美学。独特的工坊技术使得每件首饰都能感知佩戴者的情感&…

STM32_HAL库提高中断执行效率

目录 中断流程分析我的解决办法优缺点 大家都在说STM32 HAL 库中断效率低下。具体哪里不行&#xff1f;如何优化&#xff1f; 我手里的项目要用到多个定时器TIM6、TIM7、TIM9、TIM10、TIM11、TIM12、TIM13&#xff0c;在处理这些定时器中断的时候&#xff0c;也发现了这个问题。…

软件系统安全设计方案,信息化安全建设方案(Word原件)

1.1 总体设计 1.1.1 设计原则 1.2 物理层安全 1.2.1 机房建设安全 1.2.2 电气安全特性 1.2.3 设备安全 1.2.4 介质安全措施 1.3 网络层安全 1.3.1 网络结构安全 1.3.2 划分子网络 1.3.3 异常流量管理 1.3.4 网络安全审计 1.3.5 网络访问控制 1.3.6 完…

什么是微前端?有什么好处?有哪一些方案?

微前端&#xff08;Micro Frontends&#xff09; 微前端是一种架构理念&#xff0c;借鉴了微服务的思想&#xff0c;将一个大型的前端应用拆分为多个独立、自治的子应用&#xff0c;每个子应用可以由不同团队、使用不同技术栈独立开发和部署&#xff0c;最终聚合为一个整体产品…

Web前端之Vue+Element实现表格动态不同列合并多行、localeCompare、forEach、table、push、sort、Map

MENU 效果图公共数据数据未排序时&#xff08;需要合并的行数据未处于相邻位置&#xff09;固定合并行&#xff08;写死&#xff09;动态合并行方法&#xff08;函数&#xff09;执行 效果图 公共数据 Html <el-table :data"tableData" :span-method"chang…