[英]STM32F722 Hard Fault / Flash / Linker Script Issues
我将尝试尽可能最好地描述它,并通过我尝试解决的所有问题 go 但我不确定我是否能够捕捉到这一切,因为我遇到了一些奇怪的行为。 我首先要说的是,使用 STM32CubeIDE 时根本不会出现此问题。 自从我一直在使用 Makefile、OpenOCD 和 GDB 的 STM32 VSCode 以来,它才刚刚开始。显然,我可以轻松地将 go 返回到 CubeIDE,但我想让它与 VSC 一起工作,因为它是一个更好的界面。 我也使用 Mac 并运行 MacOS 13.0 Ventura。 我所有的工具都是用 Homebrew 安装的。
当我注意到我的代码在尝试运行 function 以初始化 MPU-6000 acc/gyro mpu6000Init()
时,我的代码会将 go 放入 Hardfault 处理程序时,这个问题首先出现。 这个 function 没有什么特别之处。它通过 SPI 向 IMU 发送一组数据,以在发送之间有延迟来初始化一些设置。 更奇怪的是,当我逐行执行代码时,它工作得很好。 即,如果我在 function 的开头放置一个断点并逐行运行,则没有问题。 我真的不知道那是什么意思。 当我检查调用堆栈时,它似乎来自延迟 function 但我不确定为什么,因为我早些时候使用延迟 function 没有问题。
我所有的代码都在这里。 重要的文件是Src/main.c
, Src/drv/drv_system.c
, Src/sensors/mpu6000.c
。
我确实知道可能导致此问题的其中一件事是我已经编辑了我的 linker 脚本以具有“虚拟 eeprom”,其中我将 flash 的一部分分开,因此我有一些非易失性 memory 我可以在其中保存当我关闭它时设置等。 当我刷新代码时,我的整个 EEPROM 都被擦除,我必须重新刷新设置。 是否可以避免使用 linker 脚本? 这看起来像这样:
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 384K
EEPROM (rx) : ORIGIN = 0x08060000, LENGTH = 128K
}
...
.eeprom 0x08060000 :
{
. = ALIGN(4);
KEEP(*(.eeprom))
. = ALIGN(4);
} > EEPROM
然后在main.c
的顶部我有这个const uint8_t __attribute__((__section__(".eeprom"), used)) eepromArray[131072];
提醒一下,所有这些都适用于 CubeIDE。 只是我用VSC用的工具不行。
当我在 STM32CubeProgrammer 中运行这段代码时,我使用了硬故障检测器,它让我得到了这个
另一件值得注意的事情:当我运行代码时,“输出”window 显示为:
* Executing task: "/usr/bin/make" -j16 -f STM32Make.make flash
"/opt/homebrew/bin/openocd" -f ./openocd.cfg -c "program build/Autodrone32.elf verify reset exit"
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 "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 2000 kHz
Info : STLINK V2J39M27 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.241885
Info : stm32f7x.cpu: hardware has 8 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f7x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080054a4 msp: 0x20040000
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
** Programming Started **
Info : device id = 0x10006452
Info : flash size = 512 kbytes
Info : Flash write discontinued at 0x08008358, next section at 0x08060000
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
shutdown command invoked
* Terminal will be reused by tasks, press any key to close it.
我关心的一行是Info: Flash write discontinued at 0x08008358, next section at 0x08060000
。 老实说,我不知道它到底是什么意思,但我认为 flash 的编写方式发生了一些奇怪的事情。 我试着查找这个问题,但没有找到任何有用的信息。
我使用的工具版本:
打开强迫症
Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Arm 嵌入式工具链
arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.07) 10.3.1 20210621 (release)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
制作
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
VSC
Version: 1.73.1
Commit: 6261075646f055b99068d3688932416f2346dd3b
Date: 2022-11-09T02:22:48.959Z (1 wk ago)
Electron: 19.0.17
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Darwin arm64 22.1.0
Sandboxed: No
希望这是了解正在发生的事情所需的全部信息。 也许其中一个工具箱与我正在做的事情不兼容。 也许mpu6000Init()
function 在堆栈中的某处已损坏? 我试过在不同的芯片上运行,结果相同。 我试过注释掉 function 并且它顺利通过。 也许 SPI 和延迟导致了奇怪的计时问题。 任何帮助表示赞赏。 如果您需要任何澄清信息或希望我进行一些测试,请告诉我。
事实证明问题实际上来自Src/drv/drv_spi1.c
中的 function spi1WriteOneByte(uint8_t reg, uint8_t data)
。 我将变量命名为volatile uint8_t dummy __attribute((unused))
。 然后,此变量用作 DMA 传输的 memory 地址。 我认为这会导致某种问题,因为 DMA 要么无法到达该位置,要么导致了一些不稳定的行为。 无论如何,我将其更改为static
而不是volatile
并且它有效。 如果有人能比我更好地解释这一点,请做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.