双核调试指南

提示

该文档仅适用于ET6001芯片。

ET6001芯片内部包含两个ARM Cortex-M7内核,分别为主核和从核。主核负责系统的初始化,控制和调度,从核负责数据处理和实时任务。 本文档将介绍双核之间的资源分配、调试与程序烧录、通信等方面的内容。

双核间的调试与程序烧录

上电默认状态

芯片上电或者复位(Core复位除外)后,此时,主核处于运行状态,从核处于等待状态 。 从核处于等待状态时,无法进行调试和烧录操作。 此时,主核可以通过调用API函数 DUALCORE_StartCore1(0x08080000); 来使从核进入调试模式。 其中输入参数为从核的启动地址,通常为PFLASH1的起始地址 0x08080000

// 主核main函数
int main(void)
{
    uint32_t frq = 0;
    uint8_t tx_buffer[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    uint8_t rx_buffer[8] = {0};

    SCB_EnableICache();
    SCB_EnableDCache();

    frq = CRG_GetCPUFreq();

    SHM_Init();
    IPC_Init();
    BSP_Init();

    /* 启动CORE1, 开始从 0x08080000 执行程序 */
    DUALCORE_StartCore1(0x08080000);

    while (1)
    {
        IPC_SendMessage(tx_buffer, 4);
        /* block receive */
        IPC_RecvMessage(rx_buffer, 4);
        /* 共享内存,core0 向 core1 发送数据 */
        SHM_WriteToCore1(tx_buffer, 8);
        DELAY_US(1000000);
    }
}

芯片的时钟配置及各模块的复位和门控配置均在主核中完成。系统启动文件 SystemInit 函数中,如果检测到代码在从核中运行,则 直接跳过硬件初始化工作。

void SystemInit(void)
{
    /* Enable Global Interrupt Mask */
    __enable_irq();
    /* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2));  /* set CP10 and CP11 Full Access */
#endif

    if (DUALCORE_GetCurrentCoreId() == CORE1)
    {
        return; // 从核不需要进行硬件初始化
    }
    // 主核的时钟配置
    ...

调试接口

两个核拥有完全独立的调试接口,主核和从核可以同时进行调试(从核需处于运行状态)。 主从核的调试接口均为SWD,对应的管脚名称分别为:

  • CPU0_SWJ_TMS

  • CPU0_SWJ_SWCLKTCK

  • CPU1_SWJ_TMS

  • CPU1_SWJ_SWCLKTCK

也就是说,调试双核需要2个SWD(J-Link)调试器,分别连接到主核和从核的调试接口上。

从核调试时,建议将KEIL的 Debug Reset选项中的Reset Target设置为“Core” 或者 “VECTRESET”。 因为从核的复位信号是由主核控制的,使用“System”选项可能会导致从核进入等待状态而无法调试。 主核调试时,建议将KEIL的 Debug Reset选项中的Reset Target设置为默认即可。 KEIL软件Debug配置方式如下:

双核调试-CMSIS-DAP
双核调试-J-Link

程序烧录

主核和从核的程序烧录方式相同,均为通过SWD接口进行烧录。建议按照两个核分别使用一个FLASH的方式进行FLASH资源分配。

PFLASH

起始地址

主核

PFLASH0

0x08000400

从核

PFLASH1

0x08080000

当调试器连接到从核的调试接口时,需要确认从核处于运行状态,否则调试器无法连接到从核。

另外,还需要确保用户选项字 OTA_MODE 和 BANK_SWAP 均设置为0。(出厂默认均位0)

API介绍

主核和从核的API函数均在 et6x_dualcore.h 头文件中定义。

  • DUALCORE_StartCore1(uint32_t start_addr); 使从核进入运行状态

  • DUALCORE_GetCurrentCoreId(void); 获取当前程序代码运行在哪个核上

双核间资源分配

主核和从核之间,除了每个核的ITCM和DTCM内存区域是独立的以外,其他资源均为共享资源。

ITCM&DTCM

主核和从核各自拥有独立的ITCM和DTCM,MPU,FPU,NVIC,Cache,每个核的ITCM和DTCM内存区域分别为:

  • ITCM: 0x00000000 ~ 0x0000FFFF

  • DTCM: 0x20000000 ~ 0x2000FFFF

每个核的ITCM和DTCM内存区域大小均为64KB,主核和从核的ITCM和DTCM内存区域地址相同,各种访问互不影响。 主核和从核的ITCM和DTCM内存区域均为SRAM类型的内存,具有高带宽、低延迟的特点,适合用于存储实时数据和代码。

内存

主核和从核共享256KB的SRAM内存区域,地址范围为0x20400000 ~ 0x2043FFFF。SRAM资源的分别可以按以下方式进行分配:

  • 主核和从核各自划分128KB的SRAM内存区域,主核的SRAM内存区域地址范围为0x20400000 ~ 0x2041FFFF,从核的SRAM内存区域地址范围为0x20420000 ~ 0x2043FFFF。

  • 主核和从核各自划分64KB的SRAM内存区域,主核的SRAM内存区域地址范围为0x20400000 ~ 0x20407FFF,从核的SRAM内存区域地址范围为0x20408000 ~ 0x2040FFFF。 剩余的128KB SRAM内存区域可以用于主核和从核之间的共享内存使用。

中断

主核和从核用于各自的NVIC控制器,共享256个中断源,主核和从核的中断源号相同。中断源号范围为0 ~ 255。 某个中断源号的中断请求可以同时触发主核和从核的中断处理程序。所以在实际使用时,可根据主核和从核的应用场景,每个核可选择是否使能该中断源号的中断请求。

例如:

  1. STIMER只被从核使用,主核不需要使能STIMER的中断请求。

  2. SPRWM的中断,主核和从核均需要响应,则主核和从核均需要使能该中断源号的中断请求。

使能和禁用中断源号的中断请求可以使用以下API函数:

  • NVIC_EnableIRQ(IRQn_Type IRQn); 使能中断源号的中断请求

  • NVIC_DisableIRQ(IRQn_Type IRQn); 禁用中断源号的中断请求

  • NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority); 设置中断源号的中断优先级

  • NVIC_GetPriority(IRQn_Type IRQn); 获取中断源号的中断优先级

  • NVIC_ClearPendingIRQ(IRQn_Type IRQn); 清除中断源号的中断请求

外设

主核和从核之间共享所有的外设资源,所以两个核在对外设进行同时访问时,需要进行互斥处理。 主核和从核之间的互斥处理主要利用芯片自带的硬件模块SPINLOCK来实现。

双核间通信

ET6001 针对双核应用,提供了两个硬件模块 IPCMSPINLOCK

关于该部分的内容,我们提供了示例程序,具体的使用方法可以参考该示例程序。

该示例程序的路径为:

  • ET6001_Examples/Examples/SPINLOCK

  • ET6001_Examples/Examples/IPCM

  • ET6001_Examples/Examples/dualcore_demo

其中dualcore_demo 例程为综合例程,包含了对IPCM和SPINLOCK的使用。并且提供了基于SPINLOCK + shared memory的 shm 中间件以及 基于 IPCM 的 IPC 中间件的使用示例。

IPCM

IPCM是Inter-Processor Communication Module的缩写,意为“核间通信模块”。 该模块提供两个主要的功能:一是触发核间中断,二是核间传递少量数据。 ET6001的IPCM模块共有16个消息邮箱,同时IPCM提供16个通道,每个通道均有独立的中断。 每个邮箱可参数7个32位的消息。

SPINLOCK

在 ET6001中, 主从核对同一个外设资源进行读写时, 会产生资源竞争, 导致读写 同步问题。 这个共享资源可以是同一段 SRAM 空间, 也可以是同一个外设。 这种情况下就需 要保护好共享资源。 ET6001 有硬件自旋锁外设 SPINLOCK 用于保护临界资源。 当资源已被占 用时, 资源申请者” 自旋“等待。

关于双核使用,更多的内容可以参考: ET6001双核编程应用指南