VSCode简洁美观、功能强大、插件丰富。多用于桌面开发,或许你不知道vscode还可以用来开发嵌入式。下面就来详细介绍下实现过程
依赖的工具
- STM32CUBEMX, ST官方的初始化代码生成工具
- Visual Studio Code, 个人认为目前最优秀的跨平台代码编辑器
- MingGW, windows版gcc,主要使用其make命令
- GNU Arm Embedded Toolchain, 交叉编译工具链
- openocd, 烧录工具
安装注意事项
mingw下载安装:
Downloads - Mingw-w64GCC for Windows 64 & 32 bitshttps://www.mingw-w64.org/downloads/#mingw-builds进入后选择“Mingw-builds”,点进去下载就行
另一种选择是下载集成mingw的codeblocks,安装包里集成了mingw
Code::Blocks - Code::Blockshttp://www.codeblocks.org/
GNU Arm Embedded Toolchain的下载安装
下载链接:
下载这个安装包安装即可
openocd的下载与配置
下载链接:
Download OpenOCD for Windowshttps://gnutoolchains.com/arm-eabi/openocd/只有压缩包版本,下载完后解压,放入已知目录即可。比如C:\Program Files\
以上软件,安装完成后,需要将其bin目录添加要path环境变量
比如我的:
检验是否配置正确:
按住shift右击桌面空白处,打开powershell 。 输入以下命令检测安装配置的正确性:
make --version
arm-none-eabi-gcc --version
openocd --version
如果正常,都能得到版本信息:
如果提示找不到make, 可能原因是名称不对,原来是因为安装完后默认加了mingw32的前缀,进入mingw的bin目录,直接把mingw32-make.exe复制一份,然后重命名为make.exe就OK了
到此,准备工作算是完成了。
vs code的配置
插件安装 安装c/c++ Extension Pack这个插件就行了
这个扩展包比较全。需要的都包括了。
另外,强烈推荐one dark pro 这个主题插件
牛刀小试
一 使用stm32cubemx生成初始代码
- 时钟和系统配置
下图中必须选择Serial Wire,否则有奇怪的结果 - 外设配置,这里使能串口1, 参数(115200, 8, N , 1)
-
项目设置
Toolchain/IDE这一栏,我们不选任何IDE,只选makefile
-
代码生成选项,我习惯只copy需要的库,且成对(.c/.h)生成
-
配置完成后,点击右上角的生成按钮,生成工程
二 用vscode开发
用vscode打开项目文件夹
首先看看makefile文件
源文件和头文件
随便打开一个.c文件,发现有很多未“定义标识符”错误提示,虽然不影响编译,但是看着不爽
这是因为vscode 不知道去哪里索引。
下面来解决这个问题 按下ctrl+shift+p快捷键,输入 c/c++自动弹出
编辑c/c++这个插件的配置文件, 根据makefile配置includePath, 左边是.json文件,右边是makefile文件:
是一一对应的,browse 栏下的path 也配置下 编译器路径"compilerPath"要配置正确。保存后再看刚才打开的源文件,错误提示全没了
打开终端输入make就能编译
成功生成bin和hex文件。
编译时,输出的信息太乱(因为命令很长)?可以设置成静默编译,修改makefile,在命令的前面加入@,同时echo当前编译的文件。(😂对makefile语法不是很懂的可以补一下相关教程)
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
@echo "build $<"
@$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
@echo "build $<"
@$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
@echo "generate elf file"
@$(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
再运行make试试:
编译输出简洁多了,完美。
三 用openocd烧写代码
把printf映射到串口1
修改usart.h文件
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
usart.c添加如下代码
/* USER CODE BEGIN 1 */
int _write(int file, char *ptr, int len)
{
HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY);
return len;
}
/* USER CODE END 1 */
main.c:
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(1000);
printf("hello world\n");
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
加在USER CODE BEGIN和USER CODE END之间的代码,cubemx下次生成时不会删除
工程中添加openocd的配置文件,加如下内容
source [find interface/stlink-v2.cfg]
source [find target/stm32f1x.cfg]
修改makefile:
#######################################
# clean up
#######################################
clean:
del /q $(BUILD_DIR)
#######################################
# flash
#######################################
load: all
openocd -f ./openocd.cfg -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).hex verify reset exit"
reset:
openocd -f ./openocd.cfg -c init -c halt -c reset -c shutdown
erase:
openocd -f ./openocd.cfg -c init -c halt -c "flash erase_sector 0 0 last" -c shutdown
注意,命令中的 ./openocd.cfg和上一步中的文件名保持一致。
正常情况,终端输入make load就能烧写了
烧写成功。连上串口助手看到打印结果正确,一秒一次,正确输出"hello world", 说明printf重定向也是对的,Great!