1

I am using a Atmel SAM4E-16e on Atmel SAM4E-EK Board. I have written a bootloader for this configuration. The bootloader receives the .bin-File via UART and writes it into Flash. This works without problems, i made a hex-dump and it was exactly what i expected:

  • Bootloader at 0x400000 (Flash Start Address of AT SAM4E)
  • My Application at 0x420000
  • 0x800000 is Flash End Address

This is the C-Code:

int main(void){
     // Init and downloading the .bin to Flash
     binary_exc((void*) 0x420000);
}



int binary_exec(void * vStart){
    int i;
    // -- Check parameters
    // Should be at least 32 words aligned
    if ((uint32_t)vStart & 0x7F)
    return 1;

    Disable_global_interrupt();
    // Disable IRQs
    for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF;
    // Clear pending IRQs
    for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF;

    // -- Modify vector table location
    // Barriars
    __DSB();
    __ISB();
    // Change the vector table
    SCB->VTOR = ((uint32_t)vStart & SCB_VTOR_TBLOFF_Msk);
    // Barriars
    __DSB();
    __ISB();

    Enable_global_interrupt();

    // -- Load Stack & PC
    _binExec(vStart);
    return 0;
}

void _binExec (void * l_code_addr){
    __asm__ ("mov   r1, r0        \n"
    "ldr   r0, [r1, #4]  \n" //I also tryed #5 but that doesn't work, too
    "ldr   sp, [r1]      \n"
    "blx   r0"
    );
}

But when i try to jump to my application, the Application does not start. The code for jumping to the program is out of an example of Atmel for the SAM8X (Cortex M3). The debugger says sometimes that it the PC jumps to another Address (0x004003E2) instead, but does not go on.

I found the old topic Bootloader for Cortex M3 where the solution was to just add one but this doesn't work for me, even if i used their code. Then the debugger does not responds any more.

I am using Atmel Studio 7 with GCC. The processor runs in Thumb-Mode.

I hope you can help me to solve this problem or give me some tipps what is going wrong here.

Community
  • 1
  • 1
Alex S.
  • 31
  • 1
  • 6
  • 1
    You certainly do need to set the lsb of the the register you `blx` to, or you'll attempt to interwork to non-existent ARM state and hard fault. Which address did you try adding one to (i.e. at what exact point in this code) that made things worse? – Notlikethat May 02 '16 at 13:43
  • if your code is at 0x420000 then you want to blx to 0x420001, so why are you reading the instruction at address 0x420000 and then trying to branch to the address defined by the instruction? why not orr r0,#1; blx r0? what does your disassembly show of what address enters binary_exec? and why all the overhead in binary_exec? are you trying to handle any case, was there code running before that put the system in an unknown state? – old_timer May 02 '16 at 13:55
  • you could do the or of 1 in the C call to _binExec then bin exec is nothing more than blx r0. of course if that code returns it returns to after the blx which is probably not what you want. – old_timer May 02 '16 at 13:57
  • My new Application is at 0x420000 but I need to jump to 0x420004 because the Reset vector is at this address. This is in the assembler Code. There I also tried to jump to 0x420005 because that was the solution for http://stackoverflow.com/questions/12715556/bootloader-for-cortex-m3 – Alex S. May 02 '16 at 14:43

2 Answers2

2

This code assumes that program loaded at address 0x420000 starts with a vector table:

  • SP at offset 0 (0x420000)
  • Reset address at offset 4 (0x420004).

For this, the code seems perfectly correct.

But are you sure that this vector table is correct ? Is bit 0 of data at 0x420004 set as this is Thumb code? When you compile this code, is it aware that it will run from this address (For any absolute address it might use). Do you have the possibility to use a debugger to understand when the first fault occurs?

I think you should provide the disass of the first instructions of the program you try to load at this address.

Dric512
  • 3,525
  • 1
  • 20
  • 27
2

I have solved the problem now. I still use the code I posted in my question. The problem was that the .bin-file i write on my processor's flash at 0x420000 was compiled in a way that it thought it is at flash start address (0x400000). When it has loaded the reset vector's address it was at 0x400xyz instead of 0x420xyz so the application jumped to the wrong address.

The solution was to Change the Flash start address to 0x420000 in the project I want to upload via bootloader.

nonsensickle
  • 4,438
  • 2
  • 34
  • 61
Alex S.
  • 31
  • 1
  • 6