信息流如下图
--------------------------------------------ARM端------------------------------------------
status = MESSAGE_Create (dspExecutable,strNumIterations,processorId) ;
--------PROC_setup()
--------PROC_attach()
--------POOL_open()
--------status = MSGQ_open (SampleGppMsgqName, &SampleGppMsgq, NULL) ; //打开GPP 消息队列
--------status = MSGQ_setErrorHandler (SampleGppMsgq,POOL_makePoolId(processorId,SAMPLE_POOL_ID)) ;//
--------status = PROC_load (processorId, (Char8 *) &imageInfo, numArgs, args) ;//把可执行程序下载到DSP端
--------status = PROC_start (processorId) ; //让DSP开始执行程序
--------status = MSGQ_transportOpen (processorId, &mqtAttrs) ; //打开远程传输
--------status = MSGQ_locate (dspMsgqName,&SampleDspMsgq,&syncLocateAttrs) ;//定位DSP的消息队列
status = MESSAGE_Execute (numIterations,processorId) ;
--------status = MSGQ_get (SampleGppMsgq, WAIT_FOREVER, &msg) ; //接收消息
--------status = MESSAGE_VerifyData (msg, sequenceNumber) ; //验证数据
--------if ((numIterations != 0) && (i == (numIterations + 1))) { //如果接收到的是最后一个数据,则释放
MSGQ_free (msg) ;
--------status = MSGQ_put (SampleDspMsgq, msg) ; //把之前接收到的消息再发回去
MESSAGE_Delete()
--------status = MSGQ_release (SampleDspMsgq) ; //释放远程传输消息队列
--------tmpStatus = MSGQ_transportClose (processorId) ;//关闭远程传输
--------tmpStatus = PROC_stop (processorId) ; //让DSP停止执行
-------- tmpStatus = MSGQ_setErrorHandler (MSGQ_INVALIDMSGQ, MSGQ_INVALIDMSGQ) ;
--------tmpStatus = MSGQ_close (SampleGppMsgq) ; //关闭GPP的消息队列
--------tmpStatus = POOL_close (POOL_makePoolId(processorId, SAMPLE_POOL_ID)) ;//关闭POOL
--------tmpStatus = PROC_detach (processorId) ; //与处理器分离
--------tmpStatus = PROC_destroy () ; //释放PROC
--------------------------------------------DSP端------------------------------------------
SWI MODE
DSPLINK_init()
status = SWIMESSAGE_create (&info) ;
--------status = POOL_open (0, &poolObj) ;
--------status = MSGQ_transportOpen (ID_GPP, &transport) ;
--------*infoPtr = MEM_calloc (DSPLINK_SEGID,sizeof (SWIMESSAGE_TransferInfo),DSPLINK_BUF_ALIGN) ;//分配消息结构体
--------swiAttrs.fxn = messageSWI ; //创建软件中断函数
--------status = MSGQ_locateAsync (GPP_MSGQNAME,info->localMsgq,&asyncLocateAttrs) ;
--------status = MSGQ_get (info->localMsgq, &msg, 0) ;
--------判断数据:
1 if (status == SYS_OK) { 2 /* Handle the received message */ 3 switch (MSGQ_getMsgId (msg)) { 4 case MSGQ_ASYNCLOCATEMSGID: 5 info->locatedMsgq = ((MSGQ_AsyncLocateMsg *) msg)->msgqQueue ; 6 7 /* Must free the message */ 8 MSGQ_free (msg) ; 9 10 /* Allocate and send the first message */ 11 status = MSGQ_alloc (SAMPLE_POOL_ID, 12 &msg, 13 APP_BUFFER_SIZE) ; 14 if (status == SYS_OK) { 15 MSGQ_setMsgId (msg, info->sequenceNumber) ; 16 status = MSGQ_put (info->locatedMsgq, msg) ; 17 if (status != SYS_OK) { 18 /* Must free the message */ 19 MSGQ_free (msg) ; 20 SET_FAILURE_REASON (status) ; 21 } 22 } 23 else { 24 SET_FAILURE_REASON (status) ; 25 } 26 break ; 27 28 case MSGQ_ASYNCERRORMSGID: 29 LOG_printf(&trace, "Transport error Type = %d", 30 ((MSGQ_AsyncErrorMsg *) msg)->errorType) ; 31 32 /* Must free the message */ 33 MSGQ_free (msg) ; 34 status = SYS_EBADIO ; 35 SET_FAILURE_REASON (status) ; 36 break ; 37 38 default: 39 /* Check to make sure correct message is received */ 40 if (MSGQ_getMsgId (msg) != info->sequenceNumber) { 41 LOG_printf(&trace, "Out of sequence message!"); 42 status = SYS_EBADIO ; 43 SET_FAILURE_REASON (status) ; 44 } 45 else { 46 /* Increment the sequenceNumber for next received message */ 47 info->sequenceNumber++ ; 48 if (info->sequenceNumber == MSGQ_INTERNALIDSSTART) { 49 info->sequenceNumber = 0 ; 50 } 51 MSGQ_setMsgId (msg, info->sequenceNumber) ; 52 /* Send the message back */ 53 status = MSGQ_put (info->locatedMsgq, msg) ; 54 if (status != SYS_OK) { 55 SET_FAILURE_REASON (status) ; 56 }
-------info->swi = SWI_create (&swiAttrs) ; //为接收和发送消息创建软件中断(SWI)
--------msgqAttrs.notifyHandle = info->swi; //创建消息队列
msgqAttrs.post = (MSGQ_Post) SWI_post ;
msgqAttrs.pend = NULL ;
--------status = MSGQ_open ((String )dspMsgQName, &info->localMsgq, &msgqAttrs) ;//打开消息队列
--------MSGQ_setErrorHandler (info->localMsgq, SAMPLE_POOL_ID) ;
--------SWI_post (info->swi) ;//提交消息软件中断
TSK MODE
tskMessage()
TSKMESSAGE_create()
--------DSPLINK_init()
--------status = TSKMESSAGE_create (&info) ;
--------status = POOL_open (0, &poolObj) ;
--------status = MSGQ_transportOpen (ID_GPP, &transport) ;
--------*infoPtr = MEM_calloc (DSPLINK_SEGID,sizeof (TSKMESSAGE_TransferInfo),DSPLINK_BUF_ALIGN) ;
--------SEM_new (&(info->notifySemObj), 0) ;
SEM 模块用于任务的同步和互斥,SEM_new()用于初始化信号量对象
--------msgqAttrs.notifyHandle = &(info->notifySemObj) ;//为此消息队列填充属性
msgqAttrs.pend = (MSGQ_Pend) SEM_pendBinary ;
msgqAttrs.post = (MSGQ_Post) SEM_postBinary ;
----------status = MSGQ_open ((String )dspMsgQName, &info->localMsgq, &msgqAttrs) ;//创建消息队列
----------MSGQ_setErrorHandler (info->localMsgq, SAMPLE_POOL_ID) ;
----------status = MSGQ_locate (GPP_MSGQNAME,&info->locatedMsgq,&syncLocateAttrs) ;//同步定位
status = TSKMESSAGE_execute (info) ;
----------status = MSGQ_alloc (SAMPLE_POOL_ID, &msg, APP_BUFFER_SIZE) ;
分配一个消息,由write端执行
MSGQ 接口函数被用来打开和关闭消息队列、接收和发送消息,
读取方可以调用:MSGQ_open、MSGQ_get、MSGQ_free、MSGQ_close
填写方可以调用:MSGQ_locate or MSGQ_locateAsync、MSGQ_alloc、MSGQ_put、MSGQ_release
----------MSGQ_setMsgId (msg, info->sequenceNumber) ;
----------MSGQ_setSrcQueue (msg, info->localMsgq) ;//从消息中提取应答目的地
--------status = MSGQ_put (info->locatedMsgq, msg) ;
--------status = MSGQ_get (info->localMsgq, &msg, SYS_FOREVER) ;//接收一个消息
--------MSGQ_setMsgId (msg, info->sequenceNumber) ;//把接收到的数据发送回去
MSGQ_setSrcQueue (msg, info->localMsgq) ;
status = MSGQ_put (info->locatedMsgq, msg) ;
status = TSKMESSAGE_delete (info) ;
--------- status = MSGQ_release (info->locatedMsgq) ;
---------MSGQ_setErrorHandler (MSGQ_INVALIDMSGQ, POOL_INVALIDID) ;
---------tmpStatus = MSGQ_close (info->localMsgq) ;
---------freeStatus = MEM_free (DSPLINK_SEGID,info,sizeof (TSKMESSAGE_TransferInfo)) ;//释放消息结构
总结:DSP端使用了SWI 和TSK 两种方式来实现了message的发送和接收。