多核的微控制器(mcu)向来是设计上的一大挑战,尤其是多核异构的设计。恩智浦半导体早在2011年年底,就率先推出了基于cortex-m4f和cortex-m0的双核mcu——lpc43xx/43sxx系列, 主频高达204mhz。凭借其超强的处理性能,很快受到业界的好评。四年之后,mcu双核精简版本lpc5411x系列,在广大lpc发烧友的期待中,终于露出了一代天骄的本色。
双核mcu:lpc5411x
这款lpc5411x系列mcu集成了cortex-m4f和cortex-m0+双内核,主频高达100mhz 。因为cortex-m4f内核采用harvard架构,3级流水线,支持simd,支持单精度浮点运算,单个时钟周期就能完成一条乘累加(mac)指令,所以其处理性能强悍,一般用于处理复杂的计算或算法。而cortex-m0+内核结构简单,只有2级流水线,能效高,一般用于实时控制、外设管理、数据通信等任务。
在lpc5411x产品中cortex-m4f是主核,而cortex-m0+是从核。从核的主要任务是协助主核处理非计算性的杂务,充分解放主核的运算能力,这样可以达到整个系统的最优性能。
为了实现整体性能最优,lpc5411x采用了多层ahb矩阵式总线架构,以及多个ram分块。下图是lpc5411x的内部功能框图,可以看到内部的ahb矩阵式总线架构,cortex-m4f和m0+都是总线上的master,可以访问所有的片上资源。总线访问的优先级可以通过寄存器设定。
cortex-m4f核在ahb总线上有3个接口:i-code, d-code和system总线。而cortex-m0+只有一个system总线接口。不同的ram块可以被不同的ahb master同时访问。
双核mcu的存储区分配
i-code总线用于从code内存分区取指令, 地址范围是:0x0000-0000~0x1fff-ffff。d-code总线用于从code内存分区取操作数,地址范围是:0x0000-0000~0x1fff-ffff。
当以上两条总线同时访问同一内存单元时,d-code总线访问优先级比i-code高,所以d-code先访问。对地址范围从0x2000-0000~0xdfff-ffff的访问是通过system总线进行的,可用于访问操作数、指令等,数据访问的优先级高于取指令及中断向量。
各个存储区所在的地址区域如下表:
存储区
地址区域
大小
flash
0x0000-0000 ~
0x0003-ffff
256kb
boot rom
0x0300-0000 ~
0x0300-7fff
32kb
sramx
0x0400-0000 ~
0x0400-7fff
32kb
sram0
0x2000-0000 ~
0x2000-ffff
64kb
sram1
0x2001-0000 ~
0x2001-ffff
64kb
sram2
0x2002-0000 ~
0x2002-7fff
32kb
为优化系统整体处理能力,需要让这两个cpu内核同时以最快速度执行各自指令, 比如cortex-m4f上能执行单周期的的mac指令,同时cortex-m0+上能执行单周期的32位乘法。
因此,存储区的合理分配策略是,flash和ramx以及sram0需要分配给cortex-m4f内核,分别用于存放指令代码和操作数(见上图红/黄框部分)。而sram1/sram2这两块需要分给cortex-m0+(见上图绿色框部分)。 需要注意的是,只要其中一个ram块分配给某个cpu核,这个ram块就不能分配给另一个cpu核, 否则这两个cpu核同时访问同一块区域时,就会出现总线争用,而导致另一个cpu核访问出现等待周期,从而降低整个系统处理效率。
双核运行的功耗如何?
在回答这个问题之前,让我们看一下其实测的coremark动态功耗图吧:
以代码放在flash中运行并且主频为48mhz为例,cortex-m4f动态功耗大约为96ua/mhz,而cortex-m0+为75ua/mhz。两者之和为171ua/mhz,也就是说双核同时运行时的功耗为8.2ma。这个功耗比许多其他厂家的单cortex-m4f核的mcu还低,但性能要强很多。
当然如果你比较关心功耗,可以根据应用实际情况让一个cpu内核进入低功耗模式,另一个cpu内核工作,等到一定条件时再唤醒另一个核。
双核之间怎么通信?
下面这张图说明了俩核之间的通信机制。
当一个cpu内核准备好数据之后,通过互锁信号放在共享ram中,再通过邮箱机制产生中断事件,通知另一个cpu内核来处理。另一个cpu内核处理完数据后,清理相应的中断标志。通过这种方式可以实现实时性很强的双核通信和数据交换。也可以不用互锁信号和共享ram,直接通过邮箱机制传递最多32位的数据。
另外一种简单的方法叫作消息队列机制:直接在共享ram中创建循环缓冲器用于消息队列。当一个cpu内核准备好数据之后,就把数据发送到这个队列最后面(队尾),而另一cpu内核每次从这个队列的最前面取数据。对每个队列的访问是单向的,即一个cpu核只能写,而另一个cpu内核只能读。要实现双向,必须创建至少两个队列。 这种方法可以不用互锁信号,但可以使用中断机制通知另一个cpu核,以便实现实时通信和数据交换。
双核的开发很难吗?
针对双核以及多核体系架构,恩智浦提供了多核sdk开发库(称为mcsdk), 以及丰富的例程,包含在相应多核平台的mcuxpresso sdk 开发包中。 下图显示了mcsdk的架构:
erpc即嵌入式远程过程调用(embedded remote procedure call),是一套实现调用另一核上远程服务的透明函数调用接口。mcmgr即多核管理器(multicore manager),是包含所有cpu内核信息及启动从核的函数调用接口。rpmsg-lite即远程处理器消息机制精简版(remote processor messaging – lite),包含了所有处理器间通信的函数库。
这套库支持市面上所有主流arm cortex-m软件开发工具,包括iar、keil、gcc,以及mcuxpresso ide。
有了这套多核sdk开发库,用户可以不用关心硬件底层的通信机制,直接使用相应的例程和调用接口,几分钟内便可以实现双核间的通信和数据交换代码。
下面这个例子说明如何使用rpmsg-lite,从一个cpu内核发送数据到另一内核:
rpmsg_lite_send(my_rpmsg, my_ept, remote_ept_addr, (char *)&msg,sizeof(msg), …);
其中my_rpmsg是rpmsg_lite_remote_init()或rpmsg_lite_master_init()调用所创建的rpmsg实例;如果是主cpu内核,就用rpmsg_lite_master_init()初始化, 否则就是远程cpu内核,用rpmsg_lite_remote_init()初始化
my_ept是此消息管道的端点,由rpmsg_lite_create_ept()调用创建的:
my_ept = rpmsg_lite_create_ept(my_rpmsg, local_ept_addr, …);
msg是真正要交换的消息。
remote_ept_addr,local_ept_addr分别是此消息管道的远程端点和本地端点的逻辑地址。
怎么调试双核应用程序?
在回答这个问题之前,先看一下硬件调试接口图:
上图说明,lpc5411x 系列支持对双核同时调试 ,就像调试单个cpu内核程序一样简单。
小米在AI专利申请数量上逆袭超华为?国家电网才是AI领域的大Boss?
浅谈电机的重要性及电机运维常用测试仪器
CAN/RS-485总线为什么要隔离
基于单片机实现CAN总线与LIN总线间的传输设计方案
HTC正式面向国内市场发布了升级版VR一体机Vive Focus Plus
双核MCU开发其实也不难!
上海市人民政府出台《上海市促进在线新经济发展行动方案(2020—2022年)》
KT表示2019年底会将5G网络服务覆盖到韩国的85个主要城市
土壤生态环境测试及分析评价系统设备的介绍
单片机最小系统的振荡电路原理分析
乔安户外摄像机怎么样 安防类智能家居中必不可少的户外监控
云计算助力下 远程医疗成本不断下降
gd32的全系列芯片有哪些?
一个简单的IC723应用电路分享
适合学生党的移动电源有哪些?学生党移动电源推荐
为什么深硅刻蚀中C4F8能起到钝化作用?
AMD Ryzen处理器的所有者已经可以大大改善游戏的性能
寻求转型之路 汽车产品成松下支柱产业
NRG Systems推出多输出信号风机控制传感器
AI框架技术演进 AI框架的六大技术趋势