Starting Core2 from Core0 on a S32k358 Multicore project

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Starting Core2 from Core0 on a S32k358 Multicore project

ソリューションへジャンプ
296件の閲覧回数
jonnyWHIS
Contributor II

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

0 件の賞賛
返信
1 解決策
256件の閲覧回数
jonnyWHIS
Contributor II

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

元の投稿で解決策を見る

2 返答(返信)
271件の閲覧回数
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @jonnyWHIS,

Here is a very simple example:

https://community.nxp.com/t5/S32K-Knowledge-Base/S32K358-Multicore-Start-CM7-2-from-CM7-0/ta-p/19238...

Can you compare it?

 

Regards,

Daniel

0 件の賞賛
返信
257件の閲覧回数
jonnyWHIS
Contributor II

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