SSC和IIS接口-基于AT91RM9200的嵌入式音频系统设计
- UID
- 1029342
- 性别
- 男
|
SSC和IIS接口-基于AT91RM9200的嵌入式音频系统设计
一. 引言
音频系统设计包括软件设计和硬件设计两方面,在硬件上使用了基于IIS总线的音频系统体系结构。在软件上,作为一个功能复杂的嵌人式系统,需要有嵌人式操作系统支撑。Linux是一个源代码开放的类UNIX系统,由于其具有内核可裁剪性,且提供对包括ARM、PPC在内的多种嵌人式处理器的支持,所以广泛应用于嵌人式高端产品中。虽然Linux提供了众多API来降低驱动程序制作的复杂度,但是由于音频应用对实时性有很高的要求,且需要处理的数据量较大,所以必须合理分配资源,使用合适的算法[1]。本文针对ATMEL公司的AT91RM9200处理器构造了基于IIS的音频系统,并介绍了该音频系统基于Linux内核的驱动程序构造技术。
二. 硬件体系结构
1. AT91RM9200微处理器简介
AT91RM9200是基于ARM920T内核、ARM/Thumb指令集的完整的片上系统,工作在180MHz频率下的运算速度可高于200MIPS。AT91RM9200集成了丰富的系统外围和应用外围及标准的接口,为需要大功效、低成本、低功耗的计算密集型应用提供了一个单芯片级的解决方案。
AT91RM9200的同步串行控制器SSC支持多种在音频和电信行业常用的串行同步通信协议,例如IIS、短帧同步、长帧同步等。SSC内部集成有独立的发送器、接收器和一个通用时钟分频器。发送器和接收器都有3个接口信号:收发数据信号TD/RD、时钟信号TK/RK和帧同步信号TF/RF。SSC可在低处理开销的情况下与主从模式的编解码器及专用串行接口DAC,尤其是IIS接口DAC等设备相连。最多可传输16个32位数据,可编程设定为自动启动或在帧同步信号检测到不同事件时启动[2]。
3.硬件连接
在本系统中,AT91RM9200与飞利浦的多媒体编码解码芯片UDA1380TT配合使用。AT91RM9200芯片的SSC控制器接口信号中有两条数据线,一条是输入信号数据线,一条是输出信号数据线,以同时发送和接收数据。UDA1380TT芯片除了提供IIS接口和麦克风扬声器接口,还提供L3接口控制音量等。图1是AT91RM9200芯片与UDA1380TT音频芯片的连接示意图。
在本系统中,ARM芯片的时钟信号TK1连接到UDA1380TT的BCKO和BCKI引脚上,TF1连接在字段选择信号引脚WSO和WSI上。UDA1380TT提供了两个音频通道,分别用于输入和输出,对应的引脚连接为:ARM的TD1对应UDA1380TT的数据输入DATAI,RD1对应UDA1380TT的数据输出DATA0。UDA1380TT的音频输入输出(VIN、VOUT)分别和麦克风扬声器连接,而L3接口相当于一个Mixer控制接口,可以用来控制输入输出音频信号的音量大小、低音等。L3接口的引脚L3DATA和L3CLOCK分别连接到ARM的PA25和PA26即两线接口TWI上。UDA1380TT的音频输入有3个通道,可以用作高质量音频录入,使用麦克风作为输入的时候,只使用其中的VINM通道。
至此,使用AT91RM9200芯片和UDA1380TT及其它必需外围设备构建了一个功能完善的嵌入式音频硬件系统。为接下来的与本系统对应的底层控制软件的开发做好的充分的准备。接下来进行基于硬件的底层软件设计。三. 底层驱动程序设计
嵌入式系统硬件设备种类繁多,且缺乏PC中标准的体系结构,所以必须为各种设备编写驱动程序。驱动程序的主要任务是控制音频数据在硬件中流动,并为音频应用提供标准接口。由于嵌人式系统资源有限,且处理器能力不强,所以在音频设备的驱动程序设计中,合理分配系统资源是难点。
1. 驱动程序基础
Linux设备驱动程序将设备看成文件。设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样使硬件对应用程序来说是透明的,在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。
设备驱动程序是嵌入式Linux内核的一部分,它完成以下的功能: 对硬件设备初始化和释放;把数据从内核传送到硬件,或从硬件读取数据;读取应用程序传送给设备文件的数据和回送应用程序请求的数据;检测和处理设备出现的错误和异常[3]。
2. 具体驱动程序的分析
通常将音频设备属于字符设备,它的驱动程序主要包括以下几个模块:设备的初始化和卸载、内存和DMA缓存区的设置、声音的播放和录制、其它相关控制,当然也包含相关的实现功能函数。下面对各个模块逐一介绍。
3.1 关键数据结构struct file_operations
Linux内核内部通过file结构识别设备,通过file_operations数据结构提供文件系统的入口点函数,也就是访问设备驱动的函数。File_operations的原型在中的函数指针表中定义。在本设计中structfile¬¬_operations的定义如下:
Struct file_operations at91_audio_fops =
{
open:at91_audio_open, /* open */
read:at91_audio_read, /*read */
release:at91_audio_close, /* release */
write:at91_audio_write, /* write */
ioctl:at91_audio_ioctl, /* ioctl */
};
file_operations指向的各个例程对应于设备无关操作,它让用户以访问文件的方式访问设备。对设备的打开和读写是启动程序为用户程序提供的最主要接口,分别对应于file_o perations中的open, read和write例程。
3.2 音频设备UDA1380初始化、打开和卸载
设备初始化由init_ssi(void)函数实现,在设备初始化中对音频设备的相关寄存器初始化,完成对UDA1380音量、采样频率、L3接口等的初始化,并使用了两个设备注册函数register_sound_dsp()和register_sound_mixer()注册音频设备和混频器设备,实现设备无关操作的绑定。这两个函数在2.2以上版本的内核drivers/sound/sound-core.c文件中实现。其作用是注册设备,得到设备标识,并且实现设备无关操作的绑定。在这些注册函数里使用的第一个参数都是structfile_operations类型的参数。该参数定义了设备无关接口的操作。
对音频设备的打开由open例程完成。open例程需要完成下面的任务:
(1)通过程序控制音频设备,并且为设备准备好工作参数(包括速度、声道、采样宽度)。同时设置对应的传输总线IIS和L3。
(2)根据采样参数计算出缓冲段的大小(程序也可指定缓冲区的大小),分配对应的DMA空间供设备使用。
设备卸载由cleanup_ssi(void)函数实现,注销函数unregister_sound_dsp()和unregister_sound_mixer()也在drivers/sound/sound-core.c文件中实现。注销时用输人注册时得到的设备号即可。在注销时还必须释放驱动程序使用的各种系统资源包括DMA、设备中断等。
3.3 DMA缓存区设计和内存管理
在音频设备的驱动程序设计中,DMA缓存区设计和内存管理部分最为复杂。由于音频设备有很高的实时性要求,所以合理地使用内存能加快对音频数据的处理,并减少时延。内存管理中的重要问题是缓存区块设计。常见的设计思路是使用一个缓存区,CPU先对缓存区处理,然后挂起,音频设备对缓存区操作,音频设备处理完后唤醒CPU,如此循环。需要处理大量音频数据的音频设备驱动程序,可以使用双缓冲。以录音为例,系统使用缓存2存放音频设备量化好的声音,CPU(应用程序)则处理缓存1中的声音数据;当Codec设备填充完缓存2,它移向缓存1填充数据,而CPU转向处理缓存2里的数据;不断交替循环,如图2(a),(b)所示[4]。
嵌入式系统为了提高系统的吞吐量,经常使用DMA技术直接将需要回放或者录制的声音放在内核的DMA缓存区中,DMA缓存区可以是ARM芯片上的RAM,也可以是片外的RAM。应用程序使用read或write系统调用在内核缓存和应用程序缓存中交换数据。为了解决音频应用I/O数据量大的问题,最简单的解决方法是使用比较大的缓存区,但大的缓存区在使用时会出现延时。为了解决延时问题,驱动程序使用了多段缓存机制(Multi-buffering),这种机制将一个大的缓存区分割成若干个大小相同的块(这些块也被称为"段")。这样对较大的缓存区的操作就转变为对较小的缓冲段的操作,从而可以在不增加对缓存区操作时间的情况下增加缓存区的大小。应用程序层面上,块的大小和个数可以使用ioctl系统调用来调整。
3.5 音频数据的播放与录制
音频数据的录制和播放对应驱动程序里的函数read()和write(),当内存和DMA已设置完成,录音和回放的相关程序也就易于实现了。这两个驱动例程的实现比较相近,下面就录音部分进行讨论,本设计中录音部分由at91_audio_read(struct file *file,char*buf,size_t count,loff_t * ppos)函数实现.
程序先初始化函数的局部变量,最后对输入参数进行检查,再判断设备文件的内核缓冲区是否被映射到用户空间中,如果已经被映射了,那么后面的内存拷贝就没有必要了。接下来判断和设备相关的缓存区是否已被激活,如没有激活,就初始化缓存区,对于复杂的系统,可以使用循环列表作为DMA缓存区的数据结构,如果使用的是这样的DMA管理程序,那么在初始化缓存区以后还有要将缓存区添加到DMA缓存区的循环列表中。再使用copy_to_usr()将系统缓存区中的数据拷贝到用户缓存区中,这里使用copy_to_usr()的原因是因为驱动程序使用的是内核空间,而应用程序使用的是用户空间,应用程序不能直接读取内核空间的数据。
拷贝完成以后使用dma_queue¬_buffer()将缓存区放到空闲缓存区循环列表中以方便其他程序使用。
四. 结束语
通过软、硬件的优化设计,本文介绍的基于ATMEL公司的AT91RM9200芯片的嵌入式音频系统经程序下载运行正常,同时还做了录音功能的测试。它可以运用到目前多种基于IIS总线的嵌入式音频系统中,具有广泛的应用性和实用价值,具有良好的稳定性和很高的性价比。本文作者创新点是将AT91RM9200及嵌入式Linux用在嵌入式音频系统中,如果能够对音频数据采用实时高效率的压缩技术(比如实时MP3编码技术),存储及传输效率就可以大大提高,但会增加系统成本,有待于以后进一步的研究。 |
|
|
|
|
|