DSPLINK DEMO解析之RING_IO

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 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,&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                             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                                                                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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值