vscode开发STM32的一些问题解决

本文针对STM32开发遇到的问题提供了解决方案,包括如何在VSCode中配置Makefile插件以获得自动提示,解决printf函数无法打印浮点数的問題,以及调整编译输出以减少终端卡顿。此外,还介绍了使用assert进行代码初始化错误检测的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此文章写给我即将到来的Robocon学弟

目录

前言

一、vscode自动提示

二、printf打印问题

二、编译输出

三、断言assert


 

一、vscode自动提示

如果用vscode开发stm32,使用Makefile插件就会自动提示。Makefile插件会根据当前vscode打开的文件夹下的makefile文件内容工作。如果还是出现红色波浪线,出现像找不到头文件等问题,一般重启试vscode一下,或者卸载重装插件可以解决。如果自己添加的文件找不到,应该是makefile文件写错了。注意:makefile可能和cmake等插件冲突。

二、printf打印问题

如果想用串口(usart)打印信息,C语言的printf一定是大家使用最熟悉的函数。那么怎么在STM32实现呢?如下代码即可实现:

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

int UART_Print(char *fmt, ...)
{
    int ret;
    va_list ap;
    va_start(ap, fmt);
    ret = vsprintf(UART_TxBuf, fmt, ap);
    va_end(ap);
    if (ret > 0)
    {
        HAL_UART_Transmit(&PRINT_UART, (uint8_t *)UART_TxBuf, ret, WAIT_DELAY);
    }
    return ret;
}

但是实际应用的时候发现无法打印浮点数。这个时候更改一下makefile文件的编译选项。可以在140多行找到libraries添加-u _printf_float -u _scanf_float。

# libraries
LIBS = -lc -lm -lnosys 
LIBDIR = 
LDFLAGS = $(MCU) -specs=nano.specs -u _printf_float -u _scanf_float -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections

二、编译输出

编译的时候可以看见编译速度很快,但是有些电脑在编译的时候发现终端输出太多信息,看起来很卡顿怎么办?在makefile的150多行的编译输出更改一下就好看很多。

# list of c objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of c++ objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CPP_SOURCES:.cpp=.o)))
vpath %.cpp $(sort $(dir $(CPP_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	@$(CC) -c $(CFLAGS)  $< -o $@
	@echo "[ c ] $@"

$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR) 
	@$(CPP) -c $(CFLAGS) $< -o $@
	@echo "[c++] $@"

$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
	@$(AS) -c $(CFLAGS) $< -o $@
	@echo "[asm] $@"

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@
	@echo "[->] $@"

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(HEX) $< $@
	
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@	
	
$(BUILD_DIR):
	mkdir $@

编译后的效果如下:

e5a47573b45b42ea9250d606768a1ea3.png

 

三、断言assert

如果看Hal库的代码,可以看见有很多的assert_param。这个东西在代码初始化的时候如果出现了问题会触发断言。

f50728e2d3e247f1a521c3d6a978a281.png

打开STM32CubeMX的这个选项。

65cf54c6385a49d6971a8094cc5e7afa.png

 然后在main.c文件的最下边就会出现这个assert_failed函数。然后更改里面的printf函数就可以实现判断初始化时有没有出现问题了,出现问题会直接串口打印错误文件和行数(Hal库官方的基本不会出现问题,但是我们可以在自己的初始化代码里使用)。

344b30e6de984d029d7e85f83f6dd83c.png

 

<think>嗯,用户遇到了STM32编译错误,提示‘Not enough information to list image symbols’。我得先弄清楚这个错误的原因。根据提供的引用信息,这个错误通常和符号未定义有关。比如引用4提到,可能是因为源文件没有添加到工程中,导致只有头文件声明而没有函数实体。比如SystemInit函数在启动文件startup_stm32f10x_hd.o中被引用,但找不到定义。 首先,我应该检查工程配置是否正确,特别是启动文件是否正确添加。启动文件里会调用SystemInit,如果用户没有正确实现这个函数,或者所在的源文件没有被包含,就会导致这个错误。比如引用1中的例子,SystemInit未定义,可能是因为用户没有在工程里包含system_stm32f10x.c文件。 接下来,用户可能没有正确配置硬件浮点支持,如引用5提到,如果使用了浮点单元但没在工程选项中启用,也会出现类似问题。所以需要检查编译选项,确认是否启用了正确的硬件浮点设置。 另外,工程结构的问题也可能导致源文件未被正确包含。例如,用户可能只添加了头文件目录,但源文件没有被包含到工程里,比如引用4所说的情况。这时候需要手动添加对应的.c文件。 还有,C99模式的设置可能影响编译,引用5提到如果勾选了C99 Mode,有时需要取消勾选。不过这可能因具体环境而异,需要用户尝试。 总结解决步骤的话,应该分为几个方面:检查SystemInit等函数的实现是否缺失,确认启动文件和系统文件是否添加,检查硬件浮点配置,验证工程结构,以及调整C99模式设置。同时,需要提醒用户注意编译器的警告信息,这些可能帮助定位具体缺失的符号。 另外,用户提供的引用中,错误信息还提到了其他可能的未定义符号,比如__aeabi_assert,这可能与断言函数有关,如果用户代码中使用了断言但没有包含相应的库,也可能导致问题。不过当前错误主要是关于SystemInit,所以重点应该放在系统初始化相关的文件上。 可能用户在使用某些开发环境插件时配置有误,比如EIDE插件或者VSCode的环境,需要检查工程配置是否正确导入了所有必要的源文件。同时,启动文件是否正确选择,比如针对不同型号的STM32,启动文件可能有区别,比如hd代表高密度型号,如果选错了启动文件,也可能导致函数不匹配。 最后,应该建议用户按照步骤逐一排查,从添加缺失的源文件开始,然后检查编译选项,确保所有必要的系统文件都被正确包含,并且配置选项如硬件浮点支持已经启用。如果问题依旧,再考虑其他可能性,比如工具链的配置或者插件的问题。</think>### 分步解决方案:STM32编译错误'Not enough information to list image symbols' #### 问题分析 该错误通常由**符号未定义**或**工程配置缺失**引起[^1][^3][^4],具体表现为: 1. 关键函数未实现(如`SystemInit`) 2. 源文件未加入工程(只有头文件声明) 3. 硬件浮点支持未启用 4. C99模式配置冲突 --- #### 解决方案步骤 ##### 1. **检查未定义符号实现** - **SystemInit函数缺失**:STM32启动文件`startup_stm32f10x_xx.s`会调用该函数初始化时钟系统 ```c // 在system_stm32f10x.c中添加实现 void SystemInit(void) { // 设置时钟树(如HSE、PLL等) RCC->CR |= 0x00010000; // 启用HSE while(!(RCC->CR & 0x00020000)); // 等待HSE就绪 } ``` - **确认文件包含**:将`system_stm32f10x.c`和`core_cm3.c`添加到工程中[^4] ##### 2. **验证工程结构** - **Keil工程配置**: 1. 右键项目 -> `Manage Project Items` 2. 在`Source Group`中添加缺失的`.c`文件 3. 确保`startup_stm32f10x_hd.s`启动文件与芯片型号匹配(hd=高密度,md=中密度) - **VSCode/EIDE配置**: 1. 检查`.eide`配置文件中`files.include`字段是否包含所有源文件路径[^2] 2. 更新`c_cpp_properties.json`的包含路径 ##### 3. **硬件浮点配置** - **启用FPU支持**(若使用浮点运算): 1. 打开`Options for Target` -> `Target`标签 2. 在`Code Generation`中勾选`Use FPU` 3. 选择`Single Precision`(单精度)[^5] ##### 4. **编译器模式调整** - **关闭C99 Mode**: 1. `Options for Target` -> `C/C++`标签 2. 取消勾选`C99 Mode`(部分旧版本固件库不兼容C99) --- #### 验证流程 1. 执行`Rebuild All`完整编译 2. 观察`Build Output`窗口: - 若仍有`Undefined symbol`,按错误提示补充对应函数实现 - 若出现`FPU related error`,检查步骤3的硬件浮点配置 --- #### 扩展建议 - 使用`STM32CubeMX`重新生成工程框架,避免手动配置遗漏 - 在启动文件`startup_*.s`中定位`__main`函数调用栈,验证初始化流程[^3] - 对未定义符号使用`Ctrl+F`全局搜索,确认实现文件是否加入工程[^4] [用户可见层] 相关问题 1. 如何验证STM32启动文件的正确性? 2. STM32硬件浮点配置需要注意哪些细节? 3. 为什么C99模式会导致STM32编译错误?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值