Sorry, forgot to say that of course, VTOR is updated by the bootloader
prior to jumping into the OS.
BOOTCODE __attribute__((naked, noreturn)) void __boot_app(void)
{
__asm__ __volatile__ ("\t"
/* load SP (from 08004000) */
"movw r0, #0x4000 \n\t"
"movt r0, #0x0800 \n\t"
"ldr sp, [r0] \n\t"
/* load LR (from 08004004) */
"movw r0, #0x4004 \n\t"
"movt r0, #0x0800 \n\t"
"ldr r0, [r0] \n\t"
"mov lr, r0 \n\t"
/* setup VTOR (at E000ED08) to remap vectors*/
"movw r0, #0xED08 /*adr lo*/ \n\t"
"movt r0, #0xE000 /*adr hi*/ \n\t"
"movw r1, #0x4000 /*val lo*/ \n\t"
"movt r1, #0x0800 /*val hi*/ \n\t"
"str r1, [r0] /*store value at address*/ \n\t"
"bx lr /*take the jump*/ \n"
);
}
Le 22/04/2021 à 09:59, Sebastien Lorquet a écrit :
Hello
I did that and it works in a consumer product with a stm32 since,
well, 2018 I think. Also in an open source product.
my board uses a custom linker script that locates the start of the
flash a bit farther than the usual start (one stm32 block or 16k IIRC)
. Then I compile nuttx as usual.
The bootloader happens to be built by the same process, and all the
bootloader code goes into a separate named text section and memory
zone. It could be built separately but this is convenient. Only
problem is I cant use inline strings for debug because I could not
find how to control the section these litteral strings are affected
to. So I use global const arrays. ugly but it does the job.
when the boards are manufactured the whole HEX file is flashed, which
includes BOTH the bootloader and the initial OS.
After that the board can be updated "over the air".
A python scripts extract the "OS image" from the ELF file and wrap it
appropriately, then an update file is built.
Our NuttX then includes some applicative code to retrieve and validate
this update file.
The contents are written to SPI flash (via a char driver wrapper to
MTD devices to bypass the nuttx FTL)
The board reboots
the bootloader code detects the update in the SPI flash and writes the
contents to the STM32 flash.
once complete and verified, the SPI contents is disabled. Else the
bootloader can restart the process. We could have emergency serial
code to upload an image from the bootloader, but we never had to, this
process works fine, we never had bricked boards.
This method prevents updating the bootloader.
So we can ship special OS updates that includes an updated bootloader
as a static const.
The nuttx board start code is then able to update the bootloader. We
rarely use this feature, only once IIRC.
In our case, the bootloader has to disable the SPI peripheral before
booting the OS, else NuttX will find it initialized and will not
initialize it correctly.
Our system is rather complex but is also quite failsafe.
Sebastien
Le 21/04/2021 à 20:54, Flavio Castro Alves Filho a écrit :
Hello,
I intend to use a NuttX firmware with a custom bootloader on a
STM32F4DISCOVERY board.
The bootloader will be executed on the first available memory block in
flash, and the firmware will start from the second block - position
0x08020000.
I believe I know what to do regarding linker script.
But I don't know if there is anything to be done directly in NuttX
source code.
I ask this because in a standard STM32 firmware using STM32Cube, there
is a FLASH_BASE constant that must be set correctly for the firmware
to work correctly. My worry is if there is something similar in NuttX
for the board.
Best regards,
Flavio