使用 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
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
/* TODO Adjust these memory regions to match your device memory layout */
/* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
FLASH : ORIGIN = 0x00000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
}
stm32f103ze 的 flash 的地址是 0x8000000,大小是 512K,改成如下內容:
MEMORY
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
/* TODO Adjust these memory regions to match your device memory layout */
/* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
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 一樣了。