环境安装
注:文末提供一键脚本
stm32cubeclt_6">下载安装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_25">下载安装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 Used
RAM: 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.233
Hard reset is performed
MCU Reset
Software reset is performed
RUNNING 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 : Enabled
LogFile Name : debug.log
Logging Level : 31
Listen Port Number : 61234
Status Refresh Delay : 15s
Verbose Mode : Disabled
SWD Debug : Enabled
COM 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/bash
export 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" ]; then
echo "Creating build directory..."
mkdir build
fi
cd build
if [ ! -f "Makefile" ]; then
echo "Running CMake..."
cmake ..
fi
echo "Compiling project..."
make
if [ $? -eq 0 ]; then
echo "Compilation successful."
else
echo "Compilation failed."
exit 1
fi
cd ..
}
# 烧录函数
flash() {
if [ ! -f "build/${PROJECT_NAME}.elf" ]; then
echo "ELF file not found. Please compile the project first."
exit 1
fi
echo "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" ]; then
echo "ELF file not found. Please compile the project first."
exit 1
fi
echo "Starting ST-Link GDB server..."
$STLINK_UTIL &
STUTIL_PID=$!
local load_command=""
if [ "$1" = "load" ]; then
echo "exec load"
load_command="-ex load build/${PROJECT_NAME}.elf"
fi
echo "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" in
build)
compile
;;
flash)
flash
;;
dbg)
if [ "$2" = "load" ]; then
debug load
else
debug
fi
;;
help)
show_help
;;
*)
echo "Invalid option. Use '$0 help' for usage information."
exit 1
;;
esac
}
# 执行主函数
main "$@"