从去年10月份开始学习lpc4357双核开发板,双核最主要的难点就是如何实现M4与M0的通信。nxp提供了3种通信机制,结合自己的理解整理如下:
1.Interrupt
M4与M0各自有自己的NVIC控制机器,自然就有自己的中断向量表,与以往单核不同的是,M4的中断向量表里面多了一个M0CORE_IRQHandler(称之为来自m0的中断),M0多了一个M4CORE_IRQHandler(称之为来自m4的中断)。也就是说M4可以中断M0,M0也可以中断M4。这种中断方式的通信只是作为简单的通知事件,并没有实际的数据传输。如果一个核想要中断另一个核,它只需要执行一个SEV指令(由Cortex结构提供)。那么远方的核(执行SEV指令的的核称之为local core)就会跳转到中断处理函数去执行。在中断处理函数中,我们可以做一些简单的操作,比如点亮或者关闭led。
2.Message queue
这种方式我们称之为消息队列,在内存区域中分配2个buffer,一个为CMD_BUFFER,一个为MSG_BUFFER。每个buffer都有以下4个量进行定义,QstartAddress、QendAddress、RdPtr、WrPtr。CMD_BUFFER只允许M4往里面写,M0从里面读;MSG_BUFFER只允许M0往里面写,M4从里面读。每写完一次WrPtr++、每读完一次RdPtr++。由于M4与M0读写的地址不一样,这样就不出会出现同时往同一个地址写所产生的冲突。再往队列写之前都要先查看下队列的状态,若队列不是满的(判断队列的状态分好几种情况,这里只简单介绍一种,如果WrPtr+size>=RdPtr,就认为队列为满,不能插入新的数据),那么就往里面写数据,并WrPtr++,然后通知远方的处理器。规定WrPtr==RdPtr时,队列的状态为空。远方的处理器在接收到来自另外的一个处理器发来的中断后,就从队列里读出数据(首先先判断队列不为空)。从M4发出的command的形式有以下2种:
第一个为读命令,没有实际的数据传递,只作为通知事件使用。第二个命令为写命令,后跟一个32bit的参数。
从M0发出的message的类型有以下几种:
实际使用中只需要关心第二个带参数的msg即可。
3.Mailbox
这种通信方式的命名来源于生活中的邮箱,因为它们非常相似。每个处理器可以有一个或者多个邮箱。每个邮箱有以下几个参数进行定义:
Message type(消息的类型)
Message id(消息的ID号)
32- bit parameter(32位的参数)
Callback function(回调函数)
每个邮箱有几下几种状态:
1.READY(邮箱处于就绪状态,可以往里面写消息)
2.PROCESS(书写消息完成)
3.BUSY(正在处理消息)
4.ERROR(错误)
每个处理器只能从自己的邮箱里读数据,向另外一个处理器的邮箱里写数据(就像我们只能往别人家的信箱投递信件,而只能从自己家的信箱取信件一样)。在写数据之前首先要询问邮箱的状态,如果为ready,即可写入,否则不能写。写完之后就通过中断通知remote core读取数据。
以上三种通信方式,中断只是用于简单的通知时间,邮箱和消息队列才是双核之间相互传递数据的方法。