【发布时间】:2018-04-19 21:21:10
【问题描述】:
我在将 Rust 用于嵌入式用途时遇到了问题,我可以很好地运行和调试程序,但是如果我尝试刷新程序以便它们可以在不连接到我的计算机的情况下运行,它们就无法工作。
作为参考,我使用的是 stm32f303 芯片。这似乎也是最近的问题,因为我以前没有遇到过问题。
正在闪烁的代码(只是闪烁):
#![feature(used)]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate panic_abort; // panicking behavior
extern crate stm32f30x_hal as hal;
use hal::prelude::*;
use hal::stm32f30x;
use hal::delay::Delay;
fn main() {
let cp = cortex_m::Peripherals::take().unwrap();
let dp = stm32f30x::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze(&mut flash.acr);
let mut gpioc = dp.GPIOC.split(&mut rcc.ahb);
let mut led1 = gpioc
.pc13
.into_push_pull_output(&mut gpioc.moder, &mut gpioc.otyper);
let mut delay = Delay::new(cp.SYST, clocks);
loop {
led1.set_high();
delay.delay_ms(1_000_u16);
led1.set_low();
delay.delay_ms(1_000_u16);
}
}
// As we are not using interrupts, we just register a dummy catch all
// handler
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
loop {}
}
OpenOCD 程序命令的输出:
$ openocd -f interface/jlink.cfg -f target/stm32f3x.cfg -c "program target/thumbv7em-none-eabihf/debug/cortex-m-quickstart verify reset exit"
Open On-Chip Debugger 0.10.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>'.
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : No device selected, using first device.
Info : J-Link EDU Mini V1 compiled Mar 16 2017 12:04:38
Info : Hardware version: 1.00
Info : VTarget = 3.178 V
Info : clock speed 1000 kHz
Info : JTAG tap: stm32f3x.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32f3x.bs tap/device found: 0x06422041 (mfg: 0x020 (STMicroelectronics), part: 0x6422, ver: 0x0)
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
adapter speed: 1000 kHz
Info : JTAG tap: stm32f3x.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32f3x.bs tap/device found: 0x06422041 (mfg: 0x020 (STMicroelectronics), part: 0x6422, ver: 0x0)
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1ffff1bc msp: 0x20001258
Info : Reduced speed from 8000 kHz to 4000 kHz (maximum).
adapter speed: 8000 kHz
** Programming Started **
auto erase enabled
Info : device id = 0x10036422
Info : flash size = 256kbytes
wrote 14336 bytes from file target/thumbv7em-none-eabihf/debug/cortex-m-quickstart in 0.688176s (20.344 KiB/s)
** Programming Finished **
** Verify Started **
verified 13028 bytes in 0.077558s (164.041 KiB/s)
** Verified OK **
** Resetting Target **
adapter speed: 1000 kHz
Info : JTAG tap: stm32f3x.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32f3x.bs tap/device found: 0x06422041 (mfg: 0x020 (STMicroelectronics), part: 0x6422, ver: 0x0)
shutdown command invoked
可以看出,刷机时没有任何问题,但它没有运行。再一次,使用 GDB 时一切都很好,代码运行没有任何问题。
我们将不胜感激任何帮助、建议,甚至是关于该做什么的一般性想法!
[更新]
看起来问题出在我的 boot0 引脚上,它被拉高而不是拉低。这意味着当 GDB 没有连接并设置 PC 时,MCU 会尝试从系统内存而不是主内存启动。这解释了为什么它在调试时工作但不能单独工作。
【问题讨论】:
-
使用每种方法的 telnet 接口转储/检查闪存,确认它们正在写入相同的位/字节。
-
可能您的启动代码或重置向量不正确。通过调试器加载实际上并不是从复位向量开始的。它抓住处理器,然后强制寄存器将 PC 置于“入口点”
-
不是 st 的情况,而是使用一些 nxp 芯片,例如向量表中有一个校验和,通过 openocd 的更高级别的工具将为您计算校验和,但 openocd 在较低的 telnet 访问级别不会,导致代码无法工作。
-
这很可能是入口点,在将新项目构建之前,您应该始终对向量表进行分解/检查,然后再将其提交到闪存,以确保工具、您的 makefile 等生成了一个二进制文件将启动。如果是这种情况,您可以在处理器/调试器未挂起的情况下使用 openocd 来检查闪存的开始/入口点以及处理器停止时指示的程序计数器地址,其中一个或两个可能会给您一个指示发生了什么。 (如果这是不正确构建的二进制文件的情况)。
-
在使用新的闪存映像重置部件时,您已将 boot0 拉下是吗?