环境安装
注:文末提供一键脚本
下载安装stm32cubeclt
下载地址为:https://www.st.com/en/development-tools/stm32cubeclt.html
选择 linux版本下载安装
安装好后默认在家目录st下
> $ ls ~/st/stm32cubeclt_1.16.0
CMake jre STLink-gdb-server STLinkUpgrade.sh STM32CubeProgrammer STMicroelectronics_CMSIS_SVD uninstall_clt.sh
GNU-tools-for-STM32 Ninja stlink-server.uninstall.sh STM32CubeCLT_metadata.sh STM32target-mcu st-stlink-udev-rules.uninstall.sh
下载安装stm32cubemx
下载地址为https://www.st.com/en/development-tools/stm32cubemx.html
同样下载安装linux版本,安装好后默认在~/STM32CubeMX
开发调试
1. 工程初始化
使用cubemx随意生成一个cmake的测试工程,进入到工程目录
cd balance-car #balance-car为我测试工程文件夹
export PATH=$PATH:$HOME/st/stm32cubeclt_1.16.0/GNU-tools-for-STM32/bin
mkdir build && cd build
cmake ..
2. 工程编译
继续在build目录执行make命令
make
出现以下内容表示编译成功
Memory region Used Size Region Size %age UsedRAM: 2928 B 20 KB 14.30%FLASH: 53928 B 64 KB 82.29%
[100%] Built target balance-car
编译好后的二进制名为balance-car.elf
3.工程下载
执行以下命令下载程序
~/st/stm32cubeclt_1.16.0/STM32CubeProgrammer/bin/STM32_Programmer_CLI --connect port=swd --download ./balance-car.elf -hardRst -rst --start
下载成功提示输出:
Erasing memory corresponding to segment 0:
Erasing internal memory sectors [0 52]
Download in Progress:
[==================================================] 100%File download complete
Time elapsed during download operation: 00:00:03.233Hard reset is performedMCU ResetSoftware reset is performedRUNNING Program ...Address: : 0x8000000
Application is running, Please Hold on...
Start operation achieved successfully
4.工程调试
启动gdbserver
打开一个新的命令窗口进入以下目录
cd ~/st/stm32cubeclt_1.16.0/STLink-gdb-server/bin/
修改此目录下config.txt 中-cp字段,注意需要将home后yala字段修改为自己对应家目录名称
###############################################################
# -cp <path> : Path to STM32CubeProgrammer
# Modify to correct path
# for STM32_Programmer_CLI executable
###############################################################
-cp /home/yala/st/stm32cubeclt_1.16.0/STM32CubeProgrammer/bin
此修改只进行一次,修改完成后启动gdb
./ST-LINK_gdbserver -c config.txt
启动成功输出如下
STMicroelectronics ST-LINK GDB server. Version 7.8.0
Copyright (c) 2024, STMicroelectronics. All rights reserved.Starting server with the following options:Persistent Mode : EnabledLogFile Name : debug.logLogging Level : 31Listen Port Number : 61234Status Refresh Delay : 15sVerbose Mode : DisabledSWD Debug : EnabledCOM frequency = 4000 kHz
Target connection mode: Default
Reading ROM table for AP 0 @0xe00fffd0
Hardware watchpoint supported by the target
ST-LINK Firmware version : V2J45S7
Device ID: 0x410
PC: 0x800b31c
ST-LINK device status: HALT_MODE
ST-LINK detects target voltage = 3.00 V
ST-LINK device status: HALT_MODE
ST-LINK device initialization OK
Stm32Device, pollAndNotify running...
SwvSrv state change: 0 -> 1
Waiting for connection on port 61235...
Waiting for debugger connection...
Waiting for connection on port 61234...
开始调试
回到build目录,启动gdb
~/st/stm32cubeclt_1.16.0/GNU-tools-for-STM32/bin/arm-none-eabi-gdb balance-car.elf
在gdb中连接到gdbserver
(gdb) target remote localhost:61234
Remote debugging using localhost:61234
Reset_Handler () at /home/junchao/work/balance-car/startup_stm32f103xb.s:64
64 bl SystemInit
到这里就可以正常开始下断点调试了
EXT:方法2
从第三步开始,可以使用stlink开源工具实现程序下载、调试
从https://github.com/stlink-org/stlink/releases下载最新deb安装包,安装
sudo dpkg -i ./stlink_1.8.0-1_amd64.deb
-
启动gdbserver
st-util
成功输出为
st-util 1.8.0 2024-11-15T15:40:21 INFO common.c: NRST is not connected --> using software reset via AIRCR 2024-11-15T15:40:21 INFO common.c: STM32F1xx_MD: 20 KiB SRAM, 64 KiB flash in at least 1 KiB pages. 2024-11-15T15:40:21 INFO gdb-server.c: Listening at *:4242...
-
下载调试
回到build目录,执行改变
~/st/stm32cubeclt_1.16.0/GNU-tools-for-STM32/bin/arm-none-eabi-gdb balance-car.elf
在gdb中连接到gdbserver
(gdb) target remote localhost:4242 Remote debugging using localhost:4242 main () at /home/junchao/work/balance-car/Core/Src/main.c:74 74 uint32_t loop_cnt = 0;
现在即可开始调试。若重新编译二进制后可以使用load命令下载更新程序
(gdb) load balance-car.elf Loading section .isr_vector, size 0x10c lma 0x8000000 Loading section .text, size 0xbe54 lma 0x8000110 Loading section .rodata, size 0x1108 lma 0x800bf68 Loading section .ARM, size 0x8 lma 0x800d070 Loading section .init_array, size 0x4 lma 0x800d078 Loading section .fini_array, size 0x4 lma 0x800d07c Loading section .data, size 0x228 lma 0x800d080 Start address 0x0800b31c, load size 53920 Transfer rate: 11 KB/sec, 5392 bytes/write.
一键脚本
编写了一个脚本用于一键操作
将脚本放到工程根目录(勿放到build目录),cubemx生成的工程文件夹名称不能修改,脚本依赖它运行
使用示例
./st-tool build #编译项目
./st-tool dbg # 启动调试
./st-tool dbg load # gdb启动后先进行程序下载操作再进行调试
./st-tool flash # 下载程序
请注意修改 脚本中$HOME/st/stm32cubeclt_1.16.0路径
#!/bin/bashexport PATH=$PATH:$HOME/st/stm32cubeclt_1.16.0/GNU-tools-for-STM32/bin/ # 自动检测项目名称
PROJECT_NAME=$(basename $(pwd))# 工具链配置
TOOLCHAIN_PREFIX="arm-none-eabi-"
GCC="${TOOLCHAIN_PREFIX}gcc"
OBJCOPY="${TOOLCHAIN_PREFIX}objcopy"
GDB="${TOOLCHAIN_PREFIX}gdb"# ST-Link配置
STLINK_FLASH="st-flash"
STLINK_UTIL="st-util"# 编译函数
compile() {if [ ! -d "build" ]; thenecho "Creating build directory..."mkdir buildficd buildif [ ! -f "Makefile" ]; thenecho "Running CMake..."cmake ..fiecho "Compiling project..."makeif [ $? -eq 0 ]; thenecho "Compilation successful."elseecho "Compilation failed."exit 1ficd ..
}# 烧录函数
flash() {if [ ! -f "build/${PROJECT_NAME}.elf" ]; thenecho "ELF file not found. Please compile the project first."exit 1fiecho "Creating binary file..."$OBJCOPY -O binary "build/${PROJECT_NAME}.elf" "build/${PROJECT_NAME}.bin"echo "Flashing binary to device..."$STLINK_FLASH write "build/${PROJECT_NAME}.bin" 0x8000000
}# GDB调试函数
debug() {if [ ! -f "build/${PROJECT_NAME}.elf" ]; thenecho "ELF file not found. Please compile the project first."exit 1fiecho "Starting ST-Link GDB server..."$STLINK_UTIL &STUTIL_PID=$!local load_command=""if [ "$1" = "load" ]; thenecho "exec load"load_command="-ex load build/${PROJECT_NAME}.elf"fiecho "Starting GDB debug session..."# $GDB -ex "target remote localhost:4242" "build/${PROJECT_NAME}.elf"$GDB -ex "set confirm off" \-ex "target remote localhost:4242" \$load_command \-ex "monitor reset halt" \-ex "monitor reset init" \"build/${PROJECT_NAME}.elf"# 清理ST-Link GDB server# kill $STUTIL_PID
}# 帮助信息
show_help() {echo "Usage: $0 [option]"echo "Options:"echo " build Compile the project"echo " flash Flash the binary to the device"echo " dbg Start a GDB debug session"echo " help Show this help message"
}# 主函数
main() {case "$1" inbuild)compile;;flash)flash;;dbg)if [ "$2" = "load" ]; thendebug loadelsedebugfi;;help)show_help;;*)echo "Invalid option. Use '$0 help' for usage information."exit 1;;esac
}# 执行主函数
main "$@"