MessageQ模块:主核(核0)在将图像文件输入共享内存后,需要将输入图像缓存和输出图像缓存的地址打包成消息,传递给从核。总之,MessageQ是用来传递少量信息的,一般是地址,标志位之类的参数,不是传递大规模数组用的。对于大规模的数组,可以利用messageQ传递其首地址。
MessageQ模块的主要特点:
1. 实现了处理期间变长消息的传递,所需要传递的消息一般超过32bit;
2. 其消息的传递都是通过操作消息队列来实现的;
3. 每个消息队列可以有多个写者,但只能有一个读者,而每个任务(task)可以对多个消息队列进行读写;
4. 一个宿主在准备接收消息时,必须先创建消息队列,而在发送消息前,需要打开预定的接收消息队列;
很关键的一点就是 谁接收,谁创建( messageQ_create() )
谁发送,谁打开( messageQ_open() )
MessageQ的使用过程:
一、cfg文件的配置
var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
var Ipc = xdc.useModule('ti.sdo.ipc.Ipc');
var HeapBufMP = xdc.useModule('ti.sdo.ipc.heaps.HeapBufMP');
var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
/* BIOS/XDC modules */
var BIOS = xdc.useModule('ti.sysbios.BIOS');
BIOS.heapSize = 0x8000;
BIOS.heapSection = "systemHeap";
二、heapBufMP的创建
heapBufMP的创建在主核完成(应该也可以在从核创建)
HeapBufMP_Handle heapHandle;
HeapBufMP_Params heapBufParams;
/*Create the heap that will be used to allocate messages. */
HeapBufMP_Params_init(&heapBufParams);
heapBufParams.regionId = 0;
heapBufParams.name = HEAP_NAME;
heapBufParams.numBlocks = 16;
heapBufParams.align = 128; //对齐方式
heapBufParams.blockSize = sizeof(MessageQ_MsgHeader);
heapHandle = HeapBufMP_create(&heapBufParams);
if (heapHandle == NULL)
{
System_abort("HeapBufMP_create failed
" );
}
do {
status = HeapBufMP_open(HEAP_NAME, &heapHandle);
if (status < 0) {
Task_sleep(1);
}
} while (status < 0);
三、messageQ的创建
谁接收,谁创建的原则。如果是主核通知从核,那么需要在从核函数中进行创建。
//从核
MessageQ_Msg msg;
MessageQ_Handle messageQ;
MessageQ_QueueId remoteQueueId;
Int status;
HeapBufMP_Handle heapHandle;
/* Register this heap with MessageQ */
MessageQ_registerHeap((IHeap_Handle)heapHandle, HEAPID);
/* Create the local message queue */
messageQ = MessageQ_create(localQueueName, NULL);
if (messageQ == NULL)
{
System_abort("MessageQ_create failed
" );
}
四、messageQ打开
谁发送,谁打开。主核要通知从核一些事情,那么在从核创建了messageQ之后,主核来打开这个messageQ。打开之后分配空间。
status = MessageQ_open(slaveQueueName[i], &remoteQueueId[i]);
//给头部分配空间
msg[i] = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader));
if (msg[i] == NULL)
{
System_abort("MessageQ_alloc failed
" );
}
五、messageQ发送
主核在打开之后,完成数据的发送。这里的remoteQueueId是上一步MessageQ_open的输出
/****************************************************************/
/* broadcast messages to core 0 - core number_of_cores-1 */
/****************************************************************/
void BroadcastMessages(
MessageQ_QueueId *remoteQueueId,
MessageQ_Msg *msg,
const UInt16 msgId,
const UInt16 number_of_cores )
{
Int status;
Int i;
/* Send messages to process the cores */
for(i = 0;i < number_of_cores;i++)
{
//设置msg中的msgId
MessageQ_setMsgId(msg[i], msgId);
/* 发送messageQ 从核创建的messageQ */
status = MessageQ_put(remoteQueueId[i], msg[i]);
if (status < 0)
{
System_abort("MessageQ_put had a failure/error
");
}
}
}
六、messageQ接收
对于messageQ接收来说,从核需要接收数据,因此在从核完成接收过程。接收完毕之后进行从核内部自己的处理
status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
if (status < 0)
{
System_abort("This should not happen since timeout is forever
");
}
//判断收到的msg的ID是否等于1
if(MessageQ_getMsgId(msg) == 1)
{
mc_process();
}
总结一下:
主核如果给从核发送messageQ,步骤如下
1 主核创建heapBufMP
2 从核创建messageQ messageQ_create()
3 主核打开messageQ messageQ_open()
4 主核分配空间 messageQ_alloc()
5 主核发送messageQ messageQ_put()
6 从核接收messageQ messageQ_get()
7 从核处理函数
整体流程结束。下一篇介绍一个具体的messageQ项目。
=======================================================================
最近新开的公众号,文章正在一篇篇的更新,
公众号名称:
玩转电子世界
各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。
跟着阳光非宅男,一步步走进电子的世界。
关注之后回复 资料下载 关键词可以获得
免费海量的视频学习资料
免费海量的视频学习资料下载~~!
已共享的学习视频资料,共享资料正在不断更新中。
=======================================================================