首页 > 解决方案 > 使用 OpenOCD 和 arm-none-eabi-gdb 将二进制文件加载到 stm32f103c8t6

问题描述

我试图加载从 rust 代码编译的二进制文件,但它不起作用。

首先,我从https://github.com/rust-embedded/discovery下载了 Rust 代码。然后,我建立了它。

# I am in the `src/05-led-roulette` directory
rustup target add thumbv7m-none-eabi
cargo build --target thumbv7m-none-eabi

它已成功编译。

之后,我使用 OpenOCD 成功连接了 stm32f103c8t6。然后,我运行这个命令。

arm-none-eabi-gdb -q target/thumbv7m-none-eabi/debug/led-roulette

但它似乎没有读完。

Reading symbols from target/thumbv7m-none-eabi/debug/led-roulette...
(gdb)

(尚未完成?!)

之后,我尝试了load命令,但它返回了以下句子。

Start address 0x0, load size 0
Transfer rate: 0 bits in <1 sec.

我不知道为什么它不起作用。

请帮我。

标签: rustarmgdbstm32stm32f1

解决方案


先看看你的二进制文件好不好,然后试试telnet,然后是gdb。Rust 也会增加失败的几率,所以从简单的开始:

所以.s

.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.thumb_func
reset:
    ldr r0,some_addr
    ldr r1,[r0]
    add r1,r1,#1
    str r1,[r0]
    b .
    .align
some_addr: .word 0x20000000

建造它

arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x08000000 so.o -o so.elf
arm-none-eabi-objdump -D so.elf 
arm-none-eabi-objdump -D so.elf 

so.elf:文件格式elf32-littlearm

部分.text的反汇编:

08000000 <_start>: 8000000: 20001000 andcs r1, r0, r0 8000004: 08000009 stmdaeq r0, {r0, r3}

08000008:8000008:4802 ldr r0,[pc,#8];(8000014 <some_addr>) 800000a: 6801 ldr r1, [r0, #0] 800000c: 3101 添加 r1, #1 800000e: 6001 str r1, [r0, #0] 8000010: e7fe bn 8000010 <reset:2+0x8> 80001 46c0 无;(移动 r8,r8)

08000014 <some_addr>: 8000014: 20000000 andcs r0, r0, r0

对于小程序(阅读 st 文档),这部分可以基于地址 0x08000000 或 0x00000000。0x08000000 是首选。在这种情况下,向量表必须是第一个忽略反汇编只看值

 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

0x08000009 是复位地址 ORRed 加一。所以0x08000008 | 1 是 0x08000009。所以这至少会启动并尝试无故障地获取代码。

此代码只是读取地址 0x20000000 处的字并将其递增,sram 不受重置的影响,因此我们可以继续重置并查看该值的递增。

使用您拥有的任何配置和接口,我将用于 st 部分的 openocd 组合到一个文件中,并将其与项目以及各种接口(不同版本的 stlink 和 jlink)一起携带。

openocd -f jlink.cfg -f target.cfg 

Open On-Chip Debugger 0.9.0 (2019-04-28-23:34)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : JLink SWD mode enabled
swd
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : J-Link ARM-OB STM32 compiled Jun 30 2009 11:14:15
Info : J-Link caps 0x88ea5833
Info : J-Link hw version 70000
Info : J-Link hw type J-Link
Info : J-Link max mem block 15344
Info : J-Link configuration
Info : USB-Address: 0x0
Info : Kickstart power on JTAG-pin 19: 0x0
Info : Vref = 3.300 TCK = 1 TDI = 1 TDO = 1 TMS = 1 SRST = 1 TRST = 1
Info : J-Link JTAG Interface ready
Info : clock speed 1000 kHz
Info : SWD IDCODE 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

如果在返回控制台时看不到观察点行,则它不起作用。

在另一个窗口

telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>

现在让我们停止芯片并编写我们的程序。psr、pc 等值可能与我的不同,具体取决于您运行的内容。

> reset halt
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000010 msp: 0x20001000
> flash write_image erase so.elf
auto erase enabled
device id = 0x20036410
flash size = 64kbytes
wrote 1024 bytes from file so.elf in 0.437883s (2.284 KiB/s)

让我们阅读它,看看它在那里,应该与反汇编中的单词匹配

> mdw 0x08000000 20
0x08000000: 20001000 08000009 5000f04f 31016801 e7fe6001 ffffffff ffffffff ffffffff 
0x08000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 
0x08000040: ffffffff ffffffff ffffffff ffffffff 

假设这是随机垃圾,只要我们看到它增加就可以了。

> mdw 0x20000000
0x20000000: 2e006816 
> reset
> halt
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000012 msp: 0x20001000
> mdw 0x20000000
0x20000000: 2e006817 

因此,如果您进行重置,则该值会增加,然后停止(不是在一个命令中进行重置停止)然后转储该内存位置,它应该每次都保持增加。

现在您可以选择使用此二进制文件使用 gdb 路径(我没有使用 gdb,所以没有安装),或者通过首先检查向量表以查看它是否正确来检查您的 rust 二进制文件,至少无需重置向量是正确的,那么您将出错并且不会在处理器上运行任何代码。可以使用 telnet 刷新它,或者您可以尝试 gdb。

如果 gdb 的文件有问题,那么您可能使用了错误的文件。或者文件构建不正确。您是否在该存储库中尝试了一个简单的程序?你能从那个存储库中创建一个最小的程序,一个空的入口函数或一个无限循环或一个永远计数的计数器吗?

这真的是一个gdb问题吗?这是一个openocd问题吗?这是 Rust 工具的问题吗?这是一个 Rust 二进制问题吗?这是文档中的错误,您将 gdb 指向错误的文件问题吗?如果上述工作,那么 openocd 工作,binutils 至少工作,调试器/硬件工作,它消除了这些,然后变成这是一个生锈的东西,一个 gdb 的东西,使用错误的文件的东西,还是别的什么?


推荐阅读