[En-Nut-Discussion] STM32: Problems running code with an offset in flash (bootloader)

Ole Reinhardt ole.reinhardt at embedded-it.de
Wed Mar 2 23:53:49 CET 2016


Hi all,

has anyone just compiled a program for STM32 that is not linked to the
beginning of the flash?

I need to link my program to a start address of 0x0800c000, as my system
runs a bootloader, that expects its application code at this address.

CPU:     STM32F411CE

To do so, I added a local linker script that defienes a
bootloader_offset of 0xC000 and includes stm32f10x_flash.ld:


----------------------------
ENTRY(NutInit)
SEARCH_DIR(.)

"bootloader_offset" = 0xC000;

MEMORY
{
    FLASH0 (rx) : ORIGIN = 0x08000000, LENGTH = 512K
    SRAM0 (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}

INCLUDE stm32f10x_flash.ld
----------------------------


Further I added

    .bootloader (NOLOAD):
    {
	. = bootloader_offset;
    } > FLASH0

Right at the top of stm32f10x_flash.ld (similar to stm32f10x_ram.ld)


The application is started correctly and I can output some debug
messages using the DebugPut() routine (Debug Macro). I also can register
the UART driver and output a few bytes using printf().

So far everything looks fine, but as soon as the programs gets a little
more complex it hangs / crashes. Unfortunately I don't have a JTAG
connected, so I can not evaluate any register contents.

Neither a call to NutSleep() nor to NutGetMillis() returns, but on the
other hand NutThreadYield works without any problems.

For example I can create two threads both printing characters with
DebugPut and then calling NutThreadYield. That works as expected, but as
soon as I call NutSleep() the program hangs / crashes.

I also can not print longer strings using printf(). Again the program
gets stuck, while when adding a few DebugPut() calls between several
printf() calls, the output is printed as expected.


I have the strong feeling, that the interrupt handling won't work
anymore when not linking to the flash base address (0x08000000).

a) the timer interrupt is needed for NutSleep()
b) the UART driver prints out data using an interrupt. When calling
DebugPut() in between, this routine does not wait for an interrupt, but
polls the UART status register to wait for the FIFO to get empty again.

b also explains, why printing short text using printf() works, but
longer text outputs get stuck. A longer text needs interrupt interaction
while a shorter text fits into the UART FIFO.


Does anyone of you have an idea what could cause such a behaviour?

How could the behaviour be related to either the offset where the code
is linked to or to any settings that the bootloader configures?

I'm wondering if the bootloader could have disabled all interrupts and
the STM32 startup code does not re-enable them?

I'm a little out of good ideas...


Btw: The hardware is a WifiMCU board http://www.wifimcu.com/

Best regards,

Ole Reinhardt


-- 
kernel concepts GmbH            Tel: +49-271-771091-14
Sieghuetter Hauptweg 48         Mob: +49-177-7420433
D-57072 Siegen
http://www.embedded-it.de
http://www.kernelconcepts.de


More information about the En-Nut-Discussion mailing list