Loading...
 
Skip to main content

System Workbench for STM32


Bootloader Erased when Application is programmed

There are a couple of threads that end with the poster saying that their bootloader is being erased when the applications is programmed. I hope that by starting a new post, we can get this issue resolved.

If I program the bootloader and run it, it works fine. When I program the application using the SystemWorkbench Run command it overwrites the bootloader with the elf file header information. Re-programming the bootloader again, and everything works fine.

If I have the debugger loaded, and I run the debugger, then everything works fine.

I did another experiment, I programmed the bootloader and using the ST-Link Utility I protected sectors 0 & 1. When I tried to program the application, I get an error that OpenOCD could not erase sectors 0 & 1 when the program clearly, according to the map file, starts in sector 2 (0x08008000).

This looks to me as an OpenOCD configuration problem, so I made some bootloader version of the OpenOCD configuration files and modified the base address of the flash bank command. No change.

I am out of ideas on how to fix this. Has anyone gotten this work?

Hi

If the command would be like

Copy to clipboard
openocd -f user.cfg -c "program filename.bin verify reset exit 0x08004000"


there would be no elf header.

Dieter


Dieter,

Great input. How do I configure the SystemWorkbench Run Configuration to generate that command to openocd? I want to be lazy and just click the run button.


If you change your linker configuration file (normally called LinkerScript.ld) to omit from the ROM memory section the portion of program space used by your bootloader, the ELF loader will not erase or overwrite those portions of the ROM/FLASH that have been excluded.

Here's what the MEMORY defintion inside LinkerScript.ld looks like by default for the STM32F091RC:
(128K FLASH, 32K RAM)

Copy to clipboard
MEMORY { RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K ROM (rx) : ORIGIN = 0x08000000, LENGTH = 128K }


The modified version below shows what you'd need to do if you wanted to reserve the first 32K of program FLASH space for a bootloader:

Copy to clipboard
MEMORY { RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K ROM (rx) : ORIGIN = 0x08008000, LENGTH = 96K }


Note how the ROM start address was increased by 0x8000 from 0x0800_0000 to 0x0800_8000, and the LENGTH reduced from 128K to 96K.

When you do a debug or run, or use the project explorer right-click context menu "Target" option to program your code when built using the modified MEMORY definition shown above, the first 32K of program FLASH should be left unchanged.

At the section level, it is possible to omit parts from being loaded/flashed by using the NOLOAD modifier in the section declaration in the linker config file. The example below shows what I did to allocate a 2K page of program FLASH for non-volatile parameter variable storage:

Copy to clipboard
MEMORY { RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K ROM (rx) : ORIGIN = 0x08000000, LENGTH = 126K P_FLASH (rw) : ORIGIN = 0x0801F800, LENGTH = 2K } . . . /* Non-volatile parameter data in FLASH Note - from GNU toolchain documentation: The (NOLOAD) directive will mark a section to not be loaded at run time. The linker will process the section normally, but will mark it so that a program loader will not load it into memory. */ .param_flash (NOLOAD) : { . = ALIGN(0x800); __param_flash_start = .; *(.param_flash) *(.param_flash*) . = ALIGN(4); __param_flash_end = .; } >P_FLASH


In the C source, you'd declare a variable to be located in this section like this:

Copy to clipboard
param_t param_flash __attribute__ ((section (".param_flash"),used));


I won't go into more detail on how to create NV variable storage here... there's more to it than what I've shown here. I bring it up only to demonstrate how one can use the NOLOAD section modifier to instruct the linker/loader to exclude otherwise ROMable sections from a program load.

I can not follow what you are telling us. The elf file is an image which contains information how to load the structure of the executeable to the location from where it gets executed.
Here we have the problem, that a flash programmer, openocd in this case, programs the elf header itself to flash memory. There is nothing wrong with the generation of the elf file.

The application is already relocated above the bootloader:

from STM32F103CBTx_FLASH.ld:

Copy to clipboard
MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K FLASH (rx) : ORIGIN = 0x8004000, LENGTH = 112K /* FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K */ }


from system_stm32f1xx.c:

Copy to clipboard
#define VECT_TAB_OFFSET 0x4000 //#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */


A look into the elf file:

Copy to clipboard
objdump -x /array_data01/STM32-34/mini-sys/Debug/mini-sys.elf /array_data01/STM32-34/mini-sys/Debug/mini-sys.elf: file format elf32-littlearm /array_data01/STM32-34/mini-sys/Debug/mini-sys.elf architecture: arm, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x0800da45 Program Header: LOAD off 0x00000000 vaddr 0x08000000 paddr 0x08000000 align 2**16 filesz 0x00012e88 memsz 0x00012e88 flags rwx LOAD off 0x00020000 vaddr 0x20000000 paddr 0x08012e88 align 2**16 filesz 0x000003f0 memsz 0x000024dc flags rw- LOAD off 0x000224dc vaddr 0x200024dc paddr 0x08013278 align 2**16 filesz 0x00000000 memsz 0x00000604 flags rw- private flags = 5000200: [Version5 EABI] [soft-float ABI] Sections: Idx Name Size VMA LMA File off Algn 0 .isr_vector 0000010c 08004000 08004000 00004000 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .text 0000c4a4 08004110 08004110 00004110 2**3 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .rodata 000028c0 080105b8 080105b8 000105b8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .ARM 00000008 08012e78 08012e78 00012e78 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .init_array 00000004 08012e80 08012e80 00012e80 2**2 CONTENTS, ALLOC, LOAD, DATA 5 .fini_array 00000004 08012e84 08012e84 00012e84 2**2 CONTENTS, ALLOC, LOAD, DATA 6 .data 000003f0 20000000 08012e88 00020000 2**2 CONTENTS, ALLOC, LOAD, DATA 7 .bss 000020ec 200003f0 08013278 000203f0 2**3 ALLOC 8 ._user_heap_stack 00000604 200024dc 08013278 000224dc 2**0 ALLOC 9 .ARM.attributes 0000002b 00000000 00000000 000203f0 2**0 CONTENTS, READONLY 10 .debug_info 0002281d 00000000 00000000 0002041b 2**0 CONTENTS, READONLY, DEBUGGING 11 .debug_abbrev 0000654b 00000000 00000000 00042c38 2**0 CONTENTS, READONLY, DEBUGGING 12 .debug_loc 0000ff9f 00000000 00000000 00049183 2**0 CONTENTS, READONLY, DEBUGGING 13 .debug_aranges 00001670 00000000 00000000 00059128 2**3 CONTENTS, READONLY, DEBUGGING 14 .debug_ranges 00001b80 00000000 00000000 0005a798 2**3 CONTENTS, READONLY, DEBUGGING 15 .debug_macro 00022e2f 00000000 00000000 0005c318 2**0 CONTENTS, READONLY, DEBUGGING 16 .debug_line 0001e9be 00000000 00000000 0007f147 2**0 CONTENTS, READONLY, DEBUGGING 17 .debug_str 000a08d6 00000000 00000000 0009db05 2**0 CONTENTS, READONLY, DEBUGGING 18 .comment 0000006e 00000000 00000000 0013e3db 2**0 CONTENTS, READONLY 19 .debug_frame 000049a8 00000000 00000000 0013e44c 2**2 CONTENTS, READONLY, DEBUGGING SYMBOL TABLE: 08004000 l d .isr_vector 00000000 .isr_vector ...

Hi

Finally found here a solution which works for me:
https://www.tablix.org/~avian/blog/archives/2012/11/gnu_linker_and_elf_program_header/

While in application project

Copy to clipboard
Goto Project -> Properties -> C/C++ Build -> Settings -> Tab "Tool Settings" -> MCU GCC Linker -> klick add symbol for "Other options (-XLinker [option]" -> write --nmagic


The objdump -x produces this output now:

Copy to clipboard
/array_data01/STM32-34/mini-sys/Debug/mini-sys.elf: file format elf32-littlearm /array_data01/STM32-34/mini-sys/Debug/mini-sys.elf architecture: arm, flags 0x00000012: EXEC_P, HAS_SYMS start address 0x0800fb61 Program Header: LOAD off 0x00000098 vaddr 0x08004000 paddr 0x08004000 align 2**3 filesz 0x000110d8 memsz 0x000110d8 flags rwx LOAD off 0x00011170 vaddr 0x20000000 paddr 0x080150d8 align 2**3 filesz 0x00000408 memsz 0x00002db8 flags rw- LOAD off 0x00011578 vaddr 0x20002db8 paddr 0x080154e0 align 2**0 filesz 0x00000000 memsz 0x00000600 flags rw- private flags = 5000200: [Version5 EABI] [soft-float ABI] Sections: Idx Name Size VMA LMA File off Algn 0 .isr_vector 0000010c 08004000 08004000 00000098 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .text 0000e5c8 08004110 08004110 000001a8 2**3 CONTENTS, ALLOC, LOAD, READONLY, CODE ...


Dieter


Dieter,

Thank you. Adding the -nmagic to the linker command works great!


 
Collapse/expand modules below