Hi there,
I'm attempting to convert my current S32 DS project (targeting a S32K3x8EVB board) into a multicore project. At the moment, all i need is the two cores running side-by-side without any particular interaction.
A lot of what i've set-up so far is based off a Pi - Monte Carlo multicore project available as a demo on S32 DS. In that demo, Core0 does the standard clock configuration and then attempts to wake up Core2 - via writing to a series of Register Addresses - see below. (It also configures a core-to-core interrupt, but i have omitted that from my project as i don't need it as of now. )
void sys_wake_core(uint8_t core, uint32_t boot_add)
{
if (core == 1)
{
MC_ME.PRTN0_CORE1_ADDR.R = boot_add; /* PRTN0_CORE1_ADDR */
MC_ME.PRTN0_CORE1_PCONF.R = 1; /* PRTN0_CORE1_PCONF */
MC_ME.PRTN0_CORE1_PUPD.R = 1; /* PRTN0_CORE1_PUPD */
MC_ME.CTL_KEY.R = 0x5AF0; /* CTL_KEY */
MC_ME.CTL_KEY.R = 0xA50F; /* CTL_KEY */
while(MC_ME.PRTN0_CORE1_PUPD.R & 0x1);
while(MC_ME.PRTN0_CORE1_STAT.R & 0x1);
}
#if (defined(S32K358) || defined(S32K388))
else if (core == 2)
{
MC_ME.PRTN0_CORE4_ADDR.R = boot_add;
MC_ME.PRTN0_CORE4_PCONF.R = 1;
MC_ME.PRTN0_CORE4_PUPD.R = 1;
MC_ME.CTL_KEY.R = 0x5AF0;
MC_ME.CTL_KEY.R = 0xA50F;
while(!(MC_ME.PRTN0_CORE4_PUPD.R & 0x01));
while(!(MC_ME.PRTN0_CORE4_STAT.R & 0x01));
}
#endif
...
}
Here, the address of Core2's vector table (0x00800000) is passed in and the system waits until Core2 is booted (i'm assuming?). Core2's main() doesn't perform any system setup, it just starts running application code. I have built and run this demo no problem, but when i try and replicate it for my own project Core2 isn't booted properly.
If you refer to sys_wake_core_func.png, you can see my own sys_wake_core() func, where i'm passing in the correct VTOR address. (The registers are name IP_MC_ME not MC_ME, but the value is still 402D_C000h as specified in the ref. manual) However, as callstack_on_startup.png shows, Core2's Reset_Handler() seems to be taking it to Core0's vector table and gets stuck there. The below is taken from the map file.
0x00400800 __ENTRY_VTABLE = __INIT_INTERRUPT_START
0x00400800 __CORE0_VTOR = __INIT_INTERRUPT_START
0x00600000 __CORE1_VTOR = ORIGIN (int_flash_c1)
0x00800000 __CORE2_VTOR = ORIGIN (int_flash_c2)
Am i right in thinking Core2 should be resetting to 0x0080'0000 as the map file suggests? If so how can i correct it? And are there any other steps to multicore initialisation I'm missing?
Any help is greatly appreciated
解決済! 解決策の投稿を見る。
Hi Daniel, thank you for that extra example.
Looking at the differences between my Core0 startup and the one you provided, my wake_up_core() now looks like this
static void prvSysWakeCore( portUnsignedBaseType uxCoreId, portUInt32Type ulBootAddress )
{
Power_Ip_Init(&Power_Ip_HwIPsConfigPB);
#if ( defined( S32K358 ) || defined( S32K388 ) )
if( uxCoreId == 2 )
{
IP_MC_ME->PRTN0_CORE4_ADDR = ulBootAddress;
IP_MC_ME->PRTN0_CORE4_PCONF = 1;
IP_MC_ME->PRTN0_CORE4_PUPD = 1;
IP_MC_ME->CTL_KEY = 0x5AF0;
IP_MC_ME->CTL_KEY = 0xA50F;
while( 1U == IP_MC_ME->PRTN0_CORE4_PUPD ) { };
while( 0U == ( IP_MC_ME->PRTN0_CORE4_STAT & MC_ME_PRTN0_CORE4_STAT_CCS_MASK ) ) { };
}
#endif /* #if ( defined( S32K358 ) || defined( S32K388 ) ) */
}
adding the POWER module and amending the second while loop seemed to do the trick - now both my cores are running nicely.
I also removed the .boot_header section from my Core2 linker script, one or both of these changes got it working.
Many thanks
Hi Daniel, thank you for that extra example.
Looking at the differences between my Core0 startup and the one you provided, my wake_up_core() now looks like this
static void prvSysWakeCore( portUnsignedBaseType uxCoreId, portUInt32Type ulBootAddress )
{
Power_Ip_Init(&Power_Ip_HwIPsConfigPB);
#if ( defined( S32K358 ) || defined( S32K388 ) )
if( uxCoreId == 2 )
{
IP_MC_ME->PRTN0_CORE4_ADDR = ulBootAddress;
IP_MC_ME->PRTN0_CORE4_PCONF = 1;
IP_MC_ME->PRTN0_CORE4_PUPD = 1;
IP_MC_ME->CTL_KEY = 0x5AF0;
IP_MC_ME->CTL_KEY = 0xA50F;
while( 1U == IP_MC_ME->PRTN0_CORE4_PUPD ) { };
while( 0U == ( IP_MC_ME->PRTN0_CORE4_STAT & MC_ME_PRTN0_CORE4_STAT_CCS_MASK ) ) { };
}
#endif /* #if ( defined( S32K358 ) || defined( S32K388 ) ) */
}
adding the POWER module and amending the second while loop seemed to do the trick - now both my cores are running nicely.
I also removed the .boot_header section from my Core2 linker script, one or both of these changes got it working.
Many thanks