使用 openocd 调试 STM32F103
背景
AWTK 在 STM32 上运行时,默认是使用的 Keil 管理工程。一般买开发板时,厂家提供的都是 keil 工程,移植起来比较方便,上手简单,但是后续维护比较麻烦:
-
AWTK 经常增加新的文件(比如新控件),同步到 keil 很麻烦,每个工程都要修改,文档也需要同步更新。
-
AWTK 的注释是中文,为了保证每个编译器都能正常编译,AWTK 源文件一般使用 UTF-8 With BOM 的编码。如果用 Keil 修改了代码,保存后它把 BOM 给去掉了,之后还得用其它工具把 BOM 加回去。
另外,我个人也不太喜欢在 Windows 下工作。一直希望用 gcc 来编译,用 gdb 来调试。以前尝试过,没有成功。最近看 rust-embedded,发现可以用 openocd 来调试,亲测可以使用。
我手上有块 stm32f103ze 板子,和 rust-embedded 提供的例子有些不同,需要做些改进。这里先做个笔记,供以后改造 AWTK 编译脚本时使用。
1. 安装相关软件包
Mac 下的安装方法如下:
# Rust
brew install rust
# GDB
brew install armmbed/formulae/arm-none-eabi-gcc
# OpenOCD
brew install openocd
# QEMU
brew install qemu
安装之后需要把 cargo 的 bin 目录加入到环境变量 PATH 中。
export PATH="$HOME/.cargo/bin:$PATH""
这一步很重要,否则出现找不到 rustup,或者编译时出现下面的错误:
error[E0463]: can't find crate for `core`
|
= note: the `thumbv7m-none-eabi` target may not be installed
安装 cargo-generate
cargo install cargo-generate
2. 生成一个 rust 工程
运行下列命令,项目名输入 app
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
进入 app
cd app
3. 修改配置
设置 target,STM32F103 使用的是 thumbv7m-none-eabi
rustup target add thumbv7m-none-eabi
直接修改 .cargo/config 也可以。
4. 修改 memory.x
MEMORY
{
FLASH : ORIGIN = 0x00000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
}
stm32f103ze 的 flash 的地址是 0x8000000,大小是 512K,改成如下内容:
MEMORY
{
FLASH : ORIGIN = 0x8000000, LENGTH = 512K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
}
5. 编译
cargo build
文档中,提供的几个命令,用来查看生成的可执行文件,貌似不能用:
cargo readobj --bin app -- -file-headers
提示错误:
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Failed to execute tool: readobj
可以直接使用 arm-none-eabi-xxx 命令代替吧:
arm-none-eabi-readelf -h target/thumbv7m-none-eabi/debug/app
我们可以看看代码的位置和大小(主要是确认是否和 memory.x 一致)
arm-none-eabi-size -A -x target/thumbv7m-none-eabi/debug/app
输出:
target/thumbv7m-none-eabi/debug/app :
section size addr
.vector_table 0x400 0x8000000
.text 0x558 0x8000400
.rodata 0x138 0x8000958
.data 0x0 0x20000000
.bss 0x0 0x20000000
.uninit 0x0 0x20000000
.debug_abbrev 0x1432 0x0
.debug_info 0x21e99 0x0
.debug_aranges 0x1ca0 0x0
.debug_ranges 0x17f30 0x0
.debug_str 0x2b41f 0x0
.debug_pubnames 0x9800 0x0
.debug_pubtypes 0xad8 0x0
.ARM.attributes 0x32 0x0
.debug_frame 0x5b5c 0x0
.debug_line 0x2643b 0x0
.debug_loc 0x17e 0x0
.comment 0x6d 0x0
Total 0x9f1d6
6. 调试
修改 openocd.cfg
原来内容如下:
# Sample OpenOCD configuration for the STM32F3DISCOVERY development board
# Depending on the hardware revision you got you'll have to pick ONE of these
# interfaces. At any time only one interface should be commented out.
# Revision C (newer revision)
source [find interface/stlink-v2-1.cfg]
# Revision A and B (older revisions)
# source [find interface/stlink-v2.cfg]
source [find target/stm32f3x.cfg]
因为我用的是 jlink,所以改成如下内容:
# Sample OpenOCD configuration for the STM32F3DISCOVERY development board
# Depending on the hardware revision you got you'll have to pick ONE of these
# interfaces. At any time only one interface should be commented out.
# Revision C (newer revision)
source [find interface/jlink.cfg]
source [find target/stm32f3x.cfg]
启动 openocd
正常输出如下,提示监听 3333 端口:
Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link V9 compiled Dec 30 2018 15:35:20
Info : Hardware version: 9.20
Info : VTarget = 3.229 V
Info : clock speed 1000 kHz
Info : JTAG tap: stm32f3x.cpu tap/device found: 0x3ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x3)
Warn : JTAG tap: stm32f3x.cpu UNEXPECTED: 0x3ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x3)
Error: JTAG tap: stm32f3x.cpu expected 1 of 1: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32f3x.bs tap/device found: 0x06414041 (mfg: 0x020 (STMicroelectronics), part: 0x6414, ver: 0x0)
Error: Trying to use configured scan chain anyway...
Warn : Bypassing JTAG setup events due to errors
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f3x.cpu on 3333
Info : Listening on port 3333 for gdb connections
启动 gdb。项目目录下的 openocd.gdb 中有些初始化命令,可以直接使用,免得手工输入。
arm-none-eabi-gdb target/thumbv7m-none-eabi/debug/app -x openocd.gdb
后续的调试方法就和 gdb 一样了。