用 openocd 調試 STM32F103

使用 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 一樣了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章