AnsweredAssumed Answered

Costum Bootloader gives hard fault when deleting main program

Question asked by lillie.jacob on Jan 26, 2013
Latest reply on Feb 3, 2013 by Clive One
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

Outcomes