简体   繁体   中英

STM32F722 Hard Fault / Flash / Linker Script Issues

I'm going to try and describe this as best as possible and go through everything I tried to resolve it but I'm not sure I'll be able to capture it all since I've been getting some bizarre behavior. I will start by saying this this issue does not occur at all using STM32CubeIDE. It has only started since I've been using VSCode for STM32 which uses Makefiles, OpenOCD, and GDB. Obviously I could easily go back to CubeIDE, but I would like to make things work with VSC since it's a nicer interface. I also use a Mac and am running MacOS 13.0 Ventura. All my tools were installed with Homebrew.

This problem first came about when I noticed my code would get go into a Hardfault Handler when trying to run a function that would initialize the MPU-6000 acc/gyro, mpu6000Init() . There's nothing special about this function. It sends a sends a bunch of data over SPI to the IMU to initialize some settings with a delay between the sends. EVEN weirder is that when I step through the code line by line, it works just fine. ie if I put a breakpoint at the beginning of the function and run line by line, there's no issue. I don't really know what that means. When I check the Call Stack, it seems to be coming from the delay function but I'm not sure why since I use the delay function earlier without a problem.

All my code exists here . The important files are Src/main.c , Src/drv/drv_system.c , Src/sensors/mpu6000.c .

I do know that one of the things that may be causing this problem is that I have edited my linker script to have a "virtual eeprom" where I section off a portion of the flash so I have some non-volatile memory where I can save settings etc when I turn it off. When I reflash code, my whole EEPROM gets erased and I have to reflash settings. Is this possible to avoid using the linker script? This looks something like this:

/* 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

Then at the top of main.c I have this const uint8_t __attribute__((__section__(".eeprom"), used)) eepromArray[131072]; Reminder that all of this works with the CubeIDE. It's just with the tools I use with VSC that it doesn't work.

When I run this code in the STM32CubeProgrammer, I used the hardfault detector which got me this硬故障对话框

Another thing of note: when I run the code, the "Output" window reads this:

 *  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. 

One line that concerns me is Info: Flash write discontinued at 0x08008358, next section at 0x08060000 . I honestly don't know exactly what it means but I assume something weird is happening with the way the flash is being written. I tried looking this issue up but didn't find anything useful.

Versions of the tools I'm using:

OpenOCD

Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html

Arm Embedded Toolchain

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.

Make

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

Hopefully this is all the info needed to get a picture of what's going on. Maybe one of the toolboxes just isn't compatible with what I'm doing. Maybe the mpu6000Init() function is somewhere on the stack that is corrupted? I have tried running on different chips with the same results. I have tried commenting out that function and it moves through alright. Maybe there's something with SPI and the delays causing a weird timing issue. Any help is appreciated. Let me know if you need any clarifying info or want me to run some tests.

Turns out the issue actually comes from the function spi1WriteOneByte(uint8_t reg, uint8_t data) in Src/drv/drv_spi1.c . I name a variable volatile uint8_t dummy __attribute((unused)) . This variable was then used as the memory address for the DMA transfer. I assume this was causing some sort of issue because the DMA either can't reach that location or it was causing some wonky behavior. Anyways, I changed it to static instead of volatile and it works. If someone can explain this better than I can, please do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM