DSP- 6678---------messageQ的使用

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\n" );
    }

    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\n" );
    }

四、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\n" );
    }

五、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\n");
        }
    }
}

六、messageQ接收
对于messageQ接收来说,从核需要接收数据,因此在从核完成接收过程。接收完毕之后进行从核内部自己的处理

    status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
    if (status < 0)
    {
       System_abort("This should not happen since timeout is forever\n");
    }

    //判断收到的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项目。

猜你喜欢

转载自blog.csdn.net/yunge812/article/details/80882556
dsp