【MCXN947】02 - 双核应用开发 · 初识——NXP-MCX-N9XX-BRK开发板基础教程

【MCXN947】02 - 双核应用开发 · 初识——NXP-MCX-N9XX-BRK开发板基础教程

二、双核应用开发 · 初识

[Pasted image 20241110170646.png]

1. 双核简介

结合芯片手册以及芯片白皮书,我们在MCXN94x的框图中可以看到,MCXN94x采用的双Cortex-M33核,分为主核和辅助核,主核具备如下特性:
• TrustZone技术
• 内存保护单元
• SIMD功能
• 安全仲裁单元(SAU)
• 协处理器接口
• 单精度浮点运算单元
• Arm V8指令,包括DSP指令
从核是基础型,功耗优化的处理单元,适合执行不涉及信息安全或高速计算功能的简单处理任务,它不支持主核的TrustZone、 MPU、 FPU、 SIMD、 ETM、 SAU、协处理器接口及扩展DSP指令。

[Pasted image 20241105185310.png]
由于我之前并没有接触过双核MCU的开发,首先还是从官方例程中简单了解一下双核之间交互

2. 双核Helloworld Demo

在前面点灯时我们下载的SDK中,找到如下路径的双核Demo工程:
[Pasted image 20241105185912.png]
这是一个双核MCU打印helloworld+点灯的例程,可以看到分为了两个核的工程,首先我们打开“cm33_core0”的工程文件,路径“.\SDK_2_16_100_MCXN947\boards\mcxn9xxevk\multicore_examples\hello_world\cm33_core0”
[Pasted image 20241105191229.png]
打开工程后,打开“source/hello_world_core0.c”文件:
[Pasted image 20241105190309.png]
在main.c中可以看到主核和从核的一些操作以及串口打印等,内容我们待会分析,现在先编译一下,会发现如下问题:
[Pasted image 20241105191319.png]
编译提示找不到“core1_image.bin”,既然我们编译的时core0的工程,提示找不到core1的镜像,不如我们打开cm33_core1的工程编译一下:
[Pasted image 20241105191503.png]

编译之后我们可以看到输出文件里已经出现了刚才在core0中编译提示的缺失文件“core1_image.bin”:
[Pasted image 20241105191707.png]
接下来我们回到core0工程,重新编译,发现已经编译成功,接下来配置一下Linker并勾选自动复位运行,然后烧录程序:
[Pasted image 20241105192043.png]
[Pasted image 20241105195419.png]
下载完成后可以在1-2s后看到红灯闪烁(首次下载完成后似乎勾选的自动复位运行并不起效果,需要手动按下中间的复位按键进行复位或重新上电,留坑待查),至于我们如何查看串口收发引脚,我们在开发板原理图中可能找到明显标识,需要打开Data Sheet,找到Pin的说明部分:
[Pasted image 20241105205105.png]
[Pasted image 20241105205137.png]

另外在代码中配置串口初始化的部分也可以找到:
[Pasted image 20241105200033.png]
[Pasted image 20241105200301.png]
上述可以确定打印串口采用的为FLEXCOMM4,而FLEXCOMM4引脚配置为P1_9为TX,P1_8为RX;在连接上串口之后,重新运行程序,可以看到如下日志信息,并且LED灯开始闪烁:
[Pasted image 20241105194651.png]
接下来结合现象去分析源码部分

3. 源码分析

1)主核源码

在这个双核例程中,主核工程的main函数分为三部分,分别是初始化部分、拷贝辅助核Core1镜像到RAM中,然后启动Core1并等待启动完成,最后进入for死循环,期间插入了一些打印函数:
[Pasted image 20241105232520.png]
可以看到最后调用MCMGR_StartCore函数开启辅助核(次核):

(void)MCMGR_StartCore(kMCMGR_Core1, (void *)(char *)CORE1_BOOT_ADDRESS, 2, kMCMGR_Start_Synchronous);

进入这个MCMGR_StartCore函数可以看到系统会一直等待直到次核开始运行:
[Pasted image 20241105225949.png]
从mcmgr_start_core_internal函数可以看到启动方式是控制CPUCTRL寄存器,配置为SYSCON_CPUCTRL_CPU1RSTEN_MASK(Reset使能)以及SYSCON_CPUCTRL_CPU1CLKEN_MASK(时钟使能)
[Pasted image 20241105230019.png]
这两个寄存器在Reference Manual中可以看到说明:
[Pasted image 20241105234545.png]

2)辅助核源码

辅助核系统初始化后,进行多核管理器的相关初始化,载入启动数据启动完成后,执行应用功能部分(LED灯光闪烁):
[Pasted image 20241105232406.png]
这里比较关键的是多核管理器MCMGR初始化部分,我们进入MCMGR_Init函数,可以看到首先注册一些Event(注册回调函数),然后执行mcmgr_late_init_internal函数:
[Pasted image 20241105232802.png]
进入mcmgr_late_init_internal函数内,可以看到执行了一些中断打开动作,然后通过一个邮箱通知主核:
[Pasted image 20241105232925.png]
这一点的在核间通信手册中也可以看到邮箱在双核之间通信的示例,手册还有使用互斥锁+邮箱等进行通信的示例,这里不一一列举,大家自行查看:
[Pasted image 20241105233153.png]
然后系统的双核就分别各自启动运行了,Demo例程中主核启动后进入for死循环,辅助核执行LED Blink,对于多核管理器MCMGR,我也只是通过代码以及片面的手册简单理解,我们可以在官网查找相关资料了解更详细的启动过程以及实现方法,或者参考其他大神使用其他芯片时对于MCMGR源码的讲解。

Licensed under CC BY-NC-SA 4.0