DSP/BIOS环境下的数据通信
每次中断发生时,串行口中断服务例程(ISR)把数据接收寄存器(DRR)中的数据字(32位)拷贝到数据接收管道的一空闲帧中。当1帧被填满时,ISR把该满帧写到数据接收管道中(通过调用PIP_put),供该管道的读线程(即音频处理函数)读取。音频处理函数执行时,它读取接收管道中的一满帧,处理完毕后再把它写到发送管道的一空闲帧中,供该管道的读线程(即ISR)发送。每次ISR触发时,它从发送管道中读取一满帧(若有的话),并每次32位字地发向串行口发送寄存器(DXR)直到1帧中的所有数据发送完毕。然后,该空闲帧被回收到发送管道,供音频处理函数(即该管道的写线程使用)。需要注意的是,由于例子当中发送速率与接收速率一样,因此,中断处理函数不但负责数据的接收也负责数据的发送,并且每次中断执行时只发送1个32位字。
javascript:window.open(this.src);" style="cursor:pointer;"/>
(3)需注意的问题
PIP_alloc和PIP_put由PIP对象的写线程调用,PIP_get和PIP_free由PIP对象的读线程调用,这种调用顺序是非常重要的。若打乱这种调用顺序,将会产生不可预测的后果。因此,每一次对PIP_alloc的调用都要跟着对PIP_put的调用才能继续调用PIP_alloc;对于PIP_get,情况也是如此。
另外,为了避免PIP调用过程中产生递归,作为通知读/写函数的一部分,应该避免调用PIP API函数。如果为了效率起见必须要这样做,那么对诸如此类的调用应该加以保护,以阻止同一管道对象的重入以及错误的PIP API调用顺序。例如,在发送管道的通知读函数以及接收管道的通知写函数的开始部分,我们添加了如下语句,以避免递归调用:
static Int nested = 0;
…
if (nested){/*防止由于调用PIP_get函数而产生的递归调用*/
return;
}
nested =1;
…
3 总 结
在DSP/BIOS提供的3种通信方式中,由于PIP对象的效率很高,因此使得它在基于DSP应用系统的输入输出中得到了广泛的应用。但是,我们在利用其所提供的便利的同时,一定要妥善处理好通知读/写函数的编写工作,以免发生递归调用,产生灾难性的后果。