Question
Costum Bootloader gives hard fault when deleting main program
Posted on January 26, 2013 at 09:50
Hi :)
I have a problem which I have been trying to solve my self for the last weeks. I am building a custom bootloader which has to work over CAN bus. Bootloader is located at 0x0800000 to 0x08002000 and all function that are used in the bootloader have been declared in this memory area. Upon startup, the bootloader executes and then calls a second main2 function where the main program (which will be deleted and replaced) is located. All this works at startup, I can enter the bootloader and execute the program. So far so good. Now, if the bootloader deletes the flash from 0x08002000 to 0x08010000 then I can verify that this has been deleted ok and that the bootloader itself has not been changed, but when I reset the processor I immediately get a hardfault. It happens before entering the bootloader, so must be in the startup code, but I have not had success to see where. Did I forget to place other parts of the code in the bootloader section? I am using crossworks and my flash_placement file looks like this:<!DOCTYPE Linker_Placement_File>
<
Root
name
=
''Flash Section Placement''
>
<
MemorySegment
name
=
''$(FLASH_NAME:BOOTLOADER)''
>
<
ProgramSection
alignment
=
''0x100''
load
=
''Yes''
name
=
''.vectors''
start
=
''$(BOOTLOADER_START:)''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.init''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.text3''
/>
<
ProgramSection
alignment
=
''4''
start
=
''0x08001FF0''
size
=
''0x0010''
load
=
''Yes''
inputsections
=
''KEEP (*(.VersionNumBootloader .VersionNumBootloader.*))''
name
=
''.VersionNumBootloader''
/>
</
MemorySegment
>
<
MemorySegment
name
=
''$(FLASH_NAME:FLASH)''
>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
inputsections
=
''KEEP (*(.VersionNum .VersionNum.*))''
name
=
''.VersionNum''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.text''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.dtors''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.ctors''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.rodata''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.ARM.exidx''
address_symbol
=
''__exidx_start''
end_symbol
=
''__exidx_end''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
runin
=
''.fast_run''
name
=
''.fast''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
runin
=
''.data_run''
name
=
''.data''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
runin
=
''.tdata_run''
name
=
''.tdata''
/>
</
MemorySegment
>
<
MemorySegment
name
=
''$(RAM_NAME:RAM);SRAM''
>
<
ProgramSection
alignment
=
''0x100''
load
=
''No''
name
=
''.vectors_ram''
start
=
''$(RAM_START:$(SRAM_START:))''
/>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.fast_run''
/>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.data_run''
/>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.bss''
/>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.non_init''
/>
<
ProgramSection
alignment
=
''4''
size
=
''__HEAPSIZE__''
load
=
''No''
name
=
''.heap''
/>
<
ProgramSection
alignment
=
''4''
size
=
''__STACKSIZE__''
load
=
''No''
name
=
''.stack''
/>
<
ProgramSection
alignment
=
''4''
size
=
''__STACKSIZE_PROCESS__''
load
=
''No''
name
=
''.stack_process''
/>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.tbss''
/>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.tdata_run''
/>
</
MemorySegment
>
<
MemorySegment
name
=
''$(FLASH2_NAME:FLASH2)''
>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.text2''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
name
=
''.rodata2''
/>
<
ProgramSection
alignment
=
''4''
load
=
''Yes''
runin
=
''.data2_run''
name
=
''.data2''
/>
</
MemorySegment
>
<
MemorySegment
name
=
''$(RAM2_NAME:RAM2)''
>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.data2_run''
/>
<
ProgramSection
alignment
=
''4''
load
=
''No''
name
=
''.bss2''
/>
</
MemorySegment
>
</
Root
>
This is part of my map file:
Name Origin Length Attributes
UNPLACED_SECTIONS 0xffffffff 0x00000000 xw
BOOTLOADER 0x08000000 0x00002000 xr
FLASH 0x08002000 0x0000e000 xr
RAM 0x20000000 0x00005000 xw
USB_CAN_RAM 0x40006000 0x00000200 xw
CM3_System_Control_Space 0xe000e000 0x00001000 xw
*default* 0x00000000 0xffffffff
Linker script and memory map
0x0800845c __do_debug_operation = __do_debug_operation_mempoll
0x08008024 __vfprintf = __vfprintf_int_nwp
0x08000000 __BOOTLOADER_segment_start__ = 0x8000000
0x08002000 __BOOTLOADER_segment_end__ = 0x8002000
0x08002000 __FLASH_segment_start__ = 0x8002000
0x08010000 __FLASH_segment_end__ = 0x8010000
0x20000000 __RAM_segment_start__ = 0x20000000
0x20005000 __RAM_segment_end__ = 0x20005000
0x40006000 __USB_CAN_RAM_segment_start__ = 0x40006000
0x40006200 __USB_CAN_RAM_segment_end__ = 0x40006200
0xe000e000 __CM3_System_Control_Space_segment_start__ = 0xe000e000
0xe000f000 __CM3_System_Control_Space_segment_end__ = 0xe000f000
0x00000100 __STACKSIZE__ = 0x100
0x00000000 __STACKSIZE_PROCESS__ = 0x0
0x00000000 __STACKSIZE_IRQ__ = 0x0
0x00000000 __STACKSIZE_FIQ__ = 0x0
0x00000000 __STACKSIZE_SVC__ = 0x0
0x00000000 __STACKSIZE_ABT__ = 0x0
0x00000000 __STACKSIZE_UND__ = 0x0
0x00000080 __HEAPSIZE__ = 0x80
0x20000000 __vectors_ram_load_start__ = ALIGN (__RAM_segment_start__, 0x100)
.vectors_ram 0x20000000 0x0
0x20000000 __vectors_ram_start__ = .
*(.vectors_ram .vectors_ram.*)
0x20000000 __vectors_ram_end__ = (__vectors_ram_start__ + SIZEOF (.vectors_ram))
0x20000000 __vectors_ram_load_end__ = __vectors_ram_end__
0x00000001 . = ASSERT (((__vectors_ram_end__ >= __RAM_segment_start__) && (__vectors_ram_end__ <= __RAM_segment_end__)), error: .vectors_ram is too large to fit in RAM memory segment)
0x08002000 __VersionNum_load_start__ = ALIGN (__FLASH_segment_start__, 0x4)
.VersionNum 0x08002000 0x10
0x08002000 __VersionNum_start__ = .
*(.VersionNum .VersionNum.*)
.VersionNum 0x08002000 0x10 THUMB Release/main.o
0x08002000 Program_Consts
0x08002010 __VersionNum_end__ = (__VersionNum_start__ + SIZEOF (.VersionNum))
0x08002010 __VersionNum_load_end__ = __VersionNum_end__
0x00000001 . = ASSERT (((__VersionNum_end__ >= __FLASH_segment_start__) && (__VersionNum_end__ <= __FLASH_segment_end__)), error: .VersionNum is too large to fit in FLASH memory segment)
0x08002010 __text_load_start__ = ALIGN (__VersionNum_end__, 0x4)
.text 0x08002010 0x64e8
0x08002010 __text_start__ = .
*(.text .text.* .glue_7t .glue_7 .gnu.linkonce.t.* .gcc_except_table .ARM.extab* .gnu.linkonce.armextab.*)
.glue_7 0x00000000 0x0 linker stubs
.glue_7t 0x00000000 0x0 linker stubs
I'm not really an expert in map files and the memory placement files, and this is my first bootloader.
This is how the startup works.
int main(void) //Enter Bootloader
{
InitBootloaderHardware_BL();
uint32_t res = 0,res1 = 0;
// Check if a newer image on SPI flash is available.
res = CheckSPIFlashImages_BL(GetSPIFlashImagesProgramversion);
if( Program_Consts.ProgramVersion < res )
{
//Check if SPI FLASH image is intact
res = CheckSPIFlashImages_BL(CalculateSPIFlashImagesProgramCRC);
//Compare SPI FLASH CRC value with calculated value
res1 = CheckSPIFlashImages_BL(GetSPIFlashImagesProgramCRC);
if( res == res1 )
{
EraseFlashCopyDataFromSPIFlashProgramFlash_BL();
}
}
else
{
main2(); //Main program
}
}
Any help would be very much appreciated.
Thank you in advance.
Jacob
#bootloader-flash_placement.xml