DSPLINK DEMO解析之RING_IO

来源:互联网 发布:人工智能服务平台 编辑:程序博客网 时间:2024/05/16 07:44

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]\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 become56                      * 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,&param) ;

        --------status = RingIO_acquire (RingIOReaderHandle,&bufPtr ,&acqSize) ;

        --------从DSP端获取数据缓冲

            rcvSize -= acqSize ;

            totalRcvbytes += acqSize ;

        --------relStatus = RingIO_release (RingIOReaderHandle,acqSize) ;  //释放请求缓冲

        --------attrStatus = RingIO_getAttribute (RingIOReaderHandle,&type,&param) ;

        --------如果传输程序没有发出通知,则等待

复制代码
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                                                &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                             do22                             {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                                                                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)) ;

0 0
原创粉丝点击