嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > S32K344 锁步核解耦成双核 S32K324

S32K344 锁步核解耦成双核 S32K324

    S32K344具有锁步内核,可以将内核解耦以与具有不同应用的两个内核一起工作。下面介绍S32K344用于多核目的,每个内核都有自己的启动文件,也有自己的链接器件,其中根据应用程序将内存映射到每个内核。如果两个内核都已启用(根据Boot配置),它们同时运行,无论是在调试模式还是独立模式,一个内核都可以为两个内核配置时钟,并为彼此启用或禁用时钟,可以在内核时钟门控部分找到更多信息。如果有S32K344,可以将其解耦,并用新配置在UTEST中的新记录再次锁定器件。DCF记录存储在UTEST存储器中,有一些DCFTE/PE在测试 Flash中编程,用户无法访问这些记录,锁步DCF记录编程在这上面。从偏移量2006FF的区域仅可由HSE核和SBAF访问,如生命周期、OTA启用等配置均在该区域编程。可以在S32K3 SecureBAFHSE手册文档中找到有关UTEST中编程的所有这些配置的更多详细信息。

器件配置格式Device Configuration Format (DCF 记录)

DCF记录包含在UTEST扇区中,UTEST扇区是一个8 KB OTP存储器,其中包含SoC的相关信息,作为保留配置或应用参数。在引导序列中,在系统引导期间读取DCF记录以配置芯片中的某些寄存器。DCF记录大小从地址0x1B000700开始,到0x1B001BFF结束。在这个区域内,可以找到6种DCF记录。LOCKSTEP_EN=0的新DCF记录必须编程到UTEST OTP存储器中。这可以通过C40 IP RTD驱动程序来完成。首先,通过调试器读取内存,在UTEST中找到当前的DCF记录。对于具有默认配置的器件,新记录的第一个可用空间(全部为0xFF)应为0x1B000768。

  • Start Record

  • Dcf_client_utest_misc

  • Dcf_client_reset_pad_dedicated

  • Dcf_client_dest_rst_esc

  • Dcf_client_sdid0-15

  • Dcf_client_instanceid

DCF_client_utest_misc

要在DCF_client中进行有效配置,需要一个控制字和一个数据字,图1显示了每个DCF客户端的控制字。

1 DCF 控制字

DCF_client_utest_miscData对于某些配置有32位,其中一位是LOCKSTEP_EN,如下图2所示。 

2 UTEST Miscellaneous register.

为了解耦内核,需要写0LOCKSTEP_EN 位中。 

改变 LOCKSTEP_EN

以下代码在UTEST扇区中写入LOCKSTEP_EN位,以解耦内核 

/* Following macro defines chip mode

* 1 - Lockstep operation.

* 0 - Decoupled operation. */

#define LOCKSTEP_EN   (0)

/* From here, user should not modify the code */

#define PROGRAM_DATA1  (0x00100004)  /* UTEST_MISC DCF Control Word */

#if (LOCKSTEP_EN == 1)

#define PROGRAM_DATA0  (0x00000101)  /* UTEST_MISC Data Word */

#elif (LOCKSTEP_EN == 0)

#define PROGRAM_DATA0  (0x00000100)  /* UTEST_MISC Data Word */

#else

#error "Only two options are supported for LOCKSTEP_EN: [0, 1]."

#endif

/*UTest DCF Record Space : 5376 Bytes

* 0x1B000700 - 0x1B001BFF */

#define DCF_RECORD_START_ADDRESS  (0x1B000700)  /* UTEST DCF record start address */

#define DCF_RECORD_END_ADDRESS    (0x1B001B00)  /* UTEST DCF record end address */

/************************************************************************/

/* Global Variable definition*/

/************************************************************************/

/* UTEST Miscellaneous Register */

uint32_tutest_misc_dcf[ ] = {

(uint32_t)PROGRAM_DATA0, /* DCF Data word    8h [0:31]  */

(uint32_t)PROGRAM_DATA1  /* DCF Control word Ch [32:63] */

};

/* status variables for main and express interfaces */

volatile tFLASH_STATUS status;

/* FUNCTION ********************************************************************

* Function Name : main

* Description   : Main Function for CM7 Core

* END ************************************************************************/

int main(void)

{

uint64_t *DCF_Ptr;

DCF_Ptr = ( uint64_t *)DCF_RECORD_START_ADDRESS;

while (DCF_Ptr < ( uint64_t *)DCF_RECORD_END_ADDRESS)

{

if( *DCF_Ptr == 0xFFFFFFFFFFFFFFFFULL )

{

/* unlock UTEST data flash sector */

PFLASH_Unlock(PFLASH_BL5, PFLASH_SS0, PFLASH_S0);

/* write UtestWrite in UtestSector using main interface */

status = FLASH_Write (DCF_Ptr,       /* Last DCF available */

utest_misc_dcf,        /* SRC: UTEST-MISC */

sizeof(utest_misc_dcf)); /* Number of bytes */

if (status == 0x0000C000)

{

/* DCF record programming was successful */

printf("Successfully wrote at %08lx\n", ( uint32_t)DCF_Ptr);

printf("Status: %08lx\n", ( uint32_t)status);

while (1);

}

else

{

            printf("Failed at %08lx\n", ( uint32_t)DCF_Ptr);

printf("Status: %08lx\n", ( uint32_t)status);

while (1);

}

}

DCF_Ptr++;

}

}

代码只为LOCKSTEP_EN位添加了新的配置,这是因为UTESTOTP存储器,无法执行擦除。

3 UTEST 块存储器映射

在上图3中,可以在地址0x1B000768中看到数据0x00000100,在0x1B00076C中看到控制字0x00100004,其中数据核已配置为在解耦模式下工作。在这个配置之后,可以看到橙色的其他配置,以便显示可以添加新的配置。在地址0x1B000770中,内核在Lockstep中再次配置,在地址0x1B000788中,数据0x08000101Lockstep中配置内核,POR看门狗启用,并在旁路模式中绕过QSPI IAHB。地址0x1B000790中分配的最后一条记录是将会加载的有效记录。一旦内核被解耦,就可以使用两个内核来运行不同的任务。 

多核工程

介绍如何使用RTD/SDK软件在S32DS中构建多核项目。首先创建 S32DS Application Project工程。如下图所示。

需要添加一个名称,并选择2核设备S32K324。“下一步”之后,如下图所示。在SDKs , 选择 PlatformSDK SW

需要选择两个内核,点击完成将创建以下项目。

已经准备好使用主文件,并配置Multicore_M7_0.mexMulticore_M7_1.mex。在本例中,将使用PIT计时器使用中断切换LED。第一步是配置打开.mex文件的必要模块,以便使用Config工具。对于Pins(引脚)窗口中的Multicore_M7_0,需要选择LED连接的引脚,需要选择LEDPTA31引脚,并将配置选择为具有输出方向的GPIO。将其标记为BLUE0

下一步是添加将要使用的外围设备,在本例中,需要添加Siul2_Dio以使用所选引脚,并使用与引脚相关的APIPit驱动程序来配置切换时间,以及IntCtrl_IP来配置Pit的中断处理程序。

对于PIT配置,需要选择PIT实例Channel并定义Callback。在例子中,将使用PIT_00通道,并定义Pit0_Ch0_Callback

需要产生中断,因此使能IsrEnable

InCtrl_Ip窗口,需要配置如下使能 PIT中断请求。

上述代码配置后,需要通过 Update Code按键更新产生代码.c .h 文件。

点击OK加载程序试图,在项目资源管理器中,可以使用下一个cfg.h文件。

可以使用.c文件中包含的API以及.h文件中定义的参数和结构。下图中可以看到Pit0_Ch0_Callback已经声明,并且有PIT实例0的结构和所做的配置的结构。

main文件里面实现代码,需要初始化每个模块。

/* Including necessary configuration files. */

#include "Mcal.h"

#include "Siul2_Dio_Ip.h"

#include "Siul2_Port_Ip.h"

#include "Pit_Ip.h"

#include "IntCtrl_Ip.h"

#include "Clock_Ip.h"

volatile int exit_code = 0;

/* User includes */

#define PIT_INSTANCE 0

#define PIT_CH 0

#define PIT_TIMEVAL 40000000 /* Due to AIPS_SLOW_CLK = 40 MHz */

ISR(PIT_0_ISR);

/* Callback for PIT0 Channel 0

* The BLUE0 LED is toggled every 1 second */

void Pit0_Ch0_Callback (uint8_t channel)

{

(void) channel;

Siul2_Dio_Ip_TogglePins(BLUE0_PORT, (1<<BLUE0_PIN));

}

int main(void)

{

/*Initialize configured clocks */

Clock_Ip_Init(&Mcu_aClockConfigPB[0]);

/* Port initialization for BLUE0 LED */

Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);

/* PIT initialization for Instance 0 */

Pit_Ip_Init(PIT_INSTANCE, &PIT_0_InitConfig_PB);

/* PIT initialization for Channel 0 of Instance 0 */

Pit_Ip_InitChannel(PIT_INSTANCE, &PIT_0_ChannelConfig_PB[0U]);

/* The interrupt handler is loaded */

IntCtrl_Ip_InstallHandler(PIT0_IRQn, PIT_0_ISR, NULL_PTR);

/* PIT Instance 0 channel 0 interrupt is enable */

Pit_Ip_EnableChannelInterrupt(PIT_INSTANCE, PIT_CH);

/* PIT0 Interruption is enabled*/

IntCtrl_Ip_EnableIrq(PIT0_IRQn);

/* PIT0 Channel 0 Timer is started to run */

Pit_Ip_StartChannel(PIT_INSTANCE, PIT_CH, PIT_TIMEVAL);

for(;;)

{

if(exit_code != 0)

{

break;

}

}

return exit_code;

}

针对 Core M7_1,使用 PTB18实现 LED点灯,PIT1Channel 1,需要在 MultiCore_M7_1.mex 里面按照上述配置再配置一遍,代码如下。

/* Including necessary configuration files. */

#include "Mcal.h"

#include "Siul2_Dio_Ip.h"

#include "Siul2_Port_Ip.h"

#include "Pit_Ip.h"

#include "IntCtrl_Ip.h"

#include "Clock_Ip.h"

volatile int exit_code = 0;

/* User includes */

#define PIT_INSTANCE 1

#define PIT_CH 1

#define PIT_TIMEVAL 40000000 /* Due to AIPS_SLOW_CLK = 40 MHz */

ISR(PIT_1_ISR);

static uint32_t Counter=0;

/* Callback for PIT1 Channel 1

* The RED LED is toggled every 1 second */

void Pit1_Ch1_Callback (uint8_t channel)

{

(void) channel;

Siul2_Dio_Ip_TogglePins(RED1_PORT, (1<<RED1_PIN));

}

int main(void)

{

/* Port initialization for RED1 LED */

Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);

/* PIT initialization for Instance 1 */

Pit_Ip_Init(PIT_INSTANCE, &PIT_1_InitConfig_PB);

/* PIT initialization for Channel 1 of Instance 1 */

Pit_Ip_InitChannel(PIT_INSTANCE, &PIT_1_ChannelConfig_PB[0U]);

/* The interrupt handler is loaded */

IntCtrl_Ip_InstallHandler(PIT1_IRQn, PIT_1_ISR, NULL_PTR);

/* PIT Instance 1 channel 1 interrupt is enable */

Pit_Ip_EnableChannelInterrupt(PIT_INSTANCE, PIT_CH);

/* PIT1 Interruption is enabled*/

IntCtrl_Ip_EnableIrq(PIT1_IRQn);

/* PIT1 Channel 1 Timer is started to run */

Pit_Ip_StartChannel(PIT_INSTANCE, PIT_CH, PIT_TIMEVAL);

for(;;)

{

if(exit_code != 0)

{

break;

}

}

return exit_code;

}

选择调试配置debug configuration开始工程调试。

选择LaunchGroup以加载每个Core配置,可以通过打开各个调试选项来检查配置是否正确。按下调试按钮后,将看到以下窗口,其中包含调试两个内核选项。