基于Vivado , Vitis , VSCode , OPENOCD 平台 , FT232HL - MPSSE 多协议通信,开源开发ARM与FPGA
一般MCU开发
准备
FT232HL模块
淘宝上买,或者PDD,咸鱼,自己做也行
FT2332也行,反正用有FTDI的MPSSE功能的
VScode -- Visual Studio Code
VS Code + PlatformIO = 开发 ESP32,RP2040
VS Code + Verilog 插件 = 编写 FPGA 逻辑代码
VS Code + C/C++ 插件 = 普通单片机 C 程序
Visual Studio Code - Windows官方下载 | 微软应用商店 | Microsoft Store
OPENOCD -- Open On-Chip Debugger
一款开源的片上调试与编程工具-- 穷人的 Lauterbach
OpenOCD下载安装保姆级教程(附安装包,非常详细)-阿里云开发者社区
Zadig -- Windows USB 驱动安装工具
Zadig - USB driver installation made easyZadig - USB driver installation made easy
第一步——给FT232HL换Windows USB 驱动
插上FT232H 模块
电脑的识别有时候不好辨认
可以下载FT专用驱动
===官网的点一下就行
https://ftdichip.com/wp-content/uploads/2025/03/CDM2123620_Setup.zip
===按照步骤来FTDI FT232驱动下载安装 高速转换器UIC系列驱动安装详细教程_ftdi串口驱动-CSDN博客
打开Zidag安装USB驱动
===点Options --> List All Devices
按照图中的指示配置

===点击Replace Driver之后,会显示成功,这样一来,Windows的USB驱动已经在FT232HL上安装好了

===如果想变回出厂驱动,直接右键删掉

第二步——将FT232模块与单片机连接
先看FT232HL的数据手册
FT232HL-REEL -PDF数据手册-参考资料-立创商城

看MPSSE那一栏
对应连接你的开发板或者芯片引脚
MCU的电源最好单独供电,别用模块的PC电源,但是别忘了共地
好的,这样一来我们就完成了硬件层的工作,下面就要在OPENOCD上配置FT232HL和MCU了
第三步——在OPENOCD上配置.cfg文件
下载并解压
文件路径不要有中文
里面的OPENOCD文件是这样的

OpenOCD 本身没有图形窗口,是命令行程序,用来驱动 FT232/J-Link/DAPLink,做 JTAG/SWD 调试
i. 点开bin文件,先进入CMD

左键点击地址栏,就是图片中最上面有很多箭头的,左键后会变成蓝色的,在键盘上输入CMD,紧接着点击键盘上的Enter会跳转到专用的命令提示符

这里就是OPENOCD的运行区域
ii. 配置调试器和MCU芯片的.cfg文件
OPENOCD厂商已经写好了,你要去找到你需要的,我们这里的MCU以STM32F103为例,也可以换成你需要的,这里有很多对应的资源

这里是对.cfg文件的解释

我们主要用interface 和 target

找到ft232h-module-swd.cfg,按照下图修改,把transport select swd改成jtag
再改个名字ft232h-module-jtag.cfg
transport select jtag = 告诉 OpenOCD:底层 MPSSE 硬件走 JTAG 时序引擎

在D:\openocd-0.11_mingw64_msys2_repack\bin>环境写入指令,必须保证接线无误
"D:\openocd-0.11_mingw64_msys2_repack\bin\openocd.exe"
-s "D:\openocd-0.11_mingw64_msys2_repack\share\openocd\scripts"
-f "interface/ftdi/ft232h-module-jtag.cfg"
-f "target/stm32f4x.cfg"
模拟JTAG
JTAG 或者 SWD
- FPGA/ZYNQ 开发:只能用 JTAG;
- STM32、GD32、nRF 等 Cortex-M 单片机:一律用 SWD,省引脚、速度快;
- 一块板上同时有 FPGA+MCU:JTAG 菊花链,一个下载器调试全部;
- 小引脚单片机(如 STM32F0/F103C4T6)引脚紧张,必须 SWD
- 树莓派PICO RP2040也可以用STlink
JTAG 或者 SWD
- FPGA/ZYNQ 开发:只能用 JTAG;
- STM32、GD32、nRF 等 Cortex-M 单片机:一律用 SWD,省引脚、速度快;
- 一块板上同时有 FPGA+MCU:JTAG 菊花链,一个下载器调试全部;
- 小引脚单片机(如 STM32F0/F103C4T6)引脚紧张,必须 SWD
- 树莓派PICO RP2040也可以用STlink
如果你用STLINK JTAG模块
调试器换成stlink-v2-1.cfg 或者 jlink.cfg
- JTAG(IEEE 1149.1):通用标准边界扫描协议,原生四线并行调试;
- SWD(Serial Wire Debug):ARM 专为 Cortex-M 系列设计的精简串行调试协议,是 JTAG 的轻量化替代方案
第四步 ——在VScode上开发
到这里就是在VS平台上开发嵌入式了,无论你是用STLink的SWD协议还是JTAG协议,这都是前面的步骤,接下来我们就来到VScode继续配置
文件目录格式

对着截图里面的来
.bin
.elf
.hex
这三个是我们要生成的文件,这里我已经跑过一次了
不需要配置
下载arm-tool-chain
launch.json
{
"version": "0.2.0",
"configurations": [
{
//自己取一个名字
"name": "烧录并调试 (STM32F407)",
//先安装 Cortex-Debug 插件
"type": "cortex-debug",
"request": "launch",
"servertype": "openocd",
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/build/stm32f407.elf",
//GDB路径,如果没有安装GDB,请先安装ARM-GCC工具链
"gdbPath": "D:\ARM-TOOL-CHAIN\xpack-arm-none-eabi-gcc-15.2.1-1.1-win32-x64\xpack-arm-none-eabi-gcc-15.2.1-1.1\bin\arm-none-eabi-gdb.exe"",
//OpenOCD.exe路径,如果没有安装OpenOCD,在bin目录下找openocd.exe
"serverpath": "D:/openocd-0.11_mingw64_msys2_repack/bin/openocd.exe",
//OpenOCD配置文件路径,注意这里是OpenOCD安装目录下的scripts文件夹
"searchDir": [
"D:/openocd-0.11_mingw64_msys2_repack/share/openocd/scripts"
],
//OpenOCD配置文件路径,按照刚刚找到的对应的配置文件路径填写
"configFiles": [
//调试器
"interface/ft232h-module-jtag.cfg",
//芯片型号
"target/stm32f4x.cfg"
],
//调试器端口号,默认是3333
"runToEntryPoint": "main"
}
]
}
c_cpp_properties.json
{
"configurations": [
{
"name": "STM32F407",
"includePath": [
"${workspaceFolder}/Inc"
],
"defines": [
"STM32F407xx",
"USE_HAL_DRIVER"
],
"compilerPath": "D:/ARM-TOOL-CHAIN/xpack-arm-none-eabi-gcc-15.2.1-1.1-win32-x64/xpack-arm-none-eabi-gcc-15.2.1-1.1/bin/arm-none-eabi-gcc.exe",
"cStandard": "c99",
"intelliSenseMode": "gcc-arm"
}
],
"version": 4
}
***关于STM32F407的详细说明,可以通过一下资源学习
野火【STM32F407开发板-霸天虎】
https://pan.baidu.com/s/11NsIrK254nAGgVn4j9xfkw?pwd=8bSu
Inc和Src
复制链接,我这里的是F407HAL和STAD库
链接:https://pan.quark.cn/s/c1dc6cae9f26?pwd=aanj
提取码:aanj
当然你也可以自己找其他的
选HAL或者STAD(标准库)
然后放到上面就行
我们接下来要补齐一些 .h和 .c文件还有 .s(启动文件), .ld描述文件
stm32f4xx.s启动汇编文件
启动文件--gcc 版本
GCC based toolchains
cmsis-device-f4/Source/Templates/gcc at master · STMicroelectronics/cmsis-device-f4
.h头文件寻配
STM32 HAL库头文件三胞胎stm32f4xx.h---f407.h---f4xx_hal.h解析(区别和联系) - FBshark - 博客园
可以看看这篇文章理解.h头文件的工作原理

stm32f4xx.h顶级文件
再找到你需要的芯片的寄存器映射文件,比如我这里是
stm32f407xx.h
system_stm32f4xx.h 时钟配置
stm32f4/include/system_stm32f4xx.h at master · elliottt/stm32f4
在没有配置好makefile之前,顶层头文件会报错
还有一些core.h支持API文件
core_cm4.h
cmsis_gcc.h
core_cmInstr.h
core_cmSimd.h
core_cmFunc.h
CMSIS_4/CMSIS/Include/core_cmInstr.h at master · ARM-software/CMSIS_4
以上这些带 .h的都放到Inc文件夹
STM32F407ZGTX_FLASH.ld
.c文件寻配
system_stm32f4xx.c
cmsis-device-f4/Source/Templates/system_stm32f4xx.c at master · STMicroelectronics/cmsis-device-f4
syscalls.c
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
extern int errno;
char *__env[1] = { 0 };
char **environ = __env;
void _exit(int status)
{
while (1);
}
int _close(int file)
{
return -1;
}
int _fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
int _isatty(int file)
{
return 1;
}
int _lseek(int file, int ptr, int dir)
{
return 0;
}
int _read(int file, char *ptr, int len)
{
return 0;
}
int _write(int file, char *ptr, int len)
{
return len;
}
int _getpid(void)
{
return 1;
}
int _kill(int pid, int sig)
{
errno = EINVAL;
return -1;
}
/* 堆内存分配 - 使用链接脚本提供的符号 */
extern char _end;
extern char _estack;
void *_sbrk(int incr)
{
static char *heap_end = 0;
char *prev_heap_end;
if (heap_end == 0)
heap_end = &_end;
prev_heap_end = heap_end;
if (heap_end + incr > &_estack)
{
errno = ENOMEM;
return (void *) -1;
}
heap_end += incr;
return (void *) prev_heap_end;
}
!!!!!!注意:要写一个main.c文件,不然会报错!!!!!!!
makefile配置
当你直接运行 make 时,Makefile 会执行第一个目标。而你的 Makefile 里第一个目标是 $(BUILD_DIR)(创建 build 目录),所以 make 认为 build 目录已存在,就直接结束了
.DEFAULT_GOAL := all
# ====================== 1. 芯片与全局宏(解决#error报错) ======================
MCU_TARGET = STM32F407xx
# -D 全局传入芯片宏与HAL库宏,无需在.h里手动定义
DEFINES = -D$(MCU_TARGET) -DUSE_HAL_DRIVER
# ====================== 2. GCC工具链配置(已填你验证成功的完整路径) ======================
TOOL_PREFIX := /d/ARM-TOOL-CHAIN/xpack-arm-none-eabi-gcc-15.2.1-1.1-win32-x64/xpack-arm-
#换上你的GCC工具链地址
none-eabi-gcc-15.2.1-1.1/bin/arm-none-eabi-
CC := $(TOOL_PREFIX)gcc
AS := $(TOOL_PREFIX)gcc
LD := $(TOOL_PREFIX)gcc
OBJCPY := $(TOOL_PREFIX)objcopy
SIZE := $(TOOL_PREFIX)size
RM := rm -rf
MKDIR := mkdir -p
# ====================== 3. 内核&编译参数 Cortex-M4 ======================
CPU_FLAGS = -mcpu=cortex-m4 -mthumb
FPU_FLAGS = -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS = $(CPU_FLAGS) $(FPU_FLAGS)
# 编译选项:警告、调试、C99标准
CFLAGS += -Wall -g3 -O0 -std=c99
CFLAGS += $(DEFINES)
# 链接参数:浮点printf、精简库
LDFLAGS = $(CPU_FLAGS) $(FPU_FLAGS)
LDFLAGS += --specs=nano.specs -u _printf_float
LDFLAGS += -TSTM32F407ZGTX_FLASH.ld
# ====================== 4. 头文件搜索路径 ======================
INCLUDES = \
-I./Inc \
-I./Drivers/STM32F4xx_HAL_Driver/Inc \
-I./Drivers/CMSIS/Device/ST/STM32F4xx/Include \
-I./Drivers/CMSIS/Include
# ====================== 5. 源文件配置 ======================
# C源码:Src目录下所有.c文件
C_SRCS = $(wildcard Src/*.c)
# 启动汇编文件
ASM_SRCS = startup_stm32f407xx.s
#!!!务必对应.s启动文件
# ====================== 6. 编译输出目录与产物 ======================
BUILD_DIR = build
# 所有目标.o文件,统一放到build文件夹
OBJS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SRCS:.c=.o)))
OBJS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SRCS:.s=.o)))
TARGET = app
ELF = $(TARGET).elf
BIN = $(TARGET).bin
HEX = $(TARGET).hex
#这些就是我们用makefile编译好的二进制和十六进制文件了
# ====================== 7. 编译规则(所有命令行首字符为Tab,禁止空格)======================
# 创建build文件夹
$(BUILD_DIR):
$(MKDIR) $(BUILD_DIR)
# 编译Src下的.c文件
$(BUILD_DIR)/%.o: Src/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
# 编译启动汇编.s文件
$(BUILD_DIR)/%.o: %.s | $(BUILD_DIR)
$(AS) $(CFLAGS) -c $< -o $@
# 链接生成elf可执行文件
$(ELF): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $(ELF)
$(SIZE) $(ELF)
# 生成bin烧录文件
$(BIN): $(ELF)
$(OBJCPY) -O binary $(ELF) $(BIN)
# 生成hex烧录文件
$(HEX): $(ELF)
$(OBJCPY) -O ihex $(ELF) $(HEX)
# ====================== 8. 顶层命令 ======================
# 全部编译生成elf/bin/hex
all: $(ELF) $(BIN) $(HEX)
# 清理编译中间文件与产物
clean:
$(RM) $(BUILD_DIR) $(ELF) $(BIN) $(HEX)
#下面的是你在OPENOCD的链接硬件的指令,我在上面有提到过,换上对应的烧录器与芯片的配置链接指令
# OpenOCD一键下载(适配VSCode openocd调试,可直接make flash)
flash: all
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program $(BIN) 0x08000000 verify reset exit"
第五步——MSYS2 开始编译
首先我们要确保已经在环境变量里面有这三样

下载MSYS2 mingw64/32
MinGW-w64的安装详细步骤(c/c++的编译器gcc、g++的windows版,win10、win11真实可用)-CSDN博客
理解三者关系
# MSYS、MinGW、Makefile 三者完整区别
先一句话分清定位:
1. **MinGW**:Windows 下编译 C/C++ 的**GCC编译器套件**(核心是gcc.exe)
2. **MSYS / MSYS2**:Windows 上一套**类Linux运行环境+Shell工具**(bash、rm、ls、make等)
3. **Makefile**:**构建脚本文件**,和系统无关,用来告诉 `make` 怎么编译代码
## 一、MinGW(Minimal GNU for Windows)
### 是什么
把 Linux 的 GCC、g++、ld 等编译工具移植到 Windows,**原生Windows程序**,不依赖Linux内核。
### 作用
- 提供 `gcc.exe`、`g++.exe`、`ar.exe`、`ld.exe` 编译器
- 编译出来是 `.exe`,可直接双击在Windows运行
### 缺点
- 只有编译器,缺少Linux命令:没有 `bash`、`ls`、`rm`、`make`、`sed`、`git`
- Windows cmd语法和Linux完全不同,手写Makefile极易报错(路径分隔符`\` vs `/`、换行符差异)
## 二、MSYS / MSYS2(MinGW配套类Unix环境)
### 是什么
一套轻量POSIX兼容层,自带 **bash shell + 全套Linux工具链**,分为两代:
- 老MSYS:配套旧MinGW,过时
- MSYS2:现在主流,自带包管理器pacman,可一键装gcc、cmake、git、python等
### 和MinGW关系
MSYS2内部包含**MinGW-w64**(新版MinGW,支持32/64位):
- MSYS2环境 = Shell工具(bash/make) + MinGW-w64编译器(gcc)
### 作用
1. 提供类Linux终端,支持`ls cd rm mkdir`等命令
2. 自带`make.exe`,完美解析Linux风格Makefile
3. 统一路径写法 `/c/Users/xxx`,不用折腾Windows反斜杠
### 运行区分(MSYS2三种环境)
1. **MSYS**:纯POSIX环境,编译Linux风格程序
2. **MINGW32/MINGW64**:调用MinGW-w64编译器,生成原生Windows exe(日常开发用这个)
## 三、Makefile
### 是什么
**文本脚本**,是 `make` 工具的配置文件,不属于MinGW/MSYS,Linux/macOS/Windows通用。
### 作用
描述工程编译规则:哪些源文件要编译、依赖关系、编译参数、链接库、清理、打包等。
示例极简Makefile:
```makefile
all: main
main: main.c
gcc main.c -o main.exe
clean:
rm -f main.exe
```
### 依赖工具
必须有 `make` 程序才能执行Makefile:
- Windows cmd无make,单纯装MinGW用不了Makefile
- MSYS/MSYS2自带make,直接 `make / make clean`
# 四、三者核心对比表
| 名称 | 类型 | 核心用途 | 单独使用可行吗 |
| -------- | ------------------ | --------------------------------- | -------------- |
| MinGW | C/C++编译器(GCC) | 把C代码编译成Windows exe | 单独只能编译,不能跑Makefile |
| MSYS2 | Unix Shell+工具集 | 提供bash、make、git等Linux命令,封装MinGW | 可以独立完整开发C项目 |
| Makefile | 构建脚本文件 | 定义工程自动编译流程 | 必须搭配make工具,本身无法运行 |
# 五、开发场景关系(完整流程)
1. 写代码 + 写 **Makefile**
2. 打开 **MSYS2 MINGW64** 终端(内置MinGW编译器+make)
3. 执行 `make`:make读取Makefile,调用MinGW的gcc完成编译
# 六、常见误区澄清
1. 误区:MinGW能跑Makefile
错。MinGW只有gcc,不带make、bash,cmd里执行make会报“不是内部命令”。
2. 误区:MSYS就是编译器
错。MSYS只是终端环境,编译代码还是靠内部的MinGW-w64。
3. 误区:Makefile是MSYS专属
错。Linux、macOS、WSL、MSYS2都能用Makefile,只是Windows原生环境缺少make工具。
# 七、最简总结
- **MinGW = 编译器(造exe的工具)**
- **MSYS2 = 类Linux工作台(提供终端、make、配套命令,里面自带MinGW)**
- **Makefile = 编译说明书(告诉make怎么调用gcc编译工程)**
启动MSYS2.exe
输入在VScode上的文件地址,改成以下风格
cd /d/Enbed/OPENOCD-F407

粘贴到MSYS2.c的工作区
记住必须右键,不能ctrl+V

然后输入
make clean
make -j4
就可以开始编译了
等待编译

最后输出这种东西就算成功编译,最后生成了二进制和十六进制的文件,让MCU执行
下一步就是烧录了
再在刚刚的MSYS2命令窗口输入
make flash
就可以烧录你的程序!
到此为止就完成了!!!
ARM--XILINX开发
FPGA---XILINX开发
更多推荐

所有评论(0)