DSP

DSPLINK DEMO解析之RING_IO

2019-07-13 12:05发布

RING_IO 示例阐明了如何使用 DSP/BIOS LINK 中的 RingIO 部件以及在 GPP 与使用两个RingIO 实例的 DSP 之间的数据流的方法。它实现了数据在 GPP 端运行的线程/进程的应用程序和 DSP 端之间的传递与转换。在 Linux 中,这个应用程序在某个过程中通过进程或者线程来运行。在 PrOS 中,它通过一系列任务来运行。在随后的部分应用程序中的每个线程/进程/被视为客户端。DSP端使用RingIO实现TSK。   ------------------------------------GPP端------------------------------------------------- RING_IO_BufferSize = DSPLINK_ALIGN (RING_IO_Atoi (strBufferSize),DSPLINK_BUF_ALIGN) ;  //验证指定缓冲区大小 status = RING_IO_Create (dspExecutable,strBufferSize,strBytesToTransfer,processorId) ;     --------status = RING_IO_OS_init () ;     --------status = PROC_setup (NULL) ;     --------status = PROC_attach (processorId, NULL) ;     --------status = POOL_open (POOL_makePoolId(processorId, SAMPLE_POOL_ID), &poolAttrs)     --------status = PROC_load ( processorId,(Char8 *) &imageInfo,numArgs,args) ;     --------status = RingIO_create (processorId, RingIOWriterName, &ringIoAttrs) ;     --------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] ", 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 " " , 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] ", 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] ", 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 ", 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] ", 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] ", 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] ", 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] ", 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] ", 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 &param) ; 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 &param) ; 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