STM32CubeIDE踩坑记录

eclipse实用技巧

简介

STM32CubeIDE是基于eclipse开发的,网上关于eclipse的很多高级使用技巧对于STM32CubeIDE同样适用

Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环境 2001年11月贡献给开源社区,它由非营利软件供应商联盟Eclipse基金会(Eclipse Foundation)管理,后来的发展就是各种版本发布和维护了

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台,它本身只是一个框架,通过插件组件构建开发环境,Eclipse 附带标准的插件集,包括Java开发工具(Java Development Kit,JDK)等

实用的快捷键

网上的太多,我半年使用下来认为这些比较实用

页面跳转

  • Alt+← 前一个编辑的页面
  • Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
  • Ctrl + Q 定位到最后编辑的地方

代码编辑

  • Crtl+Z Ctrl+Y 后退/前进

  • Ctrl+/ 以//注释当前行,再按取消注释

  • Ctrl + D 删除当前行

  • Alt+↓ 当前行和下面一行交互位置(可复选多行)

  • Alt+↑ 当前行和上面一行交互位置(可复选多行)

  • Ctrl + Alt + ↓或↑ 复制当前行到上或下一行

  • Ctrl + Shift + F 自动格式化对齐 (需要先选中一段文本)

  • Ctrl + I 缩进代码的选定部分(或全部)

    Auto-align "=" in assignments 推荐的 columns4eclipse插件:指定符号对齐 不错,STM32CubeIDE 可以直接安装

代码查找

  • Ctr+F 当前源代码文件查找。可以查找并批量替换

    替换指定代码片段的特定字符: shift选中片段后按Ctrl+F,唤出下图右上角替换栏,注意替换查找方式有3种可选配置

    替换指定代码片段的特定字符

  • Ctr+H 全局查找,分文本匹配查找和C/C++查找,前者更好用

  • Ctrl+K 快速查找(需要先选中一段文本)

代码折叠

默认是不开启的,在C/C++ --> Editor -->Folding 页面设置代码折叠功能

图形窗口

工具栏Windows-Prespective-Reset Prespective 可以还原工作界面到默认布局

Ctrl+M 最大化当前的Edit或View (再按则反之)

热键冲突

win10用户若为微软拼音输入法的简体中文模式,那么代码自动对齐的Ctrl + Shift + F会将中文输入法会变为繁体模式(快捷键冲突),再对齐后再Ctrl + Shift + F一次就能切回简体中文

设置代理

关闭拼写检查

WindowPreferencesGeneralEditorsText EditorsSpelling勾掉“Enable spell checking“

AmaterasUML类图插件(仅支持Java没卵用)

STM32CubeIDE实用技巧

简介

STM32CubeIDE是基于eclipse开发的,ST的亲儿子,猛推HAL库的战略级IDE,免费使用,内置的CubeMX,HAL库开发方式,但不支持导出MDK工程模板,带高级调试功能,ST-LINK、dapLink,编译和MDK5一样,巨快,首次编译时间较长,后来继续编译只要代码二进制级别的复用做得好,几乎瞬间编译完成,对比arduino环境每次编译都要从头造一个内核,哎,不比较了

快速上手

修改主题、点亮一个LED灯(通过一个配合CubeMX的实际工程快速上手)

生成hex

C/C++ Build下面的Settings中,找到Tool Settings栏,选择MCU Post build outputs,然后右侧就可以勾选hex

img

代码补全

手动弹出补全

默认C/C++的代码提示只在.和->下触发,输入除前者任意字符时,可以手动Alt+/弹出

手动弹出补全建议

可以在keys设置里修改其他按键触发,我把Alt+/改为了Crtl+Space:

手动弹出补全建议修改按键

自动弹出补全

安装完cubeide后,在D:\ST\STM32CubeIDE_1.4.0\STM32CubeIDE\plugins下本身就有一个org.eclipse.cdt.ui_xxx.jar,我们重命名其为org.eclipse.cdt.ui_xxxbak.jar,然后我们到nopear6博主的git仓库下载:https://github.com/nopear1/cubeIDE_Autocomplete 后解压,将解压的文件夹里的org.eclipse.cdt.ui_xxx.jar复制到D:\ST\STM32CubeIDE_1.4.0\STM32CubeIDE\plugins下,没错,你的这个plugins目录有两个差不多的文件,有bak和没有加bak的,这两个任何一个都不能没有不然你就无法正常看代码了,之后打开ide,自动补全功能就有了

20201115235219

若对制作git仓库的org.eclipse.cdt.ui_xxx.jar文件感兴趣,请阅读

编译报错问题

硬是找不到.h文件?

因为C++C编译器的PATH是分开的,所以两个都要检查下,可能C包含了,而C++没有啊啊啊死活也找不到.h文件?

undefined reference to class "XXX"(不一定是class)

出现这个情况,但文本编辑器可以正常解析class+索引跳转到class定义,一定是工程的C/C++的Source Location没有包含class的源代码的目录,我们添加其所在的根目录或上级目录就行

CDT(不用,请忽略)

安装CDT插件

查看CDT版本号

stm32cubeide 1.70使用cdt 10.2:

查看CDT版本号

修改字体

STM32CubeIDE中文大小不一乱码情况

推荐使用几年了感觉很舒适的一款混合字体:Consolas-with-Yahei

切换编码

Window-Preference-General-Workspace:Text file encoding里设置

20210111205518

C/C++混合编程注意点

内置的CubeMX绑定自动生成的.c文件

STM32CubeIDE内置的CubeMX生成的main.c、main.h只能是C文件,在Keil中可直接将main.c修改为main.cpp,但是,CubeMX不能,就算你修改了一周目为main.cpp和main.hpp,二周目自动生成时还会新建一个main.c和main.h,与你修改过的main.cpp、main.hpp同在

所以想不定期用CubeMX的自动生成功能推进开发的话,最好不要将一切被CubeMX绑定自动生成的.c文件极其头文件中使用C++,而是将C++逻辑写在.cpp文件中,在其同名的.h或.hpp文件里暴露出变量或纯C函数给绑定自动生成的.c文件们调用

在STM32CubeIDE内,右键某一个工程,Convert to C++,同理,可以转换回来:Convert to C,但不会将内置的CubeMX生成的main变成main.cpp和main.hpp

直接在一套同名的.c文件和.h文件中来几句class XXX,百分百报错 “Unknown type name class”这个是常识就不说了

在CubeMX自动生成的代码中,通过包装函数使用C++

STM32CubeIDE 内置的 CubeMX 可以灵活续命工程,随处可见 /* USER CODE BEGIN XXX*/ 和 /* USER CODE END XXX */ 这对好兄弟,区分机器生成的代码和的码农的业务代码,这个工具很有用,但是目前还不能生成C++代码,但是可以在其头文件中包含有包装了C++代码的纯C函数的头文件,来间接使用 C++ 代码

所有.cpp文件对应的头文件被编译器处理时,都会自动加一句#define __cplusplus__cplusplus 宏,是用来识别编译器的,当前代码被编译会作为 C++ 进行编译,利用这个宏可以在.h文件中定义式声明C++class等,但C++编译器在编译时会破坏函数名称,导致在c文件中引用C++.h文件中暴露出的兼容C语法的函数,会报错undefined reference to XXX function,那么就轮到extern "C"就出场了,它能使 C++ 中的函数名称具有C链接(编译器不会破坏名称),以便客户端C代码可以使用仅包含函数声明的C兼容头文件链接到(使用)您的函数,通过这两点配合,就能做到C/C++的混合编程了!

关于__cplusplus还要注意的:

例如你在STM32CubeIDE里创建了 test.h 和 test.cpp 两个空文件,若在test.h里写

1
2
3
#ifdef __cplusplus
/*你的代码*/
#endif

则由于IDE动态显示你的活动预处理和非活动预处理块,/*你的代码*/会亮灰色显示,表示非活动预处理块,预处理器会跳过你这段代码,那么,如何让动态显示的预处理块是活动预处理块呢?很简单,在test.cpp里写 #include "test.h"就行,你再回头看看,/*你的代码*/正常显示了,注意#define __cplusplus是对用户隐藏的操作

剩下的就是手把手教了:

使用 CubeMX 和 C++ 开发 STM32(日文)

更深入请参考:

浅谈C/C++混合编程

C++ 编译器的函数名修饰规则

串口打印浮点数

使用LIS3DH,使用USB VCP输出加速度计三轴数数据,默认配置编译后报错如下,后一句的意思是*添加“ -u _printf_float”作为链接器选项

float不支持

上传代码运行输出如下,两行乱码后都是乱码:

20210114232124

下面的方法OK:

STM32CubeIDE解决float无法被printf格式化(日文)

STM32CubeIDE版本1.0.2或更高版本

如果是Ver.1.0.2或更高版本,则只需进行以下设置即可使用它。

  • 右键单击项目→属性
  • C / C ++构建→设置→MCU设置
  • 选中newlib-nano中的printf使用float(-u _printf_float),下面一行的scanf()是否勾选看你需求

stm32cubeide启用printf_float-1024x800-方法1

低于STM32CubeIDE版本1.0.2的版本

过气了,此处省略~

实测OK

按照STM32CubeIDE版本1.0.2或更高版本的方法勾选后,sprintf用%f警告消失。

实测USB VCP以浮点数打印加速度计三轴数据OK

float_usb_printf()正常

release 和 debug

stm32cubeide build的release中,GCC和G++默认是Os优化,参数 -Os 是在 -O2 的基础上优化大小,实际测试中O1与O2大小差别几乎不计,Os也是Arduino IDE的默认优化等级,难怪之前在arduino ide里用STM32duino的包编译后代码小那么多。。。实测如下,单位是KB:

O0 O1/O2 Os
u8g+u8g绘图(release) 65 39 35 35K是可以正常运行
oled和VCP的
u8g+u8g绘图(debug) 75 48 44
+10 +9 +9
u8g+u8g绘图+LIS3DH、INA226、USB-demo)(release) 98 61 53
u8g+u8g绘图+LIS3DH、INA226、USB-demo)(debug) 106 69 61
+8 +8 +8 release的O1相比debug的O0代码减少45K,妙啊

点击debug后报错XXX Command Failed

在工程选项中将编译器的优化等级设置为Og模式,默认是O0有时会出现无法debug的bug

修改优化等级为og

带bootloader情况的debug

需要在debug设置中修改PC指针为APP程序的开始地址(第二个中断向量表的起始地址),不过建议对APP debug时将起始地址设置为0x08000000调试

Cubemx外设初始化代码生成在单独的源代码文件

下载这个使用stm32cubeide生成的工程,发现外设的相关初始化代码分离在Core文件夹的每个.c.h文件里了(tm32cubeide默认生成在main.c里的),在看这篇文章时找到了设置方法:

每个外设生成独立的 ’.c/.h’ 文件 不勾:所有初始化代码都生成在 main.c 勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中

Cubemx初始化代码生成在对应的外设文件

参考:

STM32CUBEIDE中 Debug 和 Release 的作用/区别/使用场景

GCC 优化选项 -O -O0 -O1 -O2 -O3 -Os 简单介绍

更改".ld"文件默认编辑器

默认打开".ld"文件使用 Linker Script Editor,但注释部分字体颜色在暗黑主题的黑色背景下太暗了眼睛实在难受

找了一圈也没找到设置linker Script Editor注释字体颜色的指南,有个讨论贴最接近的回答是:

目前,没有设置来更改编辑器字符颜色。对我来说,唯一的解决方案是通过右键单击 ld 文件 > 打开方式 > 其他,使用另一个 Eclipse 编辑器或外部编辑器(例如 Windows 上的 NotePad++ 或 Linux 上的 Vim)打开文件

好吧,我们右键随便一个".ld"文件,打开方式里点击,Other...

更改ld文件默认打开方式-1

然后,更改其他编辑器,试了几个,还是C/C++编辑器预览效果最好,勾选后应用到所有".ld"文件,应用即可

更改ld文件默认打开方式-2

预览效果,是不是好多了?

更改ld文件默认打开方式-3

如何更改 CubeIDE 中的内存区域?

更改项目中的内存区域,例如对于只读内存需要从 0x8080000 开始,0x40000 大小,该如何在 CubeIDE 中设置?

Keil 有一个基于 GUI 的界面可以设置内存区域,但CubeIDE 中没有,目前唯一办法是修改 “.ld文件”(GCC的那一套)

例如H750VB的默认FLASH.ld的 MEMORY 划分:

CUBEMX_H7_默认内存区划分

不论FLASH还是RAM划分,只要地址(注意对齐)和划区的大小在硬件支持的范围,那么具体哪个内存区域叫什么,起始其地址划多少,大小多少,可以自定义,比如你可以将RAM_D1 512K划分为 128K+384K两个区,再自定义个划区名字

我参考的安富莱V7教程说到,为了发挥H7最佳性能,鉴于DTCM是 400MHz 的,而其它的 RAM都是 200MHz,教程配套的例子主 RAM空间采用 TCM,而 其它需要大 RAM或者DMA的场合,使用剩余 RAM空间

那么对于STM32CubeIDE默认是使用RAM_D1的,需要将 .data、 .bss、 heap、 stack全部换到DTCMRAM,(CubeIDE默认ld文件中,DTCMRAM起始地址0x20000000就是安富莱在Keil中自定义的IRAM1的起始地址,而RAM_D1起始地址0x24000000是安富莱Keil中的IRAM2)

先换一下 .data 段试试:(对象所在的内存区可以在Buid Analyzer查看)

.data段默认使用RAM_D1 修改为DTCMRAM,再次编译,发现已经移动到里面
CUBEMX_H7_修改.data段使用的内存区_默认使用RAM_D1 CUBEMX_H7_修改.data段使用的内存区_修改为DTCMRAM

但.bss和.user_heap_stack还在RAM_D1,也修改到DCTMRAM:

注意.user_heap_stack除了SECTION里,还有这两个参数要改 将SECTION中.bss和.user_heap_stack从RAM_D1修改为DTCMRAM,再次编译,发现已经移动到里面,至此完成将RAM_D1数据都搬到DCTMRAM
CUBEMX_H7_修改_estack使用的内存区_默认使用RAM_D1 CUBEMX_H7_修改_estack使用的内存区_修改为使用DTCMRAM

对于Flash,如果想自行划分套路差不多

更多".ld"文件使用方法请参考:LAT0816:STM32CubeIDE 实用技巧之 ld 链接文件

更新日期

Date
2021/01/13 C/C++混合编程注意点
2021/01/14 串口打印浮点数
2021/02/05 release 和 debug
2021/08/08 代理、UML、手动补全、CDT
2022/03/29 修复文章++号解析错误
2022/05/13 添加外设独立生成.c或.h文件
2022/08/17 更改".ld"文件默认编辑器 + 如何更改 CubeIDE 中的内存区域?