STM32-9 STM32CubeMX的使用方法

article/2024/7/17 3:57:40

一、 说明

本项目是基于FreeRTOS项目的STM32CubeMX开发方式,说明了具体配置与相关参数,以及mdk使用,裸机也可以参考本配置。

二、项目建立步骤

1、新建项目
在这里插入图片描述2、选择芯片型号
在这里插入图片描述
3、配置时钟
RCC 设置,选择 HSE(外部高速时钟) 和LSE(低速时钟)为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)
在这里插入图片描述
4、时钟配置,去Clock Configuration配置RCC时钟为72MHZ,外部低速时钟LSE主要和RTC有关,看情况配置,使用的话需要去使能RTC,使能回去选择时钟为LSE时钟线路 32.768Khz.

在这里插入图片描述
注意RTC的配置,可以选择BCD和16进制
在这里插入图片描述
5、配置调试模式,不配置听说第一次烧录代码厚,jlink不能识别设备了
SYS 设置,选择 Debug 为 Serial Wire,根据情况选择自己的仿真器

6、在 System Core 中选择 SYS ,对 Timebase Source 进行设置,选择 TIM1 作为HAL库的时基(除了 SysTick 外都可以),如果是裸机的话可以选择systick时钟,但目前我要跑系统

在基于STM32 HAL的项目中,一般需要维护的 “时基” 主要有2个:
HAL的时基,SYS Timebase Source
OS的时基(仅在使用OS的情况下才考虑)

而这些 “时基” 该去如何维护,主要分为两种情况考虑:
1、裸机运行:
可以通过 SysTick(滴答定时器)或 (TIMx)定时器 的方式来维护 SYS Timebase Source,也就是HAL库中的 uwTick,这是HAL库中维护的一个全局变量。在裸机运行的情况下,我们一般选择默认的 SysTick(滴答定时器) 方式即可,也就是直接放在 SysTick_Handler() 中断服务函数中来维护。
2、带OS运行:
前面提到的 SYS Timebase Source 是STM32的HAL库中的新增部分,主要用于实现 HAL_Delay() 以及作为各种 timeout 的时钟基准。
在使用了OS(操作系统)之后,OS的运行也需要一个时钟基准(简称“时基”),来对任务和时间等进行管理。而OS的这个 时基 一般也都是通过 SysTick(滴答定时器) 来维护的,这时就需要考虑 “HAL的时基” 和 “OS的时基” 是否要共用 SysTick(滴答定时器) 了。
使用FreeRTOS的时候,不要使用 SysTick(滴答定时器)作为 “HAL的时基”,因为FreeRTOS要用

7、FreeRTOS配置
在 Middleware 中选择 FREERTOS 设置,并选择 CMSIS_V1 接口版本
在这里插入图片描述

两个标准接口区别,CMSIS是一种接口标准,目的是屏蔽软硬件差异以提高软件的兼容性。RTOS v1使得软件能够在不同的实时操作系统下运行(屏蔽不同RTOS提供的API的差别),而RTOS v2则是拓展了RTOS v1,兼容更多的CPU架构和实时操作系统。因此我们在使用时可以根据实际情况选择,如果学习过程中使用STM32F1、F4等单片机时没必要选择RTOS v2,更高的兼容性背后时更加冗余的代码,理解起来比较困难。

在这里插入图片描述
config配置
在这里插入图片描述

mutexes创建互斥量
events 创建事件
FreeRTOS heap usage FreeRTOS堆使用情况
user constants 用户常量
tasks and queues 任务和队列
timers and semaphores 定时器任务和队列
config parameters 配置参数
include parameters 头文件参数
advanced sttings 高级设置

config parameters 配置参数
{kernel settings 内核配置{USE_PREEMPTION: Enabled:RTOS使用抢占式调度器;Disabled:RTOS使用协作式调度器(时间片)。TICK_RATE_HZ: 值设置为1000,即周期就是1ms。RTOS系统节拍中断的频率,单位为HZ。MAX_PRIORITIES: 可使用的最大优先级数量。设置好以后任务就可以使用从0到(MAX_PRIORITIES - 1)的优先级,其中0位最低优先级,(MAX_PRIORITIES - 1)为最高优先级。MINIMAL_STACK_SIZE: 设置空闲任务的最小任务堆栈大小,以字为单位,而不是字节。如该值设置为128 Words,那么真正的堆栈大小就是 128*4 = 512 Byte。MAX_TASK_NAME_LEN: 设置任务名最大长度。IDLE_SHOULD_YIELD: Enabled 空闲任务放弃CPU使用权给其他同优先级的用户任务。USE_MUTEXES: 为1时使用互斥信号量,相关的API函数会被编译。USE_RECURSIVE_MUTEXES: 为1时使用递归互斥信号量,相关的API函数会被编译。USE_COUNTING_SEMAPHORES: 为1时启用计数型信号量, 相关的API函数会被编译。QUEUE_REGISTRY_SIZE: 设置可以注册的队列和信号量的最大数量,在使用内核调试器查看信号量和队列的时候需要设置此宏,而且要先将消息队列和信号量进行注册,只有注册了的队列和信号量才会在内核调试器中看到,如果不使用内核调试器的话次宏设置为0即可。USE_APPLICATION_TASK_TAG: 为1时可以使用vTaskSetApplicationTaskTag函数。ENABLE_BACKWARD_COMPATIBILITY: 为1时可以使V8.0.0之前的FreeRTOS用户代码直接升级到V8.0.0之后,而不需要做任何修改。USE_PORT_OPTIMISED_TASK_SELECTION: FreeRTOS有两种方法来选择下一个要运行的任务,一个是通用的方法,另外一个是特殊的方法,也就是硬件方法,使用MCU自带的硬件指令来实现。STM32有计算前导零指令吗,所以这里强制置1。USE_TICKLESS_IDLE: 置1:使能低功耗tickless模式;置0:保持系统节拍(tick)中断一直运行。假设开启低功耗的话可能会导致下载出现问题,因为程序在睡眠中,可用ISP下载办法解决。USE_TASK_NOTIFICATIONS: 为1时使用任务通知功能,相关的API函数会被编译。开启了此功能,每个任务会多消耗8个字节。RECORD_STACK_HIGH_ADDRESS: 为1时栈开始地址会被保存到每个任务的TCB中(假如栈是向下生长的)。}Memory management settings:内存管理设置{Memory Allocation: Dynamic/Static 支持动态/静态内存申请TOTAL_HEAP_SIZE: 设置堆大小,如果使用了动态内存管理,FreeRTOS在创建 task, queue, mutex, software 		timer or semaphore的时候就会使用heap_x.c(x为1~5)中的内存申请函数来申请内存。这些内存就是从堆ucHeap[configTOTAL_HEAP_SIZE]中申请的。Memory Management scheme: 内存管理策略 heap_4。}TOTAL_HEAP_SIZE的配置可以参考http://www.manongjc.com/detail/59-ethaltlwtgyvjls.htmlHook function related definitions: 钩子功能相关定义{USE_IDLE_HOOK: 置1:使用空闲钩子(Idle Hook类似于回调函数);置0:忽略空闲钩子。USE_TICK_HOOK: 置1:使用时间片钩子(Tick Hook);置0:忽略时间片钩子。USE_MALLOC_FAILED_HOOK: 使用内存申请失败钩子函数。CHECK_FOR_STACK_OVERFLOW: 大于0时启用堆栈溢出检测功能,如果使用此功能用户必须提供一个栈溢出钩子函数,如果使用的话此值可以为1或者2,因为有两种栈溢出检测方法。}Run time and task stats gathering related definitions:运行时和任务统计数据收集相关定义:{GENERATE_RUN_TIME_STATS: 启用运行时间统计功能。USE_TRACE_FACILITY: 启用可视化跟踪调试。USE_STATS_FORMATTING_FUNCTIONS: 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数prvWriteNameToBuffer()、vTaskList()、vTaskGetRunTimeStats()。}Co-routine related definitions:协同例程相关定义:{USE_CO_ROUTINES: 启用协程。MAX_CO_ROUTINE_PRIORITIES: 协程的有效优先级数目。}Software timer definitions:软件定时器{USE_TIMERS: 启用软件定时器。}Interrupt nesting behaviour configuration:中断嵌套行为配置:{	LIBRARY_LOWEST_INTERRUPT_PRIORITY: 中断最低优先级。LIBRARY_LOWEST_INTERRUPT_PRIORITY: 系统可管理的最高中断优先级。}
}

使用软件定时器的话,要在配置里面使能,然后去timers and semaphores 定时器任务和队列创建

Timer Name: 定时器名称
Callback: 回调函数名称
Type: 定时器类型,osTimerPeriodic周期定时器,osTimerOnce单次定时器
Code Generation Option: 代码生成选项
Parameter: 回调函数形参,不用的时候配置为0或NULL即可
Allocation: 分配方式:Dynamic 动态内存创建
Conrol Block Name: 控制块名称

8、project Manager进入项目管理
在这里插入图片描述
分别是项目名称,项目地址,程序结构、工具链文件夹位置、编译IDE(选择MDK版本)
在这里插入图片描述
Stack栈的大小为:0x400(1024Byte),Heap堆的大小为:0x200(512Byte)。
这也是为什么一个基础的工程编译后,RAM的空间也占用了1.6K左右的原因,因为堆栈的空间均分配在RAM中,可在编译的map文件中查看RAM资源占用的情况。

若工程中使用的局部变量较多,定义的数据长度较大时,若不调整栈的空间大小,则会导致程序出现栈溢出,程序运行结果与预期的不符或程序跑飞。这时我们就需要手动的调整栈的大小。

当工程中使用了malloc动态分配内存空间时,这时分配的空间就为堆的空间。所以若默认的堆空间大小不满足工程需求时,就需要手动调整堆空间的大小。
在这里插入图片描述
无论是前后台或者是基于RTOS的系统都可能在调用C库函数时存在线程安全Thread-Safe问题,例如下图对malloc()函数的调用。该类问题出现时,公用资源例如RAM数据出现冲突而应用程序仍能在一段正常运行后才出现问题。对工程师而言,难以调试,也难以查找到根本原因。STM32CubeMX针对EWARM, MDK-ARM和STM32CubeIDE工具链提供了对应的Thread-Safe解决策略,可以直接配置完成。

在这里插入图片描述
将所有使用过的库复制到项目文件夹中
只拷贝需要的库文件
在工具链项目配置文件中添加必要的库文件作为参考

将外围设备初始化生成为每个外围设备的一对.c/.h’文件
重新生成时备份以前生成的文件
重新生成时保留用户代码
不重新生成时删除以前生成的文件

将所有空闲引脚设置为模拟引脚(以优化功耗
启用完全断言

选择模板以生成自定义代码

最后开始创建即可,第十章我们可以看一下在MDK使用的方法


http://www.ngui.cc/article/show-1007530.html

相关文章

Baumer工业相机堡盟相机在BGAPI SDK中如何实现Bitmap的复制克隆(C#)

项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具…

Go map 内存泄露

前言 在Go中, map这个结构使用的频率还是比较高的. 其实在所有的语言中, map使用的频率都是很高的. 之前在使用中, 一直都知道map的内存在元素删除的时候不会回收, 但一直没有仔细的研究为什么. 今天就来好好揣摩揣摩. func main() {m : make(map[int][128]byte)for i : 0; …

Python参数类型定义、私有函数与变量、全局变量

函数的参数类型定义 参数名 冒号 类型函数函数定义在Python3.7之后可用函数不会对参数类型进行验证 def add(a:int, b:int3):print(a b)add(1, 2) add(hello, xiaomu)def test(a:int, b:int3, *args:int, **kwargs):print(a, b, args, kwargs)test(1, 2, 3, 4, namexiaomu)…

用户态--fork函数创建进程

我们一般使用Shell命令行来启动一个程序&#xff0c;其中首先是创建一个子进程。但是由于Shell命令行程序比较复杂&#xff0c;为了便于理解&#xff0c;我们简化了Shell命令行程序&#xff0c;用如下一小段代码来看怎样在用户态创建一个子进程。 #include <stdio.h> #i…

OceanBase CTO杨传辉:持续降低使用门槛,打造开发者友好的分布式数据库

3月25日&#xff0c;首届OceanBase开发者大会在北京举行。大会发布了OceanBase 4.1版本&#xff0c;公布两大友好工具&#xff0c;升级文档易用性&#xff0c;统一企业版和社区版代码分支&#xff0c;全面呈现了OceanBase打造极致的开发者友好数据库的成果。过去13年&#xff0…

【广州华锐互动】电力线路检测VR实训系统有哪些特色?

在电力系统运行中&#xff0c;故障测试是非常重要的一环&#xff0c;旨在检测和排除系统中可能存在的故障&#xff0c;保障电力系统的正常运行。传统的故障测试方法往往需要在实际场景下进行操作&#xff0c;不仅操作难度较大&#xff0c;而且存在安全隐患&#xff0c;同时操作…

详解内核态与用户态

介绍下内核态与用户态 内核态和用户态是操作系统中的两种不同的运行状态&#xff0c;它们的区别如下&#xff1a; 权限不同&#xff1a;内核态是操作系统拥有最高权限的运行状态&#xff0c;可以访问系统的所有资源&#xff0c;而用户态只能访问受限的资源。 系统调用&#x…

网易云音乐API部署Vercel获取接口过程

前提&#xff1a;部署自己的网易云接口主要用途在于在完成前端的仿网易云播放器的时候&#xff0c;根据自己部署的接口可以用于获取数据。大体流程是通过在github上fork别人的API接口项目&#xff0c;然后在Vercel部署即可获得自己的网易云后端数据接口了&#xff0c;不过根据我…

(五)Tomcat源码阅读:Connector组件分析

一、概述 因为Connector组件没有实现接口规范&#xff0c;因此我们直接对该类的方法进行分析即可。 二、源码阅读 阅读思路&#xff0c;我的阅读思路是这样的&#xff0c;大的类无非就是对小类的使用&#xff0c;因此我们想分析整体的一下架构的化我们就先从大类出发找到比较…

【LeetCode】二叉树的前序遍历(递归,迭代,Morris 遍历)

目录 题目要求&#xff1a;给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 方法一&#xff1a;递归 方法二&#xff1a;迭代 思路分析&#xff1a; 复杂度分析 代码展示&#xff1a; 方法三&#xff1a;迭代进阶 思路分析&#xff1a; 代码展示&…