MPC5604  code jump fail

cancel
Showing results for 
Search instead for 
Did you mean: 

MPC5604  code jump fail

Jump to solution
920 Views
ningwang
Contributor III

Hello,Very thinks to notice my questions.

     I'm developing bootloader on MPC5604 using UART0 and it works well. I download form linux via uart to MPC5604. Frist I burn bootloader on the address 0x00000000, then bootloader runs and download app to the address 0x00018000, when finished, bootloader jumped to app using

 

SYS_Jump2App(*((uint32_t *)(0x00018000+4)));

while(1){};

 

App works well too. But In the app, when I want to jump back to bootloader using

SYS_Jump2App(*((uint32_t *)(0x00000000+4)));

while(1){};

it appears failed, and the bootloader can't run.  Hoever, but if when I want to jump back to bootloader using reset  method in app, the bootlader can startup well. As when we upgrate our app, reseting the system is not allowed because all IO status should not changed.

 

Is there any problem when using

SYS_Jump2App(*((uint32_t *)(0x00000000+4)));

while(1){};

? Or there's other things to notice?

Thanks very much!

Original Attachment has been moved to: BOOT.rar

Labels (1)
1 Solution
525 Views
ningwang
Contributor III

Thank you very much ! At this morning, I also think there may be problem with SYS_Jump2App(), and I try to use

((void (*)())( *(uint32_t *)(BOOT_OTA_RCW_ADDR+4)))(); 

and it works!

I think this may the universal way to realize code jump ! Thank you let know the reason why SYS_Jump2App() can not work.

View solution in original post

6 Replies
525 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

there's no problem with the jump itself. But you have to consider other things - the device and its registers are not in default reset state. The most important point - interrupts. You should disable interrupts by means of MSR[EE] bit and also locally in all peripherals. Consider to put also other peripherals to default reset state if necessary. In other words - the bootloader must be aware that device is not in default reset state.

If it doesn't help, some extensive debugging will be necessary.

Regards,

Lukas

525 Views
ningwang
Contributor III

     Thanks very much, and I think what you said is correct. I want just verify the jump code,  when the bootloader strartup, the uart will print "this is in boot mode", and then I let jump to the beginning of the program. If it works, this program may always print this message, but it's just print once, and debugging appears  "XXXX Bus Error - No Opcode ".

    I upload the project,  and  which part should be set before SYS_Jump2App is not found yet.

int main(void)

{                   

    //UPGRADE_Chk();

  SWT_Disable();

  SYS_Init();                   

  PERI_ClkGenInit();                          

  INTC_Init();                  

    //GPIO_Init();   

    UART0_Init();

    //IIC_Init();     

               

    enableInterrupts();

    //GPIO_OutputPwrOnInit();   

    UART0_Write((unsigned char*)"this is in boot mode\n",strlen("this is in boot mode\n")); 

    disableInterrupts();

    SYS_Jump2App( *((uint32_t *)(0x00000000+4)) );               

    while(1)

    {

        MsgHandler(); 

    }

}

0 Kudos
525 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

I got it. It's compiler issue. The call of SYS_Jump2App is translated in this way:

pastedImage_0.png

se_lwz instruction is used to load the reset vector from flash. But this instruction should not be used because r0 is not replaced by zero but by content of r0 register. Or it could be used but r0 would have to loaded appropriately.

r0 register is 0x0F at that moment:

pastedImage_1.png

So, it will read address 0x13 which is 0xFFFFFFFF. Then it will jump to this wrong address.

Instead if se_lwz, e_lwz should be used. Here is the description of instructions:

pastedImage_2.png

CodeWarrior 2.10 is not being updated anymore, so it will not be fixed in this version. I'm not sure if this works in CodeWarrior 10.6, I will let you know later.

Workaround:

I found this one - write the function in this way:

#define VECTOR_ADDRESS 0x00000004

asm void SYS_Jump2App(void)

{

    /* Load reset vector address */

    e_lis  r3,VECTOR_ADDRESS@h

    e_add16i r3,r3,VECTOR_ADDRESS@l

    /* Load vector */

    e_lwz r3,0(r3)

    /* Move vector to link register */

    mtlr r3

    /* Branch link register */

    blr

}

And simply call it:

SYS_Jump2App();

I didn't find a way how to use a function with parameter because compiler always uses se_lwz.

Regards,

Lukas

526 Views
ningwang
Contributor III

Thank you very much ! At this morning, I also think there may be problem with SYS_Jump2App(), and I try to use

((void (*)())( *(uint32_t *)(BOOT_OTA_RCW_ADDR+4)))(); 

and it works!

I think this may the universal way to realize code jump ! Thank you let know the reason why SYS_Jump2App() can not work.

525 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

By the way, I did quick test in CW10.6.4 and it has been already fixed...

0 Kudos
525 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Nice to see that you have found another workaround!

0 Kudos