Atmel SAM4E Bootloader/VTOR executing new application

I've written a boot loader for the Atmel SAM4E device which is working to a point, it can receive new application code via SPI, erase flash and write to flash, but I don't understand how to execute the new application. I've learned the VTOR can be relocated, but I'm not sure how. (my application sits at address 0x00420000).
I'm very new to writing code for ARM, so I'd appreciate any help.

Many thanks

Paul

Parents
  • binary_exec((void*) 0x00420000);

    int binary_exec(void * vStart){
    int i;

    // -- Check parameters
    // Should be at least 32 words aligned
    if ((uint32_t)vStart & 0x7F) return 1;

    wdt_disable(WDT);

    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();

    __set_MSP(vStart);

    // 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"
    );
    }

Reply
  • binary_exec((void*) 0x00420000);

    int binary_exec(void * vStart){
    int i;

    // -- Check parameters
    // Should be at least 32 words aligned
    if ((uint32_t)vStart & 0x7F) return 1;

    wdt_disable(WDT);

    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();

    __set_MSP(vStart);

    // 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"
    );
    }

Children
No data