Compiling application to run not from the start of the flash stm32L4R9I - linker

I have an steval-stwinkt1 board, that i am trying to enable support for DFU mode.
I flashed costume boot loader firmware on to the the start of the flash (0x8000000) that lets you load into another firmware that was uploaded by the DFU mode or to stay in the current program to flash new firmware throw the USB.
i used this st tutorial- https://www.youtube.com/watch?v=n_LDXOQHerU
I tried the .dfu package that comes with the STM32Cube and i saw that the program ran successfully so i assume that the bootloader works.
but when i try to make my own DFU package from my software the software never loads and i get hard fault. i moved the software according to the ST totorial & some research i done to 0x800C000 by changin the following lines:
in the FLASH.ld file:
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
to:
FLASH (rx) : ORIGIN = 0x800C000, LENGTH = 2048K
and in the stm32l4r9xx.h changed FLASH_BASE to:
#define FLASH_BASE (0x0800C000UL)
on another try i tried instead of changing FLASH_BASE to change VECT_TAB_OFFSET but it still didnt work.
to make the dfu package i use dfu-tool (i use linux) and use this command:
dfu-tool convert dfuse software.bin software.dfu
also tried to convert the hex int dfu package using the official tool that is used in the tutorial i used and still didnt work
what do i need to change to make my software works when i load the dfu package?
thanks
itay

It appears to me that you have overlooked the fact that your application-dedicated flash size is not going to be 2048K anymore, since your custom bootloader is now placed at the start of the flash. Therefore, you need to subtract the app's flash origin from the total flash size:
FLASH (rx) : ORIGIN = 0x800C000, LENGTH = 2048K - (ORIGIN(FLASH) - 0x8000000)
In such cases, a suggestion would be to try to debug the hard fault using the HardFault_Handler() and a bit of coding. You will then be able to extract and analyze the link register, program counter, program status register, etc. at the moment when hard fault occurred.

Related

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. i.e 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.

How to pass data from u-boot bootloader to QNX application via ram?

Using QNX 6.5.x with u-boot as a bootloader, on an ATSAMA5d3x module.
We'd like to pass some amount of data, ~1.5kb, from the bootloader into QNX via RAM, rather than trying to pass it via flash storage.
Is there a mechanism to tell QNX to reserve an area of RAM and not touch it? This would let us mmap it from the QNX application to read the data out of it, without QNX using it for heap or otherwise zeroing it out.
Is there another approach you've used to pass data like this into QNX?
QNX startup-* programs permit the use of the -r argument to reserve a block of phyiscal address space. You can supply arguments to startup in the .build file for the bootstrap image (the source to mkifs).
Example:
[image=0x22000000]
[virtual=armle-v7,raw +compress] .bootstrap = {
# reserve 4k at paddr 0x20000000 and don't clear it
startup-atsama5d3x-ek -vvv -r 0x20000000,4096,1
# reset of boot code goes here
}
[+script] .script = {
# and so on
}
# and so forth
Ref: http://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.utilities/topic/s/startup_options.html
I try using qnx 6.5.0 on ATSAMA5d3x
I use default nand driver from bsp, but periodically(when try open some bin file) i get this error:
fs-etfs-sama5d3x: readcluster DATAERR on cluster xxxxxx
after reset all ok, i can run binary, but after a while this error will appear again
Why is this happening? You use default driver?
Maybe you know something
*Forgive me for asking in your question, too little information on qnx 6.5.0 on ATSAMA5d3x
enter image description here

Can I easily compile u-boot with more commands for arm versatile bp

I have compiled u-boot from u-boot-2013.01.y branch for versatilebp board (arm), and I need fatload command that is not present in this configuation.
I'm running u-boot under qemu
DRAM: 128 MiB
WARNING: Caches not enabled
Using default environment
In: serial
Out: serial
Err: serial
Net: SMC91111-0
Warning: SMC91111-0 using MAC address from net device
VersatilePB # fat
Unknown command 'fat' - try 'help'
VersatilePB # help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
cmp - memory compare
cp - memory copy
crc32 - checksum calculation
dhcp - boot image via network using DHCP/TFTP protocol
env - environment handling commands
erase - erase FLASH memory
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print command description/usage
iminfo - print header information for application image
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
mtest - simple RAM read/write test
mw - memory write (fill)
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
setenv - set environment variables
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version
VersatilePB #
I need fatload to load file containing image of fat filesystem containing kernel of freebsd. Can I somehow change compile config for that board to compile u-boot with fatload command? Or it's just not possible/not supported for that board?
Having done more or less exactly this for a Versatile AB, it's most certainly possible. The simplest way is to find where that board's command set is defined, and hack in the commands you want by defining the relevant CONFIG_CMD_* symbols. In this case, that place is include/configs/versatile.h.
Looking at my checkout of 2015.07, I seem to have added, among others (I think I was trying to convince the MMC to work at the time), these lines:
#define CONFIG_CMD_FAT
#define CONFIG_DOS_PARTITION 1

How to recover from infinite reboot loops in NodeMCU?

My NodeMCU program has gone in to infinite reboot loop.
My code is functionally working but any action I try to do, e.g. file.remove("init.lua") or even just =node.heap(), it panics and reboots saying: PANIC: unprotected error in call to Lua API (not enough memory).
Because of this, I'm not able to change any code or delete init.lua to stop automatic code execution.
How do I recover?
I tried re-flashing another version of NodeMCU, but it started emitting garbage in serial port.
Then, I recalled that NodeMCU had two extra files: blank.bin and esp_init_data_default.bin.
I flashed them at 0x7E000 and 0x7C000 respectively.
They are also available as INTERNAL://BLANK and INTERNAL://DEFAULT in the NodeMCU flasher.
This booted the new NodeMCU firmware, all my files were gone and I'm out of infinite reboot loop.
Flash the following files:
0x00000.bin to 0x00000
0x10000.bin to 0x10000
And, the address for esp_init_data_default.bin depends on the size of your module's flash.
0x7c000 for 512 kB, modules like ESP-01, -03, -07 etc.
0xfc000 for 1 MB, modules like ESP8285, PSF-A85
0x1fc000 for 2 MB
0x3fc000 for 4 MB, modules like ESP-12E, NodeMCU devkit 1.0, WeMos D1 mini
Then, after flashing those binaries format its file system (run "file.format()" using ESPlorer) before flashing any other binaries.
Downloads Link
I've just finished working through a similar problem. In my case it was end-user error that caused a need to forcibly wipe init.lua, but I think both problems could be solved similarly. (For completeness, my problem was putting a far-too-short dsleep() call in init.lua, leaving the board resetting itself immediately upon starting init.lua.)
I tried flashing new NodeMCU firmware, writing blank.bin and esp_init_data_default.bin to 0x7E000 and 0x7C000, and also writing 0x00000.bin to 0x00000 and 0x10000.bin to 0x10000. None of these things helped in my case.
My hardware is an Adafruit Huzzah ESP8266 breakout (ESP-12), with 4MB of flash.
What worked for me was:
Download the NONOS SDK from Espressif (I used version 1.5.2 from http://bbs.espressif.com/viewtopic.php?f=46&t=1702).
Unzip it to get at boot_v1.2.bin, user1.1024.new.2.bin, blank.bin, and esp_init_data_default.bin (under bin/ and bin/at/).
Flash the following files to the specified memory locations:
boot_v1.2.bin to 0x00000
user1.1024.new.2.bin to 0x010000
esp_init_data_default.bin to 0xfc000
blank.bin to 0x7e000
Note about flashing:
I used esptool.py 1.2.1.
Because of the nature of my problem, I was only able to write changes to the flash when in programming mode (i.e. after booting with GPIO0 held down to GND).
I found that I needed to reset the board between each step (else invocations of esptool.py after the first would fail).
Erased the flash. esptool.py --port <your/port> erase_flash
Then I was able to write a new firmware. I used a stock nodeMCU 0.9.5 just to isolate variables, but I strongly suspect any firmware would work at this point.
The only think that worked for me was python flash tool esptool in ubuntu, windows flashtool never deleted init.lua and reboot loop.
Commands (ubuntu):
git clone https://github.com/themadinventor/esptool.git
cd esptool
python esptool.py -h
ls -l /dev/tty*
nodemcu_latest.bin can be downloaded from github or anywhere.
sudo python esptool.py -p /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m 0 nodemcu_latest.bin

STM32F2 removal of readout protection

The STM32F2 micro-controller has build in capabilities to prevent readout of application code using a debug interface. It works fine and is accomplished pretty easily by configuring the read protection(RDP) level to '1' (!0xAA || !0xCC) or '2' (0xCC which is irreversible). Except trying to turn it off is where i run in to issues.
The expected behavior when the RDP level is lowered back to 0:
The chip will perform a mass flash erase.
Followed by clearing the protection flag.
System reset
Except after a power cycle the flash has been successfully erased but the protection flag remains on level '1' (0x55) keeping the debug interface disabled. And thus preventing me from writing any new application code. It is possible to fiddle around with the debugger and force the flag to level 0 (0xAA) manually though..
Is there anyone who have had the same or similar issues with the STM32F2xx series that can help me out? I'm using the STM32 standard peripheral drivers for programming the flash.
Enable
// Enable read out protection
FLASH_OB_Unlock();
FLASH_OB_RDPConfig(OB_RDP_Level_1);
FLASH_OB_Launch();
FLASH_OB_Lock();
// Restart platform
NVIC_SystemReset();
Disable
// Disable read out protection
FLASH_OB_Unlock();
FLASH_OB_RDPConfig(OB_RDP_Level_0);
FLASH_OB_Launch();
FLASH_OB_Lock();
// Restart platform
NVIC_SystemReset();
This is because before the clearing the protection flag, and in the middle of mass flash erase, you restart the chip.
The only way to recover the chip is to use the system bootloader.
Force boot0 pin to be 1 and force boot1 pin to be 0 at power up, start bootloader then connect USB and program the chip with DFU programmer.
You can download the DFU programmer here.
I used the library as follows (it was not working without FLASH_Unlock();):
// Flash Readout Protection Level 1
if (FLASH_OB_GetRDP() != SET) {
FLASH_Unlock(); // this line is critical!
FLASH_OB_Unlock();
FLASH_OB_RDPConfig(OB_RDP_Level_1);
FLASH_OB_Launch(); // Option Bytes programming
FLASH_OB_Lock();
FLASH_Lock();
}
No need for NVIC_SystemReset();.
Checking functionality worked best with STM32 ST-LINK utility CLI for me:
> "C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ST-LINK_CLI.exe" -c SWD -rOB
STM32 ST-LINK CLI v3.0.0.0
STM32 ST-LINK Command Line Interface
ST-LINK SN : 51FF6D064989525019422287
ST-LINK Firmware version : V2J27S0
Connected via SWD.
SWD Frequency = 4000K.
Target voltage = 2.9 V.
Connection mode : Normal.
Device ID:0x422
Device flash Size : 256 Kbytes
Device family :STM32F302xB-xC/F303xB-xC/F358xx
Option bytes:
RDP : Level 1
IWDG_SW : 1
nRST_STOP : 1
nRST_STDBY : 1
nBoot1 : 1
VDDA : 1
Data0 : 0xFF
Data1 : 0xFF
nSRAM_Parity: 1
WRP : 0xFFFFFFFF
Not really a solution, but I hope this saves someone some time.

Resources