MPC5748G re-boot Core0 from a new location with MC_ME_CADDR

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

MPC5748G re-boot Core0 from a new location with MC_ME_CADDR

1,053 次查看
wattenre
Contributor I

Hello all,

I would like to switch between BOOTLOADER and APPLICATION by setting the MC_ME_CADDR1 and restarting the Z4_0 via a "functional" reset.

The BOOTLOADER has its bootheader in 0x00FA0000 and its content in 0x01000000 (see linker script below). The APPLICATION is written from the raw binary file via CAN to 0x01200000 and the bootheader to 0x00FC0000. This write process works without errors. According to the BAF search sequence the APPLICATION is correctly executed after a reset (0x00FC0000 is fetched before 0x00FA0000).

Now I want to switch back to the BOOTLOADER with the following code:
   MC_ME->CCTL1 = 0x00FC;
   MC_ME->CADDR1 = 0x01200000 | 1;
   MC_ME->MCTL = 0x00005AF0;
   MC_ME->MCTL = 0x0000A50F;

But this doesn't work, instead the Z4_0 boots after the "functional" reset from the BAF, which leads to the start of the APPLICATION instead of the BOOTLOADER. If i delete the BAF section at 0x00FC0000, then the BOOTLOADER is starting again without any problems.

Thanks in advance.

Greetings René

 



Linker Scripts:

BOOTLOADER

* Define FLASH */

FLASH_BASE_ADDR = DEFINED(__flash_base_addr__) ? __flash_base_addr__ : 0x01000000;
FLASH_SIZE =  DEFINED(__flash_size__) ? __flash_size__ : 1856K;

/* Define SRAM */
SRAM_BASE_ADD/R = DEFINED(__sram_base_addr__) ? __sram_base_addr__ : 0x40000000;
SRAM_SIZE = DEFINED(__sram_size__) ? __sram_size__ : 256K;

/* Define RAppID boot data address */
RAPPID_BOOT_APP_DELAY_ADDR = 0x00FA0008;
RAPPID_BOOT_APP_KEY_ADDR   = 0x00FA000C;

MEMORY
{
    flash_rchw : org = 0x00FA0000, len = 0x4
    cpu0_reset_vec : org = 0x00FA0000+0x10, len = 0x4
    cpu1_reset_vec : org = 0x00FA0000+0x14, len = 0x4
    cpu2_reset_vec : org = 0x00FA0000+0x04, len = 0x4
    rappid_boot_data : org = 0x00FA0000+0x08, len = 0x8

    m_text : org = FLASH_BASE_ADDR, len = FLASH_SIZE
    m_data : org = SRAM_BASE_ADDR, len = SRAM_SIZE
}
 
 
APPLICATION
 
/* Define FLASH */
FLASH_BASE_ADDR = DEFINED(__flash_base_addr__) ? __flash_base_addr__ : 0x01200000;
FLASH_SIZE =  DEFINED(__flash_size__) ? __flash_size__ : 1856K;

/* Define SRAM */
SRAM_BASE_ADDR = DEFINED(__sram_base_addr__) ? __sram_base_addr__ : 0x40000000;
SRAM_SIZE = DEFINED(__sram_size__) ? __sram_size__ : 256K;

/* Define RAppID boot data address */
RAPPID_BOOT_APP_DELAY_ADDR = 0x00FC0008;
RAPPID_BOOT_APP_KEY_ADDR   = 0x00FC000C;

MEMORY
{
    flash_rchw : org = 0x00FC0000, len = 0x4
    cpu0_reset_vec : org = 0x00FC0000+0x10, len = 0x4
    cpu1_reset_vec : org = 0x00FC0000+0x14, len = 0x4
    cpu2_reset_vec : org = 0x00FC0000+0x04, len = 0x4
    rappid_boot_data : org = 0x00FC0000+0x08, len = 0x8

    m_text : org = FLASH_BASE_ADDR, len = FLASH_SIZE
    m_data : org = SRAM_BASE_ADDR, len = SRAM_SIZE
}
 
#MPC5748G
0 项奖励
回复
4 回复数

1,040 次查看
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi @wattenre 

it does not work in this way. MC_ME.CADDR registers take effect only during wake up from standby modes or when changing modes in Mode Entry. Typical use-case for the second situation is starting of Z4B and Z2 cores from Z4A core like this:

void Core_Boot(void)
{
/* Enable e200z4b and e200z2 cores in RUN0-RUN3, DRUN and SAFE modes */
MC_ME.CCTL[2].R = 0x00FC; /* e200z4b is active */
MC_ME.CCTL[3].R = 0x00FC; /* e200z2 is active */

/* Set start address for e200z4b and e200z2 cores */
MC_ME.CADDR[2].R = E200Z4B_BOOT_ADDRESS | 1; /* e200z4b boot address + RMC bit */
MC_ME.CADDR[3].R = E200Z2_BOOT_ADDRESS | 1; /* e200z2 boot address + RMC bit */

/* Mode change - re-enter the DRUN mode to start cores */
MC_ME.MCTL.R = 0x30005AF0; /* Mode & Key */
MC_ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */

while(MC_ME.GS.B.S_MTRANS == 1); /* Wait for mode entry complete */
while(MC_ME.GS.B.S_CURRENT_MODE != 0x3); /* Check DRUN mode entered */
}

But after reset, reset vectors from boot header are always used.

So, there are two solutions:

- more common solution is to always start a bootloader after each reset. The bootloader then decides if it should jump to application or not.

- second solution is to reprogram the boot headers when needed.

Regards,

Lukas

1,021 次查看
wattenre
Contributor I

Hi @lukaszadrapa,

thank you very much for the fast and detailed answer on Friday and for providing additional solutions to solve my problem.
In the reference manual I found the following note in chapter 38.1.3.3:

The fact that a core does not need to be on in the current mode for it to be reset using the ME_CADDRx[RMC] bit in the next mode transition allows the boot core, for example, to cause itself to re-boot from a new location when all other cores are off without needing to turn on one of the other cores to handle the mode transition.

How can I perform the mentioned self-restart from another location? Is it also possible only by rewriting the boot headers in the BAF?

Thanks in advance.

René

0 项奖励
回复

984 次查看
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

it's exactly the same as shown in my first answer in Core_Boot() function. Notice that when RMC bit set, it resets only the core on mode change. It does not reset whole microcontroller. And this is very often issue when customers jumps from bootloader to application (or vice versa) without reset. If the device is not in default reset state (or completely deinitialized), it usually leads to various SW issues due to previous initialization. So, it's possible but it's very important to deinitialize the device by your SW.

Regards,
Lukas

999 次查看
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi @wattenre 

I'm sorry for delayed response, I'm totally overloaded now. That's a good question, I haven't met this until now. I will allocate some time to check it more thoroughly next week and I will let you know.

Thanks for patience.

Regards,

Lukas