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

problems with secondary bootloader on LPC1768 with MCP1700

I'm using µVision 4.50.0.0 with Keil MCB1700 with LPC1768.

I wrote a secondary boot-loader, that reads srecord file from usb and writes that into flash starting 0x20000.
The AN10866.pdf from NXP helped a lot.

The application itself is built with following changes:
Target Options IROM1 Start 0x20000 Size 0x60000
Asm options Define NO_CRP.

The following code should start my application after
successful update/validating the present firmware:

#define APPL_RUN_ADDR           0x00020000

__asm void boot_jump(U32 address)
{
    LDR SP, [R0]
    LDR PC, [R0, #4]
}


void run_appl()
{
     SCB->VTOR = APPL_RUN_ADDR & 0x1FFFF80;

    boot_jump(APPL_RUN_ADDR);
}


This code snippet is copied from nxp's AN10866.pdf, too.

But the firmware doesn't start reliable. Where do I stuck?

APPL_RUN_ADDR is defined to 0x20000

at 0x20004 there's 00020229 (this is the Reset_Handler fro my application, which I checked in the map file).

Unfortunately I don't find the AN10866.zip example files, to see how nxp's bootloader was built exactly.

What else have I forgotten to do?

Thanks in advance
Hubert

Parents
  • Q S, Thanks for your quick answer.

    As I'm transferring the application as S-record file, where every line has its own check-sum, as well as at the end there's an record where I can compare the count of received records with the ones contained in that s-record file.

    I took from your code the PCONP reset, as I'm not using SPI/SSP interfaces I omitted the accesses to CPSR/SPSR.

    It doesn't change very much. Very seldom the application starts, but most of the time not.

    Now I took a deeper look what the processor does when jumping from bootloader into application.
    Single-stepping (F11) in Disassembly beginning at my boot_jump function I observe the following:

    After

    LDR PC, [R0, #4]
    

    the PC is at the Reset_Handler of the application, with single steps I walk through the SystemInit as well as the __main (_main_scatterload) from there I reach my normal main function. But the following free run (F5) results in a Hard_Fault (HARD_FAULT_STAT = 0x40000000)

    I've already checked bit0 of the Interrupt vectors, they're all set (Thumb Mode).

    What else am I missing?

    Thanks Hubert

Reply
  • Q S, Thanks for your quick answer.

    As I'm transferring the application as S-record file, where every line has its own check-sum, as well as at the end there's an record where I can compare the count of received records with the ones contained in that s-record file.

    I took from your code the PCONP reset, as I'm not using SPI/SSP interfaces I omitted the accesses to CPSR/SPSR.

    It doesn't change very much. Very seldom the application starts, but most of the time not.

    Now I took a deeper look what the processor does when jumping from bootloader into application.
    Single-stepping (F11) in Disassembly beginning at my boot_jump function I observe the following:

    After

    LDR PC, [R0, #4]
    

    the PC is at the Reset_Handler of the application, with single steps I walk through the SystemInit as well as the __main (_main_scatterload) from there I reach my normal main function. But the following free run (F5) results in a Hard_Fault (HARD_FAULT_STAT = 0x40000000)

    I've already checked bit0 of the Interrupt vectors, they're all set (Thumb Mode).

    What else am I missing?

    Thanks Hubert

Children
  • Digging even deeper into the assembly showed after reaching my main function

    0x00021110 F7FEFFE9  BL.W     0x000200E6
    0x00021114 2200      MOVS     r2,#0x00
    0x00021114 2200      MOVS     r2,#0x00
    0x00021116 4611      MOV      r1,r2
    0x00021118 F2AF0057  ADR.W    r0,{pc}-0x53  ; @0x000210C5
    0x0002111C F8DFC0C4  LDR.W    r12,[pc,#196]  ; @0x000211E4
    0x00021120 DF00      SVC      0x00
    

    executing the SVC 0x00 call results in the HardFaultHandler.

    The C-code of that main look like

    
    int main (void)
    {
      os_sys_init(init);
      while(1);
    }
    

    I hope this gives some more hints about what I'm missing.

    Thanks Hubert

  • Where do you remap your interrupt vectors for your new code into the proper interrupt offset prior to executing the os_sys_init(init) call? You need to go back and review how a system functions, I believe.

  • O.K.

    Now I found the solution to start the application located at APPL_RUN_ADDR = 0x20000 reliably.

    before changing the vector table the irq's have to be disabled in the bootloader.

    
    __asm void boot_jump(U32 address)
    {
        LDR SP, [R0]
        LDR PC, [R0, #4]
    }
    
    void run_appl()
    {
    
    //   void (*user_code_entry)(void);
    
       /* Change the Vector Table to the USER_FLASH_START
       in case the user application uses interrupts */
    
         __disable_irq();
         LPC_SC->PCONP = 0x001817BE;
         SCB->VTOR = APPL_RUN_ADDR & 0x1FFFF80;
         boot_jump(APPL_RUN_ADDR);
    }
    

    and in the application the irq's have to be enabled again before calling os_sys_init()!!!

    int main (void)
    {
      __enable_irq();
      os_sys_init(init);                        /* Initialize RTX and start init */
    }
    

    The bootloader is compiled with IROM1 Start=0x0 Size = 0x20000

    The application is compiled with IROM1 Start=0x20000 Size = 0x60000 and Asm Define = NO_CRP

    Hubert

  • Note that this works _only_ because your specific controller starts up in privileged mode. This might not be the case using other controllers.