I.MX RT1176笔记(3)-- 双核启动和通信 MU

12 篇文章 23 订阅
2 篇文章 0 订阅

简介
I.MX RT1176 是一个双核的MCU,那么两个核之间是如何启动的呢?通过什么方式通信的呢?这里多废话几句,nxp demo中有提供相关框架(如下图)但本章不讲多核框架,只是一个初步认识,尽量用最底层思维去实现基本功能。
在这里插入图片描述

1.双核启动方法
rt1176 默认是m7核启动m4核的,如果需要修改,需要烧写eFuse(这里我们就默认官方的启动吧,手里只有一台开发板,烧eFuse还是需要勇气的。。。手动狗头)。
在这里插入图片描述
首先要双核启动,我们必须先让m7核跑起来,通过m7核操作m4才能完整实现双核启动,具体流程如下:

  • m7核完全启动(能跑到main,文章最后会给工程链接)
  • m7拷贝m4代码(比如bin文件在Flash某个区域或者SD卡里面等等)到指定Ram(m4 TCM)
    请添加图片描述
    为啥不是跳转m4实际ram 0x1ffe_0000 而是 0x2020_0000,官方手册是有说明大致意思就是在m7内核中通过 0x2020_0000能重映射到m4 ram中的0x1ffe_0000
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
#define CM4_IMAGE_START   0x30FC0000U   //Flash镜像文件起始地址,这个位置其实可以任意定义,只要不跟M7重叠
#define CM4_RAM_START     0x20200000U

    uint32_t imageSize = xBSP_MuliteCore_GetImageSize();
    /*将Flash 镜像文件拷贝到指定RAM*/
    SCB_CleanInvalidateDCache_by_Addr((void*)CM4_RAM_START, imageSize);
    memcpy((void*)CM4_RAM_START, (void*)CM4_IMAGE_START, imageSize);
    SCB_CleanInvalidateDCache_by_Addr((void *)CM4_RAM_START, imageSize);

笔者为了证实这个重映射问题,特意仿真测试了m7和m4的内存,事实证明是这样的
在这里插入图片描述

  • 设置m4中断向量表映射位置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
void xBSP_SetCM4_Vector(uint32_t vectorAddr)
{
    IOMUXC_LPSR_GPR->GPR0 = IOMUXC_LPSR_GPR_GPR0_CM4_INIT_VTOR_LOW(vectorAddr >> 3);
    IOMUXC_LPSR_GPR->GPR1 = IOMUXC_LPSR_GPR_GPR1_CM4_INIT_VTOR_HIGH(vectorAddr >> 16);
}
    /*设置中断向量映射位置*/
	xBSP_SetCM4_Vector(CM4_RAM_START);
  • 启动m4内核
void launch_cm4_core(void)
{
    /* If CM4 is already running (released by debugger), then reset the CM4.
       If CM4 is not running, release it. */
    if ((SRC->SCR & SRC_SCR_BT_RELEASE_M4_MASK) == 0)
    {
        SRC_ReleaseCoreReset(SRC, kSRC_CM4Core);
    }
    else
    {
        SRC_AssertSliceSoftwareReset(SRC, kSRC_M4CoreSlice);
    }    
}

    /*启动M4内核*/
	launch_cm4_core();

执行上述步骤,m4核也就正常启动了

2.双核通信MU
说到多核通信,若是多块MCU:类似于整车系统ECU单元的话,通常使用CAN或LIN总线实现通信;当然也有使用串口,USB等等实现通信。但是这里说的通信是单MCU,多个内核,像RT1176,内核提供了MU接口,如下图所示:
在这里插入图片描述请添加图片描述
在这里插入图片描述

看到框图,我们可以将MU理解成m7和m4之前连接了串口接口。可以通过轮询或中断的方式查询MU状态。可以通过TR寄存器发送数据;RR寄存器接收数据;SR为状态寄存器用于查询TR和RR状态;CR控制寄存器用于配置MU。

/** MU - Register Layout Typedef */
typedef struct {
  __IO uint32_t TR[4];                             /**< Processor A Transmit Register 0..Processor A Transmit Register 3, array offset: 0x0, array step: 0x4 */
  __I  uint32_t RR[4];                             /**< Processor A Receive Register 0..Processor A Receive Register 3, array offset: 0x10, array step: 0x4 */
  __IO uint32_t SR;                                /**< Processor A Status Register, offset: 0x20 */
  __IO uint32_t CR;                                /**< Processor A Control Register, offset: 0x24 */
} MU_Type;

接下来我们配置m7和m4核。

m7核:

#define BOOT_FLAG      (0x01U)    /* Flag indicates Core Boot Up*/
void xBSP_MUInit(void)
{
	muMutex = xSemaphoreCreateMutex();	
	
    /* MUA init */
    MU_Init(MUA);	
	
    /* Wait Core 1 is Boot Up */
    while (BOOT_FLAG != MU_GetFlags(MUA))
    {
    
	}	

//    /*是否使用中断方式判断*/
//    MU_EnableInterrupts(MUA, kMU_Rx0FullInterruptEnable);
//    NVIC_EnableIRQ(MUA_IRQn);
}

//MU接收任务,用来观测m4发送的参数
void xTASK_ReceiveMsg(void* pvParameters)
{
	for(;;)
	{
		MuData =xBSP_MU_ReceiveMsg();
		muDataBuff[wrp++] = MuData;	
		wrp = wrp % 1024;
		
		vTaskDelay(100);
	}
}

m4核:

#define BOOT_FLAG      (0x01U)    /* Flag indicates Core Boot Up*/
void xBSP_MUInit(void)
{
	/* MUB init */
    MU_Init(MUB);
    /* Send flag to Core 0 to indicate Core 1 has startup */
    MU_SetFlags(MUB, BOOT_FLAG);
}

void xTASK_SendMsg(void)
{
	static uint32_t data;
	xBSP_MU_SendMsg(data);
	data++;
}

测试(仿真M7核):
利用MU标志,可观测出M4启动完成
在这里插入图片描述
在m7接收任务中观测MU,可接收到m4发送的参数
在这里插入图片描述
另外双核间有共享内存,在m7和m4都能正常观测,使用前需要配置MPU。

注:多核通信并不是这么简单,这里只是做个简单演示,涉及到的问题很多。所以这时候是需要多核框架来实现的,如nxp提供的:erpc、rpmsg-lite(基于linux多核裁剪的)、stream buffer(rtos提供)

这里提供M7核源码(内含m4镜像文件,点击下载可将m7和m4可执行文件烧录到指定路径):
RT1176_M7_RTOS

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值