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