This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC812 bootloader

I'm using a lpc812 to make a bootloader.
The boot design is mapped 0x0000 to 0x1000 flash.
The application is mapped 0x1000 to 0x3FFC flash.

I program the application and boot with the Flash magic, but when jumping for the same application does not run.
I read the lpc812 with Flash magic, hex is correct in the mapped positions.

#define XBOOT_APP_ADDR          0x00001000
#define XBOOT_APP_SIZE          0x3000
#define XBOOT_APP_VERSION_ADDR  (XBOOT_APP_ADDR + XBOOT_APP_SIZE - 4)

void XBoot_RunApp(void) {
        XBootEntryPtr appEntry;
        appEntry = (XBootEntryPtr)*((uint32_t*)XBOOT_APP_ADDR);
        (appEntry)();
}

My application only flashes a led without interruption.

static const uint32_t AppVersion __attribute__((at(XBOOT_APP_VERSION_ADDR))) = 0x00000012;

int main(void) {
        SystemCoreClockUpdate();

        /* Matrix clock */
        LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 7);
        /* Reset pin */
        LPC_SWM->PINENABLE0 &= (1UL << 6);

        /* Led */
        LPC_GPIO_PORT->DIR0 |= (1UL << LED_PIN);
        LPC_GPIO_PORT->B0[LED_PIN] = LED_ON;

        //SysTick_Config((SystemCoreClock / 1000) - 1);

        while (1) {
                if (++LEDCount > 0xFFFF) {
                        LEDCount = 0;
                        if (LPC_GPIO_PORT->B0[LED_PIN] == LED_ON)
                                LPC_GPIO_PORT->B0[LED_PIN] = !LED_ON;
                        else
                                LPC_GPIO_PORT->B0[LED_PIN] = LED_ON;
                }
        }
}

Can anyone help me?

  • I managed to jump into the application!
    I had to make a function in asm:

                    AREA    |.text|, CODE, READONLY
                    EXPORT  XBoot_RunApp            [WEAK]
    
    XBoot_RunApp
                    LDR     R0, =0x1000
                    LDR     R0, [R0]
                    MOV     SP, R0
    
                    LDR     R0, =0x1004
                    LDR     R0, [R0]
                    MOV     PC, R0
    
                    END
    

    Now I can not map the NVIC application in RAM.
    SysTick_Handler does not work..

    #define XBOOT_APP_ADDR          0x00001000
    #define XBOOT_RAM_ADDR          0x10000000
    
    static void App_ReAllocateNVIC(void) {
            uint32_t *src, *dst;
            uint32_t size;
    
            __disable_irq();
            src = (uint32_t*)XBOOT_APP_ADDR;
            dst = (uint32_t*)XBOOT_RAM_ADDR;
            size = 0xC0;
            while (size > 0) {
                    *dst++ = *src++;
                    size -= 4;
            }
            LPC_SYSCON->SYSMEMREMAP = 0x1;
            __enable_irq();
    }
    

  • You could also have just called the PC vector in your original C code instead of loading the SP and trying to jump to that.

    Do you have a debugger? Can you step through the transition?

    Make sure you've carved out space in the IRAM definitions to ensure your vector copy doesn't interfere with other variables placed in RAM.

  • I do not have debugger..

    Project RAM definitions:
    [IRAM1] nodefault start 0x10000000 size 0xC0 noinit
    [IRAM2] default start 0x100000C1 size 0xF3C init
    Variables in IRAM2..

    After calling ReAllocateNVIC() the application stops working..

  • Probably would help here, consider investing in the appropriate tools.

    Don't define the 0x10000000..0x100000BF region at all, just define IRAM1 as 0x100000C0..0x10000FFF [Size 0xF40]. The Linker has NO interest in the vector region. Make sure the REMAP code does what it's supposed too, and that ALL active interrupts have defined/functional service routines. Ideally your boot loader shouldn't have left any enabled once it leaves.

  • In LPC812 could not do the remap.
    The same routine for LPC11e13 worked!

    Calling the boot for the app only worked on ASM using SP and PC, the function below will not work.

    void XBoot_RunApp(void) {
            XBootEntryPtr appEntry;
            appEntry = (XBootEntryPtr)*((uint32_t*)XBOOT_APP_ADDR + 4);
            (appEntry)();
    }
    

  • What about

    void XBoot_RunApp(void) {
            XBootEntryPtr appEntry;
            appEntry = (XBootEntryPtr)*((uint32_t*)(XBOOT_APP_ADDR + 4));
            (appEntry)();
    }
    

    Print out the value ascribed to addEntry and confirm it is that of your ResetHandler.

    Life would be much easier if you could use a debugger instead of using valueless terms like "doesn't work" or "will not work". Inspect WHAT is going on, determine WHY it is happening.

  • I found a JTAG!
    The value of appEntry == 0x1004..
    When I call (appEntry)() is generated HardFault_Handler()..