Debug STM32F103 with openocd
background
When AWTK runs on STM32, the Keil management project is used by default. Generally, when buying a development board, the manufacturer provides the keil project, which is more convenient to transplant and easy to use, but the follow-up maintenance is more troublesome:
-
AWTK often adds new files (such as new controls), it is very troublesome to synchronize to keil, each project needs to be modified, and the documents also need to be updated synchronously.
-
AWTK's comments are in Chinese. In order to ensure that each compiler can compile normally, AWTK source files generally use UTF-8 With BOM encoding. If you use Keil to modify the code, it will remove the BOM after saving, and then you have to use other tools to add the BOM back.
Also, I personally don't really like working under Windows. Always hope to use gcc to compile, use gdb to debug. Tried it before, without success. Recently, I looked at rust-embedded and found that openocd can be used to debug, and it can be used for personal testing.
I have a stm32f103ze board in hand, which is a little different from the example provided by rust-embedded and needs to be improved. Make a note here for later use when transforming the AWTK compilation script.
1. Install related packages
The installation method under Mac is as follows:
# Rust
brew install rust
# GDB
brew install armmbed/formulae/arm-none-eabi-gcc
# OpenOCD
brew install openocd
# QEMU
brew install qemu
After installation, you need to add cargo's bin directory to the environment variable PATH.
export PATH="$HOME/.cargo/bin:$PATH""
This step is very important, otherwise rustup cannot be found, or the following error occurs when compiling:
error[E0463]: can't find crate for `core`
|
= note: the `thumbv7m-none-eabi` target may not be installed
Install cargo-generate
cargo install cargo-generate
2. Generate a rust project
Run the following command, enter app for the project name
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
enter the app
cd app
3. Modify the configuration
Set the target, STM32F103 uses thumbv7m-none-eabi
rustup target add thumbv7m-none-eabi
You can also modify .cargo/config directly.
4. Modify 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
}
The address of the flash of stm32f103ze is 0x8000000, the size is 512K, and it is changed to the following:
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. Compile
cargo build
In the document, several commands are provided to view the generated executable file, but it seems that they cannot be used:
cargo readobj --bin app -- -file-headers
Prompt error:
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Failed to execute tool: readobj
You can use the arm-none-eabi-xxx command directly instead:
arm-none-eabi-readelf -h target/thumbv7m-none-eabi/debug/app
We can look at the location and size of the code (mainly to confirm whether it is consistent with memory.x)
arm-none-eabi-size -A -x target/thumbv7m-none-eabi/debug/app
output:
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. Debug
Modify openocd.cfg
The original content is as follows:
# 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]
Because I am using jlink, I changed it to the following:
# 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]
start openocd
The normal output is as follows, prompting to listen to port 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
Start gdb. There are some initialization commands in openocd.gdb in the project directory, which can be used directly to avoid manual input.
arm-none-eabi-gdb target/thumbv7m-none-eabi/debug/app -x openocd.gdb
The subsequent debugging method is the same as gdb.