OMAPL138学习----DSPLINK DEMO解析之READWRITE
READWRITE 示例阐明了大缓冲区通过直接读写 DSP 内部 RAM 来进行传输的概念。它实现了在 GPP 端和使用 PROC_Read()和 PROC_Write() API 的 DSP 端以及两个 DSP 端之间的大尺寸数据缓冲器之间的数据与信息的传递和转换。DSP 端应用程序采用 MSGQ 实现了 TSK。
------------------------------------------------GPP端----------------------------------------------------
status = RDWR_Create (dspExecutable,strBufferSize,strNumIterations,processorId)
-------- status = PROC_setup (NULL) ;
--------status = PROC_attach (processorId, NULL) ;
--------status = POOL_open (POOL_makePoolId(processorId, SAMPLE_POOL_ID),&SamplePoolAttrs) ;
--------status = MSGQ_open (SampleGppMsgqName, &SampleGppMsgq, NULL) ; //打开GPP端消息队列
--------status = PROC_load (processorId,(Char8 *) &imageInfo,NUM_ARGS,args) ;
--------status = PROC_start (processorId) ;
--------mqtAttrs.poolId = POOL_makePoolId(processorId, SAMPLE_POOL_ID) ; //打开远程传输
status = MSGQ_transportOpen (processorId, &mqtAttrs) ;
--------status = MSGQ_locate (SampleDspMsgqName,&SampleDspMsgq,&syncLocateAttrs) ; //定位DSP消息队列
status = RDWR_Execute (dspAddress,bufferSize,numIterations,processorId) ;
--------status = RDWR_AllocateBuffer (bufferSize, (Pvoid *) &bufIn) ;
RDWR_AllocateBuffer (IN Uint32 size, OUT Pvoid * buf) { DSP_STATUS status = DSP_SOK ; *buf = malloc (size) ; if (*buf == NULL) { status = DSP_EMEMORY ; } return status ; }
--------确定DSP内存区
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ptr8 = (Uint8 *) (bufIn) ; 2 ptr16 = (Uint16 *) (bufIn) ; 3 for (j = 0 ; 4 DSP_SUCCEEDED (status) && (j < bufferSize / DSP_MAUSIZE) ; 5 j++) { 6 if (DSP_MAUSIZE == 1) { 7 *ptr8 = 0 ; 8 ptr8++ ; 9 } 10 else if (DSP_MAUSIZE == 2) { 11 *ptr16 = 0 ; 12 ptr16++ ; 13 } 14 }
--------status = PROC_write (processorId, dspAddr2, bufferSize, bufIn) ;
--------初始化数据为1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ptr8 = (Uint8 *) (bufOut) ; 2 ptr16 = (Uint16 *) (bufOut) ; 3 for (j = 0 ; 4 DSP_SUCCEEDED (status) && (j < (bufferSize / DSP_MAUSIZE)) ; 5 j++) { 6 if (DSP_MAUSIZE == 1) { 7 *ptr8 = 0x1 ; 8 ptr8++ ; 9 } 10 else if (DSP_MAUSIZE == 2) { 11 *ptr16 = CONVERT_ENDIANISM (0x1) ; 12 ptr16++ ; 13 } 14 }
--------status = PROC_write (processorId, dspAddr1, bufferSize, bufOut) ; //写数据到DSP
--------验证DSP侧数据缓冲是否被写
if (DSP_SUCCEEDED (status)) { status = MSGQ_alloc (POOL_makePoolId(processorId, SAMPLE_POOL_ID), APP_MSG_SIZE, (MSGQ_Msg *) &msg) ; if (DSP_SUCCEEDED (status)) { /* Set the message id as the scaling factor */ #if (defined (OMAP) && defined (PCPY_LINK)) || defined (WORD_SWAP) msg->gppWriteAddr = WORDSWAP_LONG ((dspAddr1 / DSP_MAUSIZE)) ; msg->dspWriteAddr = WORDSWAP_LONG ((dspAddr2 / DSP_MAUSIZE)) ; msg->size = WORDSWAP_LONG ((bufferSize/ DSP_MAUSIZE)) ; msg->scalingFactor = WORDSWAP_LONG (i) ; #else /* if (defined (OMAP) && defined (PCPY_LINK)) || defined (WORD_SWAP) */ msg->gppWriteAddr = (dspAddr1 / DSP_MAUSIZE) ; msg->dspWriteAddr = (dspAddr2 / DSP_MAUSIZE) ; msg->size = (bufferSize / DSP_MAUSIZE) ; msg->scalingFactor = i ; #endif /* if (defined (OMAP) && defined (PCPY_LINK)) || defined (WORD_SWAP) */ /* Send the message */ status = MSGQ_put (SampleDspMsgq, (MSGQ_Msg) msg) ; if (DSP_FAILED (status)) { RDWR_1Print ("MSGQ_put failed. Status: [0x%x]\n", status) ; } } else { RDWR_1Print ("MSGQ_alloc failed. Status: [0x%x]\n", status) ; }
--------等待DSP回发确认数据被写入的消息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 if (DSP_SUCCEEDED (status)) { 2 status = MSGQ_get (SampleGppMsgq, WAIT_FOREVER, (MSGQ_Msg *) &msg) ; 3 if (DSP_SUCCEEDED (status)) { 4 status = MSGQ_free ((MSGQ_Msg) msg) ; 5 if (DSP_FAILED (status)) { 6 RDWR_1Print ("MSGQ_free failed. Status: [0x%x]\n", 7 status) ; 8 } 9 } 10 else { 11 RDWR_1Print ("MSGQ_get failed. Status: [0x%x]\n", status) ; 12 } 13 }
-------- status = PROC_read (processorId, dspAddr2, bufferSize, bufIn) ; //从DSP内存中读取数据
--------验证回读的数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 if (DSP_SUCCEEDED (status)) { 2 ptr8 = (Uint8 *) bufIn ; 3 ptr8_1 = (Uint8 *) bufOut ; 4 ptr16 = (Uint16 *) bufIn ; 5 ptr16_1 = (Uint16 *) bufOut ; 6 for (j = 0 ; 7 (j < (bufferSize / DSP_MAUSIZE)) && DSP_SUCCEEDED (status); 8 j++) { 9 if (DSP_MAUSIZE == 1) { 10 if (ptr8 [j] != (Uint8) (ptr8_1 [j] * i)) { 11 RDWR_1Print ("Data mismatch at [0x%x]\n", j) ; 12 RDWR_1Print (" Expected [0x%x]\n", (ptr8_1 [j] * i)) ; 13 RDWR_1Print (" Received [0x%x]\n", ptr8 [j]) ; 14 status = DSP_EFAIL ; 15 } 16 } 17 else if (DSP_MAUSIZE == 2) { 18 if ( CONVERT_ENDIANISM (ptr16 [j]) 19 != (Uint16) (CONVERT_ENDIANISM (ptr16_1 [j]) * i)) { 20 RDWR_1Print ("Data mismatch at [0x%x]\n", j) ; 21 RDWR_1Print (" Expected [0x%x]\n", 22 (CONVERT_ENDIANISM (ptr16_1 [j]) * i)) ; 23 RDWR_1Print (" Received [0x%x]\n", 24 CONVERT_ENDIANISM (ptr16 [j])) ; 25 status = DSP_EFAIL ; 26 } 27 } 28 } 29 30 if ((i % 100) == 0) { 31 RDWR_1Print ("Verified %5d Iterations of " 32 "Correct Data Read/ Write\n", i) ; 33 } 34
RDWR_Delete (processorId) ;
--------status = MSGQ_release (SampleDspMsgq) ;
--------status = MSGQ_transportClose (processorId) ;
--------tmpStatus = PROC_stop (processorId) ;
--------tmpStatus = MSGQ_close (SampleGppMsgq) ;
-------- tmpStatus = POOL_close (POOL_makePoolId(processorId, SAMPLE_POOL_ID)) ;
--------tmpStatus = PROC_detach (processorId) ;
--------tmpStatus = PROC_destroy () ;
--------tmpStatus = RDWR_OS_exit () ;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
RDWR_OS_exit(Void) { DSP_STATUS status = DSP_SOK ; return status ; }
------------------------------------------------GPP端----------------------------------------------------
DSPLINK_init()
status = TSKRDWR_create (&info);
--------status = POOL_open (0, &poolObj) ;
--------status = MSGQ_transportOpen (ID_GPP, &transport) ;
--------*infoPtr = MEM_calloc (DSPLINK_SEGID,sizeof (TSKRDWR_TransferInfo),DSPLINK_BUF_ALIGN) ;
--------GPP端等待DSP打开一个消息队列,DSP首次打开本地消息队列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 if (status == SYS_OK) { 2 /* Set the semaphore to a known state. */ 3 SEM_new (&(info->notifyDspSemObj), 0) ; 4 5 /* Fill in the attributes for this message queue. */ 6 msgqAttrs.notifyHandle = &(info->notifyDspSemObj) ; 7 msgqAttrs.pend = (MSGQ_Pend) SEM_pendBinary ; 8 msgqAttrs.post = (MSGQ_Post) SEM_postBinary ; 9 10 /* Creating message queue */ 11 status = MSGQ_open (DSP_MSGQNAME, &info->dspMsgqQueue, &msgqAttrs) ; 12 if (status != SYS_OK) { 13 SET_FAILURE_REASON (status) ; 14 } 15 }
--------定位GPP的消息队列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 if (status == SYS_OK) { 2 /* Synchronous locate. */ 3 status = SYS_ENOTFOUND ; 4 while ((status == SYS_ENOTFOUND) || (status == SYS_ENODEV)) { 5 syncLocateAttrs.timeout = SYS_FOREVER ; 6 status = MSGQ_locate (GPP_MSGQNAME, 7 &info->gppMsgqQueue, 8 &syncLocateAttrs) ; 9 if ((status == SYS_ENOTFOUND) || (status == SYS_ENODEV)) { 10 TSK_sleep (1000) ; 11 } 12 else if (status != SYS_OK) { 13 LOG_printf (&trace, "MSGQ_locate (msgqOut) failed. " 14 "Status = 0x%x\n", status) ; 15 } 16 } 17 }
status = TSKRDWR_execute (info);
--------等待关于数据缓冲区信息的消息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 for (i = 0 ; 2 ( ((info->numTransfers == 0) || (i < info->numTransfers)) 3 && (status == SYS_OK)) ; 4 i++) { 5 /* Wait for the messaging containing information about data buffer */ 6 status = MSGQ_get (info->dspMsgqQueue, (MSGQ_Msg *) &msg, SYS_FOREVER) ; 7 if (status == SYS_OK) { 8 readBuf = (Char *) msg->gppWriteAddr ; 9 writeBuf = (Char *) msg->dspWriteAddr ; 10 size = msg->size ; 11 scalingFactor = msg->scalingFactor ; 12 13 HAL_cacheInv ((Ptr) readBuf, size) ; 14 15 for (j = 0 ; j < size ; j++) { 16 writeBuf [j] = (Char) (readBuf [j] * scalingFactor) ; 17 } 18 19 HAL_cacheWbInv ((Ptr)(msg->dspWriteAddr), size) ; 20 21 /* Now send a message to the GPP */ 22 status = MSGQ_put (info->gppMsgqQueue, (MSGQ_Msg) msg) ; 23 if (status != SYS_OK) { 24 SET_FAILURE_REASON(status); 25 } 26 } 27
status = TSKRDWR_delete (info);
-------- status = MSGQ_close (info->dspMsgqQueue) ;
--------freeStatus = MEM_free(DSPLINK_SEGID, info, sizeof (TSKRDWR_TransferInfo)); //释放信息结构体