RING_IO 示例闡明瞭如何使用 DSP/BIOS LINK 中的 RingIO 部件以及在 GPP 與使用兩個RingIO 實例的 DSP 之間的數據流的方法。它實現了數據在 GPP 端運行的線程/進程的應用程序和 DSP 端之間的傳遞與轉換。在 Linux 中,這個應用程序在某個過程當中經過進程或者線程來運行。在 PrOS 中,它經過一系列任務來運行。在隨後的部分應用程序中的每一個線程/進程/被視爲客戶端。DSP端使用RingIO實現TSK。app
------------------------------------GPP端-------------------------------------------------ide
RING_IO_BufferSize = DSPLINK_ALIGN (RING_IO_Atoi (strBufferSize),DSPLINK_BUF_ALIGN) ; //驗證指定緩衝區大小函數
status = RING_IO_Create (dspExecutable,strBufferSize,strBytesToTransfer,processorId) ;oop
--------status = RING_IO_OS_init () ;post
--------status = PROC_setup (NULL) ;ui
--------status = PROC_attach (processorId, NULL) ;spa
--------status = POOL_open (POOL_makePoolId(processorId, SAMPLE_POOL_ID), &poolAttrs)線程
--------status = PROC_load ( processorId,(Char8 *) &imageInfo,numArgs,args) ;rest
--------status = RingIO_create (processorId, RingIOWriterName, &ringIoAttrs) ;code
--------status = PROC_start (processorId) ;
status = RING_IO_Create_client(&writerClientInfo,(Pvoid)RING_IO_WriterClient, NULL) ;
-------processId = fork() ; //建立一個子進程
------- retStatus = RING_IO_getLinkAccess(pInfo->processorId); //在子進程中,爲子進程獲取進入限
--------lptrToFun = funcPtr; //調用用戶程序
--------調用RING_IO_WriterClient()
--------RingIOWriterHandle = RingIO_open (RingIOWriterName,RINGIO_MODE_WRITE,(Uint32)(RINGIO_NEED_EXACT_SIZE)) ; //GPP以wirter的身份打開RingIO
--------status = RING_IO_CreateSem (&semPtrWriter) ; //爲通知建立一個信號量
--------status = RingIO_setNotifier (RingIOWriterHandle,RINGIO_NOTIFICATION_ONCE,RING_IO_WRITER_BUF_SIZE,&RING_IO_Writer_Notify,(RingIO_NotifyParam) semPtrWriter) ; //爲GPP建立的RingIO創建通知程序
--------RING_IO_Writer_Notify()
1 RING_IO_Writer_Notify (IN RingIO_Handle handle, 2 IN RingIO_NotifyParam param, 3 IN RingIO_NotifyMsg msg) 4 { 5 DSP_STATUS status = DSP_SOK ; 6 7 /* Post the semaphore. */ 8 status = RING_IO_PostSem ((Pvoid) param) ; 9 if (DSP_FAILED (status)) { 10 RING_IO_1Print ("RING_IO_PostSem () failed. Status = [0x%x]\n", 11 status) ; 12 } 13 }
--------status = RingIO_setAttribute(RingIOWriterHandle,0,type,0) ;
--------status = RingIO_sendNotify (RingIOWriterHandle,(RingIO_NotifyMsg)NOTIFY_DATA_START);
---------status = RingIO_setvAttribute (RingIOWriterHandle,0, /* at the beginning */0, /* No type */0,attrs,sizeof (attrs)) ;
--------status = RingIO_acquire (RingIOWriterHandle,&bufPtr ,&acqSize) ; //
--------若是請求成功,則向ring緩衝區寫數據,而後釋放
1 if ((DSP_SUCCEEDED (status)) && (acqSize > 0)) { 2 RING_IO_InitBuffer (bufPtr, acqSize) ; 3 4 if ( (RING_IO_BytesToTransfer != 0) 5 && ( (bytesTransfered + acqSize) 6 > RING_IO_BytesToTransfer)) { 7 8 /* we have acquired more buffer than the rest of data 9 * bytes to be transferred */ 10 if (bytesTransfered != RING_IO_BytesToTransfer) { 11 12 relStatus = RingIO_release (RingIOWriterHandle, 13 (RING_IO_BytesToTransfer- 14 bytesTransfered)) ; 15 if (DSP_FAILED (relStatus)) { 16 RING_IO_1Print ("RingIO_release () in Writer " 17 "task failed relStatus = [0x%x]" 18 "\n" , relStatus) ; 19 } 20 } 21 22 /* Cancel the rest of the buffer */ 23 status = RingIO_cancel (RingIOWriterHandle) ; 24 if (DSP_FAILED(status)) { 25 RING_IO_1Print ("RingIO_cancel () in Writer" 26 "task failed " 27 "status = [0x%x]\n", 28 status) ; 29 } 30 bytesTransfered = RING_IO_BytesToTransfer; 31 32 } 33 else { 34 35 relStatus = RingIO_release (RingIOWriterHandle, 36 acqSize) ; 37 if (DSP_FAILED (relStatus)) { 38 RING_IO_1Print ("RingIO_release () in Writer task " 39 "failed. relStatus = [0x%x]\n", 40 relStatus) ; 41 } 42 else { 43 bytesTransfered += acqSize; 44 } 45 } 46 47 if ((bytesTransfered % (RING_IO_WRITER_BUF_SIZE * 8u)) == 0) 48 { 49 RING_IO_1Print ("GPP-->DSP:Bytes Transferred: %lu \n", 50 bytesTransfered) ; 51 } 52 } 53 else { 54 55 /* Acquired failed, Wait for empty buffer to become 56 * available. 57 */ 58 status = RING_IO_WaitSem (semPtrWriter) ; 59 if (DSP_FAILED (status)) { 60 RING_IO_1Print ("RING_IO_WaitSem () Writer SEM failed " 61 "Status = [0x%x]\n", 62 status) ; 63 } 64 } 65 } 66
--------Send End of data transfer attribute to DSP
1 type = (Uint16) RINGIO_DATA_END ; 2 3 do { 4 status = RingIO_setAttribute (RingIOWriterHandle, 5 0, 6 type, 7 0) ; 8 if (DSP_SUCCEEDED(status)) { 9 RING_IO_1Print ("RingIO_setAttribute succeeded to set the " 10 "RINGIO_DATA_END. Status = [0x%x]\n", 11 status) ; 12 } 13 else { 14 RING_IO_YieldClient () ; 15 } 16 }
--------status = RingIO_sendNotify (RingIOWriterHandle,(RingIO_NotifyMsg)NOTIFY_DATA_END) ;//向讀取者(DSP)發送通知
--------刪除通知使用的信號量
1 if (semPtrWriter != NULL) { 2 tmpStatus = RING_IO_DeleteSem (semPtrWriter) ; 3 if (DSP_SUCCEEDED (status) && DSP_FAILED (tmpStatus)) { 4 status = tmpStatus ; 5 RING_IO_1Print ("RING_IO_DeleteSem () Writer SEM failed " 6 "Status = [0x%x]\n", 7 status) ; 8 }
-------- tmpStatus = RingIO_close (RingIOWriterHandle) ; //關閉GPP讀寫端的RingIO
status = RING_IO_Create_client(&readerClientInfo,(Pvoid)RING_IO_ReaderClient,NULL) ;
-------processId = fork() ; //建立一個子進程
------- retStatus = RING_IO_getLinkAccess(pInfo->processorId); //在子進程中,爲子進程獲取進入限
--------lptrToFun = funcPtr; //調用用戶程序
--------RingIOReaderHandle = RingIO_open (RingIOReaderName,RINGIO_MODE_READ,0) ;
--------status = RING_IO_CreateSem (&semPtrReader) ;
--------status = RingIO_setNotifier (RingIOReaderHandle,RINGIO_NOTIFICATION_ONCE,0,&RING_IO_Reader_Notify,(RingIO_NotifyParam) semPtrReader) ;
--------調用RING_IO_Reader_Notify()
1 RING_IO_Reader_Notify (IN RingIO_Handle handle, 2 IN RingIO_NotifyParam param, 3 IN RingIO_NotifyMsg msg) 4 { 5 DSP_STATUS status = DSP_SOK ; 6 7 switch(msg) { 8 case NOTIFY_DATA_START: 9 fReaderStart = TRUE; 10 break; 11 12 case NOTIFY_DATA_END: 13 fReaderEnd = TRUE; 14 break; 15 16 default: 17 break; 18 } 19 20 /* Post the semaphore. */ 21 status = RING_IO_PostSem ((Pvoid) param) ; 22 if (DSP_FAILED (status)) { 23 RING_IO_1Print ("RING_IO_PostSem () failed. Status = [0x%x]\n", 24 status) ; 25 } 26 }
------ status = RING_IO_WaitSem (semPtrReader) ;
--------status = RingIO_getAttribute (RingIOReaderHandle,&type,¶m) ;
--------status = RingIO_acquire (RingIOReaderHandle,&bufPtr ,&acqSize) ;
--------從DSP端獲取數據緩衝
rcvSize -= acqSize ;
totalRcvbytes += acqSize ;
--------relStatus = RingIO_release (RingIOReaderHandle,acqSize) ; //釋放請求緩衝
--------attrStatus = RingIO_getAttribute (RingIOReaderHandle,&type,¶m) ;
--------若是傳輸程序沒有發出通知,則等待
status = RING_IO_WaitSem (semPtrReader) ; if (DSP_FAILED (status)) { RING_IO_1Print ("RING_IO_WaitSem () Reader SEM failed " "Status = [0x%x]\n", status) ; }
--------tmpStatus = RING_IO_DeleteSem (semPtrReader) ;
---------tmpStatus = RingIO_close (RingIOReaderHandle) ;
--------RING_IO_Exit_client (RING_IO_ClientInfo *pInfo)
RING_IO_Join_client (&writerClientInfo) ;
RING_IO_Join_client (&readerClientInfo) ;
RING_IO_Delete (processorId) ;
--------tmpStatus = RingIO_delete (processorId, RingIOWriterName) ;
--------tmpStatus = PROC_stop (processorId) ;
--------tmpStatus = POOL_close (POOL_makePoolId(processorId, SAMPLE_POOL_ID)) ;
--------tmpStatus = PROC_detach (processorId) ;
-------- tmpStatus = PROC_destroy () ;
--------tmpStatus = RING_IO_OS_exit () ;
------------------------------------DSP端-------------------------------------------------
DSPLINK_init()
tskRingIoTask = TSK_create (tskRingIo, NULL, 0) ;
-status = TSKRING_IO_create (&info) ;
-------- status = POOL_open (SAMPLE_POOL_ID, &poolObj) ;
--------status = RingIO_create (GBL_getProcId (),RING_IO_WRITER_NAME,&ringIoAttrs) ;
--------writerHandle = RingIO_open (RING_IO_WRITER_NAME,RINGIO_MODE_WRITE,flags) ; //DSP做爲寫端打開RINGIO
--------readerHandle = RingIO_open (RING_IO_READER_NAME,RINGIO_MODE_READ,flags) ; //DSP做爲讀取端打開RINGIO
--------*infoPtr = MEM_calloc (DSPLINK_SEGID,sizeof (TSKRING_IO_TransferInfo),DSPLINK_BUF_ALIGN) ;
--------info->writerHandle = writerHandle; //填充傳輸信息結構體
info->readerHandle = readerHandle;
--------SEM_new (&(info->writerSemObj), 0) ;
SEM_new (&(info->readerSemObj), 0) ;
-status = TSKRING_IO_execute (info) ;
---------writerWaterMark = (RING_IO_dataBufSize < RINGIO_WRITE_ACQ_SIZE) ?RING_IO_dataBufSize : RINGIO_WRITE_ACQ_SIZE ;
--------status = RingIO_setNotifier ( info->writerHandle,RINGIO_NOTIFICATION_ONCE,writerWaterMark,&TSKRING_IO_writer_notify,(RingIO_NotifyParam) info) ;
--------TSKRING_IO_writer_notify()函數中調用SEM_post()發送一個信號
--------readerAcqSize = (RING_IO_dataBufSize < RINGIO_READ_ACQ_SIZE)?RING_IO_dataBufSize : RINGIO_READ_ACQ_SIZE ;
--------status = RingIO_setNotifier ( info->readerHandle, //爲讀取者設置通知
INGIO_NOTIFICATION_ONCE,
0 /* readerWaterMark */,
&TSKRING_IO_reader_notify,
(RingIO_NotifyParam) info) ;
--------semStatus = SEM_pend (&(info->readerSemObj), SYS_FOREVER) ; //等待GPP端的開始通知
--------獲取GPP端的數據開始通知
1 do 2 { 3 /* Get start attribute from gpp */ 4 rdRingStatus = RingIO_getAttribute(info->readerHandle, 5 &type, 6 ¶m) ; 7 if ((rdRingStatus == RINGIO_SUCCESS) 8 || (rdRingStatus == RINGIO_SPENDINGATTRIBUTE)) { 9 /* Got the fixed attribute */ 10 if (type == RINGIO_DATA_START) { 11 /* Set the attribute start attribute to output */ 12 wrRingStatus = RingIO_setAttribute(info->writerHandle, 13 0, 14 type, 15 0) ; 16 if (wrRingStatus != RINGIO_SUCCESS) { 17 SET_FAILURE_REASON (wrRingStatus) ; 18 } 19 else { 20 /* Sending the Hard Notification to gpp reader */ 21 do 22 { 23 wrRingStatus = RingIO_sendNotify ( 24 info->writerHandle, 25 (RingIO_NotifyMsg)NOTIFY_DATA_START) ; 26 if (wrRingStatus != RINGIO_SUCCESS) { 27 SET_FAILURE_REASON (wrRingStatus) ; 28 } 29 } while (wrRingStatus != RINGIO_SUCCESS) ; 30 } 31 } 32 } 33
--------請求輸出RINGIO 緩衝
info->writerRecvSize = writeAcqSize; wrRingStatus = RingIO_acquire (info->writerHandle, (RingIO_BufPtr *) &(info->writerBuf) , &(info->writerRecvSize)) ;
--------semStatus = SEM_pend (&(info->writerSemObj), SYS_FOREVER) ; //等待寫方的通知
--------rdRingStatus = RingIO_acquire(info->readerHandle,(RingIO_BufPtr *)&(info->readerBuf),&(info->readerRecvSize)) ;
--------semStatus = SEM_pend (&(info->readerSemObj), SYS_FOREVER) ; //等待讀取緩衝可用
--------rdRingStatus = RingIO_release (info->readerHandle,info->readerRecvSize) ; //釋放輸入緩衝(讀取緩衝)
--------RING_IO_apply((RingIO_BufPtr *)info->writerBuf,info->scalingFactor,info->scaleOpCode,size) ;
--------wrRingStatus = RingIO_release (info->writerHandle,size) ;
--------wrRingStatus = RingIO_cancel(info->writerHandle) ; //取消其他的輸出緩衝
……RINGIO其餘狀況的處理
1 else if (rdRingStatus == RINGIO_SPENDINGATTRIBUTE) { 2 3 rdRingStatus = RingIO_getAttribute(info->readerHandle, 4 &type, 5 ¶m) ; 6 if ((RINGIO_SUCCESS == rdRingStatus) 7 || (RINGIO_SPENDINGATTRIBUTE == rdRingStatus)) { 8 9 /* Got the fixed attribute */ 10 if (type == RINGIO_DATA_END) { 11 if (info->writerRecvSize) { 12 wrRingStatus = 13 RingIO_cancel(info->writerHandle) ; 14 } 15 16 /* Set theRINGIO_DATA_END attribute to output */ 17 do{ 18 wrRingStatus = RingIO_setAttribute(info->writerHandle, 19 0, 20 type, 21 0) ; 22 if(wrRingStatus != RINGIO_SUCCESS) { 23 SET_FAILURE_REASON (wrRingStatus) ; 24 } 25 26 } while (RINGIO_SUCCESS != wrRingStatus) ; 27 28 /* Send notification */ 29 wrRingStatus = RingIO_sendNotify( 30 info->writerHandle, 31 (RingIO_NotifyMsg)NOTIFY_DATA_END) ; 32 if(wrRingStatus != RINGIO_SUCCESS) { 33 SET_FAILURE_REASON (wrRingStatus) ; 34 } 35 status = RINGIO_SUCCESS; 36 /* DATA transfer completed. Exit from the loop. */ 37 exitFlag = TRUE; 38 } 39 } 40 else if (rdRingStatus == RINGIO_EVARIABLEATTRIBUTE) { 41 42 /* Read the variable attribute from the gpp */ 43 j = sizeof(attrs) ; 44 rdRingStatus = RingIO_getvAttribute (info->readerHandle, 45 &type, 46 &i, 47 attrs, 48 &j) ; 49 if((RINGIO_SUCCESS == rdRingStatus) 50 || (RINGIO_SPENDINGATTRIBUTE == rdRingStatus)) { 51 52 /* got the variable attribute */ 53 info->scalingFactor = attrs[0]; 54 info->scaleOpCode = attrs[1]; 55 info->scaleSize = attrs[2]; 56 57 do { 58 wrRingStatus = RingIO_setvAttribute( 59 info->writerHandle, 60 0, 61 type, 62 i, 63 attrs, 64 j) ; 65 if (wrRingStatus == RINGIO_EWRONGSTATE) { 66 } 67 } while (RINGIO_SUCCESS != wrRingStatus) ; 68 69 } 70 else if(RINGIO_EVARIABLEATTRIBUTE == rdRingStatus) { 71 72 /* This case should not arise. 73 * as we have provided the sufficient buffer 74 * to receive variable Attribute 75 */ 76 SET_FAILURE_REASON (rdRingStatus) ; 77 } 78 else { 79 /* For RINGIO_EPENDINGDATA, RINGIO_EFAILURE 80 * nothing to be done. go and read data again 81 */ 82 } 83 } 84 else { 85 /* For other return status 86 * (RINGIO_EPENDINGDATA,RINGIO_EFAILURE) 87 * no thing o be done. go and read the data again 88 */ 89 90 } 91 } 92 else { 93 /* Control should not come here. 94 * as reader ringio is opened with need exact flag false. 95 */ 96 } 97 } 98 else { 99 /* For Any other wrRingStatus,Consider it as failure */ 100 status = RINGIO_EFAILURE ; 101 SET_FAILURE_REASON (status) ; 102 }
-status = TSKRING_IO_delete (info) ;
-------- tmpStatus = RingIO_close (info->writerHandle) ;
--------tmpStatus = RingIO_delete (GBL_getProcId(), RING_IO_WRITER_NAME) ;
--------status = RingIO_close (info->readerHandle) ;
--------freeStatus = MEM_free (DSPLINK_SEGID,info,sizeof (TSKRING_IO_TransferInfo)) ;