VOIP语音终端的设计与实现_第1页
VOIP语音终端的设计与实现_第2页
VOIP语音终端的设计与实现_第3页
VOIP语音终端的设计与实现_第4页
VOIP语音终端的设计与实现_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

VOIP语音终端硬件设计一 VOIP语音终端的语音收发过程是:首先接收模拟语音信号,然后进行A/D转换、语音压缩编码,最后经过打包封装后传输到网络上;在接收端,VOIP语音终端接收网络上传输来的数据包,经过解封装、语音解压缩解码和转换后,将模拟语音信号提供给用户由此,本文设计了一个VOIP语音终端的硬件电路如图所示。 可以看出,我们设计的VOIP语音终端主要由以下几部分组成,CPU,语音编解码模块,CODEC模块和外围电路等。CPU:目前许多VOIP语音终端都采用集成了各种协议(H.323,SIP,MGCP等)的网络电话主芯片,比如PA1688和AR1688等,但采用这些CPU的问题在于芯片内集成的协议不可编程,灵活性不强,无法满足用户某些特殊需求。因此我们选择Motorola公司的通信处理芯片MPC860作为终端的CPU,该芯片是专门为网络应用设计的处理器,内部集成了32位PowerPC微控制器和以太网的MAC层功能,专门用于处理网络协议、信令交互、呼叫处理等网络应用。在我们的设计中,MPC860是整个终端电路的主控,实现由SIP修改而来的类SIP协议,同时,MPC860负责与网络接口,数据的封装/解封装和对电路其他功能模块的控制,比如对某些芯片的功能设置以及对终端编解码协议的选择等。语音编解码模块:本文所设计的VOIP语音终端支持G.711、、G.729和CVSD等多种编解码格式,虽然可以使用通用DSP来完成这些编解码工作,但利用专用编解码芯片可以减少系统调试时间、减轻通用DSP的负担,我们选用美国公司的CMX639芯片完成CVSD编码,其他编码利用TI公司的TMS320VC5416实现。其中,TMS320VC5416是编解码模块的主控,也就是说所有编解码的数据必须经过TMS320VC5416。这么做的好处是可以节约MPC860的接口资源,同时,也更加符合电路模块化的设计思想。CODEC模块:该模块的主要功能是完成话音数据的A/D和D/A转换,我们选择了ANALOGDEVICES公司的AD73311芯片完成CODEC功能,它同TMS320VC5416交互的是64Kbps的PCM数据。另外,CMX639的输人输出必须是模拟信号,因此我们利用MPC860控制一个继电器或模拟开关来实现模拟音频信号的分路。外围电路:外围电路主要包括电源模块、LCD和键盘等,主要完成电路供电、信息显示和用户输人等功能。VOIP语音终端硬件实现 在硬件电路的实际实现中,有几个关键问题需要注意,下面进行详细分析。 ●MPC860与TMS320VC5416的接口 在我们的设计中,MPC860负责整个终端的控制,承担着与网络接口的工作,因此所有编解码的数据都需要经过MPC860与TMS320VC5416的接口,我们实现了两者的HPI接口连接方案。HPI存取接口由控制寄存器HPIC、地址寄存器HPIA和数据寄存器HPID实现,MPC860和TMS320VC5416均可访问HPIC以完成HPI接口的设置,而HPIA和HPID只能由MPC860访问。在HPI通信方式下,TMS320VC5416的片内存储器对外界完全透明,由MPC860访问HPIA和HPID就可以完成对TMS320VC5416片内存储器的读写。图2给出了MPC860与TMS320VC5416采用HPI16接口的连接。 从图中可以看出,我们在两者接口处使用CPLD对一些控制信号进行了处理,保证了通信的有效进行。●CMX639与TMS320VC5416的接口CMX639是将输人、输出滤波器,编解码电路,逻辑控制电路集成在一起的CVSD编解码芯片,它通过外加时钟信号或内部可编程时钟,可在多种编解码/采样速率下工作,具有很强的适应性。由于CVSD编码的特点,CMX639的输人输出都没有帧同步信号,完全是比特流,所以CMX639与TMS320VC5416的McBSP连接有困难,因为使用McBSP,帧同步信号必不可少,因此,我们使用的两个GPIO作为数据输人输出,两个中断引脚作为时钟信号与CMX639连接,如图所示。从图中可以看出,我们利用CMX639提供的时钟作为TMS320VC5416的中断,每来一个中断,就从GPIO输人或者输出一个比特的数据。考虑到TMS320VC5416中断是下降沿有效,我们使用CPLD对中断信号和时钟信号进行了连接。●LCD和键盘对于语音终端来说,LCD和键盘是必不可少的设备,用来显示用户的输入以及终端所处状态等信息,键盘则是终端的用户输入设备。本文选择北京青云创新公司的带中文字库图形点阵液晶显示模块LCM128645ZK作为VOIP语音终端的显示模块,该LCM使用并行方式与MPC860连接,连接如图4所示.从图中可以看出,我们使用MPC860的一个GPIO与LCM的RS引脚连接,用来选择数据寄存器或者命令寄存器。另外,MPC860的片选信号与LCM的读写数据起始引脚(E)之间需要通过CPLD连接。对于键盘,我们选择了MAXIM公司的MAX7348作为VOIP语音终端的键盘控制芯片,它可以支持8*5共40个键的控制,完全可以满足普通VOIP语音终端的需要。更为重要的是,它采用I2C接口同MPC860连接,简单易用,由于I2C的连接非常简单,本文不再赘述。在电路实现中,还有一些问题需要注意,比如电源模块的设计与实现,因为电源的可命性涉及到整个终端的可命性,另外,使用MPC860实现RJ45接口也是一个关健问题VoIP终端平台的设计与实现二系统设计需求分析根据设计目标我们把需求细化为以下几个方面:一、接口要求●RJ45以太网接口。●音频接口。●串口。●LCD接口。二、协议支持●符合RFC3261规范的SIP信令协议;可与符合该规范的任何VoIP设备进行会话。●TCP/IP协议支持。●用RTP/RTCP协议进行语音数据的实时传输与控制。三、功能●SIP终端之间可通过IP地址直接实现语音呼叫与通话。●可注册到SIP代理服务器及重定向服务器,并通过服务器完成呼叫。●语音编解码算法可选,能适应低带宽工作环境。●类似传统电话的响铃音、回铃音提示。●实现语音通话功能,主观感觉接近普通PSTN电话。●CPU运算能力强,接口丰富。●软件操作系统功能强大,扩展性好。系统功能组成与结构设计系统按功能可分四个组成模块:用户接口模块、语音处理模块、系统控制模块和网络接口模块。用户接口模块的功能是为使用者提供操作接口以及信息反馈。目前采用串口来调试及输入输出,未来计划采用键盘和LCD。语音处理模块的功能是对模拟语音进行滤波、放大、A/D转换、PCM量化并送入控制模块,同时对来自控制模块的数字信号进行D/A转换、滤波、放大最后还原为模拟语音。系统控制模块是整个系统的核心,完成对整个系统的控制、管理。包括软件和数据的存储、TCP/IP、SIP等协议栈的实现,UA功能的实现,对语音数据流的控制与编解码以及用户接口的响应等。网络接口模块的功能是实现RJ45的以太网接口,为数据传输提供符合规范的通道。总体结构如图所示:硬件设计硬件需求本产品的硬件设计分为五个部分:核心处理器、存储单元、Codec单元、网络接口单元和用户接口单元。一、核心处理器;1)首先,我们需要核心处理器有较高的主频,可满足系统控制、音频编解码和数据流控制,同时有相当的富余量为以后的新功能作储备。2)由于语音会话时的数据吞吐量较大,需要处理器支持DMA方式,以减轻CPU的负担。3)具备音频接口。4)具备LCD接口。5)为简化软件开发,需要对嵌入式操作系统有较好的支持。6)可靠性高、功耗低。存储单元1)FLASH有16M以上的容量,满足操作系统、应用程序以及音频文件存储的需要以及预留空间的需要。同时可靠性高,不易损坏。2)SDRAM有32M以上容量,以满足操作系统及应用程序运行需要及升级预留的需要。Codec单元1)音频接口与CPU音频接口兼容。2)可实现全双工A/D、D/A工作。3)采样频率可调。4)具有放大、增益控制、音量调节等功能。音质清晰、保真。网络接口单元1)音频数据量较大。以太网接口芯片应有足够的运行速度,速率应在10Mbps以上。2)兼容NE2000网络适配器,以方便驱动程序的开发。用户接口1)LCD接口与CPU可直接连接。2)矩阵键盘。芯片选择与电路设计(1)核心处理器S3C2410X选择三星公司的S3C2410X芯片作为核心处理器。S3C2410X微处理器是一款由Samsung为手持设备设计的低功耗、高度集成的16/32位RISC处理器,采用272脚FBGA封装,为手持设备和一般类型应用提供了低价格、低功耗、高性能小型微控制器的解决方案。S3C2410X的显著特性是它的CPU核心,是一个由AdvancedRISCMachines(ARM)有限公司设计的16/32位ARM920TRISC处理器。ARM920T实现了MMU,AMBABUS和Harvard高速缓冲体系结构。这一结构具有独立的16KB指令Cache和16KB数据Cache,每个都是由8字长的行(1ine)构成。通过提供一系列完整的系统外围设备,S3C2410X大大减少了整个系统的成本,消除了为系统配置额外器件的需要。工作频率最高达到203MHz,同时具有MMU(内存管理单元),使得处理器轻松运行于WindowsCE,Linux等操作系统以及进行较为复杂的信息处理。S3C2410X提供了以下丰富的内部设备:分开的16KB的指令Cache和16KB数据Cache,MMU虚拟存储器管理,LCD控制器(支持STN&TFT),支持NANDFlash系统引导,系统管理器(片选逻辑和SDRAM控制器),3通道UART,4通道DMA,4通道PWM定时器,I/0端口,RTC,8通道10位ADC和触摸屏接口,IIC-BUS接口,IIS-BUS接口,USB主机,USB设备,SD主卡&MMC卡接口,2通道的SPI以及内部PLL时钟倍频器。S3C2410X的IIS(Inter-ICSound)总线是Philips公司提出的串行数字音频总线协议。它是一种面向多媒体的音频总线,专用于音频设备之间的数据传输,为数字立体声提供序列的连接至标准编解码器。IIS总线只处理声音数据。其他信号(如控制信号)必须单独传输。为了使电路的引出引脚尽可能少,IIS只使用了3条串行总线:提供分时复用功能的数据通道线(SD)、字段选择线(WS)和时钟信号线(SCK)。S3C2410X内置IIS总线接口,可直接外接8/16比特的立体声CODEC。它还可以给FIFO通道提供DMA传输模式而非中断模式,从而使数据发送和接收同时进行。该IIS接口有3种工作方式,可以通过设置IISCON寄存器来选择。本文介绍的硬件框架基于传输和接收模式。在这种模式下,ⅡS数据线将通过双通道DMA同时接收和发送音频数据,DMA服务请求由FIFO只读寄存器自动完成。S3C2410X支持4通道连接系统总线(AHB)和外围总线(APB)的DMA控制器。(2)Codec芯片UDAl341TS系统采用的音频设备是Philips公司的UDAl341TS芯片。UDAl341TS支持IIS总线数据格式,采用位元流转换技术进行信号处理,完成声音信号的模数转换,具有可编程增益放大器和数字自动增益控制器,其低功耗、低电压的特点使其非常适合用于MDCD、笔记本电脑等便携式设备。UDAl341TS支持的数据格式有一般IIS数据格式和MSB调整IIS数据格式,如图:硬件连接上,核心处理器S3C2410X上与IIS相关的引脚有五个:1、串行数据输入IISDI,对应IIS总线接口中的SD信号,方向为输入。2、串行数据输出IISDO,对应IIS总线接口中的SD信号,方向为输出。3、左右通道选择IISLRCK,对应IIS总线接口中的WD信号,即采样时钟。4、串行位时钟IISCLK,对应IIS总线接口中的SCK信号。5、音频系统主时钟CODECLK,对应IIS总线接口中的SYSCLK信号。CODECLK一般为采样频率的256倍或384倍,符号为256fs或384fs,其中fs为采样频率。CODECLK通过处理器主时钟分频获得,可以通过在程序设定分频寄存器获取,分频因子可以设为0到31.CODECLK与采样频率的对应表格如下,使用中需要正确的选择IISLRCK和CODECLK。 UDA1341TS一共有28个引脚,除去电源线、地线与测试线外,有两组音频输入信号线、一组音频信号输出信号线、一组IIS总线接口信号,一组L3总线。音频输入输出信号线接到麦克风和耳机底座。IIS总线接口根据功能定义:SYSCLK接S3C2410X的CODECLK、DATAI接IISDO、DATAO接IISDI、WS接IISLRCK、BCK接IISCLK。L3总线是UDA1341TS提供的一组用来配置数字音频处理参数和系统控制参数的接口,使用S3C2410X的3根GPIO信号线GPG5、GPG6、GPG7来连接。(3)网络控制芯片RTL8019AS 网络接口芯片的选择是REALTEK公司的RTL8019AS以太网控制器。它的主要性能为:符合EthernetII与IEEE802.3(10Base5、10Base2、10BaseT)标准;它支持UTP、AUI、BNC自动探测,还支持对10BaseT拓扑结构的自动极性修正;在片内建有16K的RAM,用于收发缓冲,降低对处理器的速度要求,可以满足高数据率下的传输和接收;支持8/16位数据总线,8个中断申请线以及16个I/O基地址选择;有全双工通信接口,可以通过交换机在双绞线上同时发送和接收数据,速率可同时达到10Mbps;是NE2000兼容芯片;允许4个诊断LED引脚可编程输出;用100引脚PQFP封装,缩小了PCB尺寸。网络接口芯片是作为网络适配器,通过RJ-45接口与以太网相连,它受系统控制模块控制收发数据,将数据以Mac协议封装后送入以太网中。 RTL8019AS的引脚中主要用到的有片选信号AEN,接S3C2410X的nGCS3;复位信号RSTRV,接S3C2410X的nRESET;读写控制信号IORB、IOWB,接S3C2410X的nOE、nWE;地址信号SA(0-4),接S3C2410X的A(0-4);数据线SD(0-15),接S3C2410X的D(0-15)。其余的是电源线和地线等。(4)存储芯片 S3C2410X处理器的存储控制器可以为偏外存储器访问提供必要的控制信号,它的主要特点有:支持大端(BigEndian)/小端(LittleEndian)模式;地址空间:每个Bank128MB(一共1GB),每个Bank支持8/16/32位数据总线编程;8个内存Bank:6个用于ROM、SRAM和其它;2个用于ROM/SRAM/SDRAM;一个起始地址和大小可编程的Bank(7)和7个起始地址固定的Bank(0~6);所有内存Bank可编程寻址周期;支持SDRAM自动刷新模式;支持多种类型ROM启动,包括:NOR/NANDFlash、EEPROM等。下图为S3C2410X复位后的存储器地址分配。根据是否使用NANDflash为bootROM,Bank0的定义有所不同,当使用NANDflash时,0地址指向片内SRAM,否则指向片选信号nGCS0指向的存储器。 Bank1-Bank15的起始地址和空间大小都是固定的,Bank6的起始地址是固定的,是空间大小和Bank7一样是可变的,可以配置为2M/4M/8M/16M/32M/64M/128M。Bank6和Bank7的详细的地址和空间大小的关系如下表: 注:Bank6和Bank7大小必须相同 存储单元中ROM我们未采用Nandflash,而是用了可靠性更好的NorFLASH,型号为Intel的TE28F128,容量为16M字节,使用Bank0地址,片选接nGCS0,SDRAM采用现代的HY57V561620,容量为32M字节,使用Bank6,片选接nGCS6。 (5)串口 用于采用串口作为用户接口,用于和终端的交互。这部分电路比较简单,直接用MAX3232芯片做电平转换,连接S3C2410X的串口0和DB9接口。 软件设计 软件设计主要包括四部分工作:操作系统的选择与移植、硬件驱动的开发、SIP协议栈和语音编解码库的实现和应用程序的开发。操作系统的选择与移植操作系统的选择本产品选择了嵌入式Linux作为底层操作系统。Linux是一个类似于Unix的操作系统。它起源于芬兰一个名叫LinuxTorvalds的业余爱好,但现在已经是最为流行的一款开放源代码的操作系统。Linux从1991年问世到现在,短短十几年时间内已发展成为一个功能强大、设计完善的操作系统。Linux也已经有了大量的应用。Linux对多任务调度和网络应用有着良好的支持。采用Linux作为开发平台,可以在开发应用程序时可以忽略硬件,而专注于功能实现。(2)嵌入式Linux开发环境的建立及开发流程 Linux交叉开发采用宿主机和目标机的模式进行。宿主机是一台运行Linux的PC机,目标机即VoIP终端。开发时使用宿主机上的交叉编译、汇编及连接工具形成可执行的二进制代码,这种代码并不能在宿主机上直行,而只能在目标机上执行。然后把可执行文件下载到目标机上运行。调试时的方法很多,可以使用串口,以太网口等,具体使用哪种调试方法可以根据目标机处理器所提供的支持做出选择。宿主机和目标板的处理器一般都不相同,宿主机为Intel处理器,而目标板为SAMSUNGS3C2410。 本系统的开发环境为: 操作系统:宿主机:LinuxFedoraCore5 编辑器:Vi编程语言:标准C Linux交叉开发包括Linux内核的开发和Linux应用程序的开发。Linux内核的开发下图所示为本系统所采用的实验环境以及开发流程。在主机的FedoraCore5Linux操作系统下安装Linux发行包以及交叉编译器arm-linux-gcc。然后对Linux进行配置(makemenuconfig)并选择适合本实验系统的相关配置,配置完成后进行编译生成Linux映像文件zImage。然后通过u-boot的tftp命令将该文件下载到目标板并执行。Linux应用程序的开发Linux应用程序的开发在宿主机一端的操作与内核开发类似,都是用arm-linux-gcc编译器应用程序,不同的是,编译生成elf格式的文件而不是Linux映像文件。编译生成的应用程序可以通过多种方式进行调试,下面介绍几种我们的系统中可以使用的方式:Linux应用程序以文件的方式直接将elf格式的文件加入到Linux文件系统中,然后更新整个文件系统,然后运行目标机Linux系统并运行应用程序。 2、运行目标机Linux系统,然后在目标机Linux系统中通过一些工具软件将宿主机中的应用程序通过以太网下载到目标机Linux系统,如NFS、FTP、TFTP等。3、在宿主机端将Linux应用程序拷贝到u盘,然后运行目标机Linux系统,然后在目标机Linux系统中通过挂载U盘,然后在U盘运行应用程序。(3)Linux的移植我们采用的Linux版本为韩国MIZI公司为$3C2410X处理器开发的开源版本板极BSP包Linux2.4.18-rmk7-pxal,该版本也是三星公司的$3C2410Xdemo板上的linux演示版本,己根据S3C2410X处理器的配置作了片级开发,但由于是开源版本,外围驱动作的并不完整。同时,由于使用的硬件芯片和三星的demo板并不相同,需要在配置Linux时进行一些调整,并对部分源代码作修改。主要有存储单元的配簧以及文件系统的建立。BSP包的下载地址见附录。①配置与编译1、Linux源代码结构Linux的源代码组织成如下结构:arch/arm:与架构和平台相关的代码都放在arch目录下。针对ARM的Linux,有一个子目录和它对应—arm。drivers:这个目录包含了所有的设备驱动程序。驱动程序又被分成“block”、“char”、“net”等几种类型。fs:这里有支持多种文件系统的源代码,几乎一个目录就是一个文件系统,如MSDOS、VFAT、proc和ext2等。 include:相关的头文件。它们被分成通用和平台专用两部分。目录“asm-$(ARCH)”包含了平台相关的头文件,在它下面进一步分成“asm-$(MACHINE)”以及“asm-$(PROCESSOR)”等子目录。与板子相关的头文件放在“asm-$(MACHINE)”下,与CPU相关的头文件放在“asm-$(PROCESSOR)”下。例如,对于没有MMU的处理器,“arch-arm”用于存放硬件相关的定义。 init:含一些启动kernel所需做的所有初始化动作,里面有一个main.c,针对kernel做初始化动作,设置一些参数等,并对外围设备初始化。ipc:提供进程间通信机制的源代码,如信号量、消息队列和管道等。kernel:包含进程调度算法的源代码,以及与内核相关的处理程序,例如系统调用。mm:该目录用来存放内存管理的源代码,包括MMU。net:支持网络相关的协议源代码。lib:包含内核要用到的一些常用函数。如字符串操作,格式化输出。script:这个目录中包含了在配置和编译内核时要用到的脚本文件。2、配置和编译Linux核心我们通过linux的配置工具menuconfig来进行定制。启动菜单配置工具后,按自己的需要进行配置。与默认设置相比,改动的有,启动根文件系统的变化,我们采用RAMDISK为根文件系统,用来存放主要的系统配置数据和库文件,这样的好处有两点:l、文件系统放在RAM中运行,速度快,质量高;2、安全性好。因为如果根文件系统遭到破坏,也只是在RAM中被破坏,重新启动后即恢复为原始数据。对于不需要修改的文件我们将其放在RAMDISK中可以起到保护的作用。为此我们进入Blockdevices选项,选上RAMdisksupport,大小设为8192(8M),并选上InitialRAMdisk(initrd)support。另外我们使用了一个JFFS2文件系统来作为配置数据存储空间,大小也为8M,因此选择jffs2disksupport。然后选择“Ok”确认,将退回到主菜单。然后按“Esc”键退出,并将提示是否保存,请选择“Yes”保存。对于Jffs2文件系统,我们还要在源文件中对其进行设定,具体做法为修改linux目录下drivers/rntd/map/中的s3c2410.intel.c,在结构体s3c2410partitions中添加以下代码:name:“jffs2(8M-256KBytes)”,size:(Ox700000-Ox080000),offset:0x980000,其中size为文件系统的大小,offset为文件系统的起始地址。 配置完成后,或者makezImage进行编译,makezImage将make生成的核心进行压缩,并加入一段解压的启动代码。最后生成的zImage文件即为内核文件。 要启动内核,我们还需要一个bootloader来引导,bootloader的作用相当于PC中的BIOS,是系统加电运行后的第一段代码。我们使用的GNU项目中的u-boot来实现这一功能。下载地址见附录。 u-boot的用户接口类似于Linux的shell界面,通过串口连接以后,用户可以交互式的输入命令和看到结果。同事,u-boot支持包括串口、以太网接口和USB接口等多种方式的文件下载,大大方便了开发工作。在移植并烧写了u-boot后,可以省却仿真器,直接使用以上接口就可完成文件的下载工作。 我们使用的U-BOOT是已针对2410和INTELTE28F128移植的包,可直接使用。需要注意的是要在Linux中对U-BOOT的存储空间加以保护,具体作法为在linux目录下drivers/rntd/map/中的s3c2410.intel.c,在结构体s3c2410partitions中添加以下代码: name:”reservedforu-boot”, size:0x080000, offset:0x0,②文件系统的制作RAMDISK的制作第一步:在宿主机中使用mkfs命令制作RAMDISK/sbin/mkfs/dev/ram58096第二步:创建一个目录/mnt/ram5,用来编辑RAMDISK的内容Mkdir/mnt/ram5第三步:装载RAMDISK到目录中Mount/dev/ram5/mnt/ram5第四步:将根文件系统中所需要的内容拷贝到目录中。主要有根文件系统目录,系统库文件和启动配置文件。Cprd/*/mnt/ram5-rf第五步压缩文件系统Umount/dev/ram5Gzipramdisk这样我们就得到了需要的RAMDISK文件ramdisk.gz2、JFFS2文件系统的制作在PC中制作JFFS2文件系统使用mkfs.jffs2工具,先将文件系统中需要的内容放在JFFS2目录中,然后将目录制作为jffs2文件系统,命令如下:mkfs.jffs2-djffs2-oprog.jffs2要使用JFFS2文件系统,要使用mount命令加载。可以在系统启动配置文件中添加加载命令,这样系统启动后就会自动将jffs2文件系统加载上。以上工作完成后,通过u-boot将内核、RAMDISK、JFFS2下载到FLASH,加电后即可运行。下图为启动界面。嵌入式Linux启动界面4.3.2音频驱动程序的开发对于PC机上的设备,由于接口的规范和应用的普及,大多数都有厂家提供的驱动程序。但对于嵌入式设备,我们往往需要依据Linux的驱动程序规范和相关的芯片手册自己编写驱动程序,这也是嵌入式Linux开发中十分重要的一个环节,编制完好的驱动程序可以大大简化应用程序的开发。在我们用的linuxBSP包中,针对8019的网络设备驱动已实现,使用中未发现问题。但音频设备的驱动没有完整实现,只简单实现了一个放音功能,无法录音,也不能工作在全双工模式,只支持立体声不支持单声道。因此音频的驱动需要自行编写。在Linux中,系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:l、对设备初始化和释放;2、把数据从内核传送到硬件和从硬件读取数据;3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据;4、检测和处理设备出现的错误。在Linux操作系统下有三类主要的设备文件类型,字符设备、块设备和网络设备。字符设备是指存取时没有缓存的设备。块设备的读写都有缓存来支持,并且块设备必须能够随机存取(randomaccess),字符设备则没有这个要求。典型的字符设备包括鼠标,键盘,串行口等。块设备主要包括硬盘软盘设备,CD.ROM等。一个文件系统要安装进入操作系统必须在块设备上。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待。网络设备在Linux里做专门的处理。Linux的网络系统主要是基于BSDunix的socket机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据的传递。系统里支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。用户进程通过设备文件来与实际的硬件打交道。每个设备文件都有其文件属性(c/b),表示是字符设备还是块设备,另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们。设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序。(1)Linux驱动开发流程Linux下驱动以模块的方式展现,可以单独作为模块在运行时同内核连接,也可以直接连接进内核。模块同内核版本密切相关。通过模块计数来维持生命周期,确定是否可卸载。/proc/modules保存了当前连接入内核的模块信息。模块和应用程序的差异:1、模块运行在内核空间,应用程序在用户空间。2、模块只能使用内核导出的函数,不能使用其他函数库,包括glibc库。3、模块必须考虑到并发,所以代码都必须是可重入的。模块函数一般有以下9个:Init_module:初始化函数,注册模块,连接到内核时被调用Clean_module:卸载函数,Init_module的逆操作,撤消所有注册,从内核中移出时调用(常用方式是自定义初始化/卸载函数,使用module_init(my_init),module_exit(my_cleanup)来声明,使得直接连接进内核的驱动更容易编写,因为内核中每个驱动的初始化/卸载函数为不同名字)open打开设备,应该是对设备的第一个操作函数。如为NULL,则所有调用都成功;release关闭设备,在文件结构被释放。只有当设备文件的所有拷贝都被释放时,才进行release调用,而不是每次应用调close时都执行。同open一样,也可以为NULL;read用来从设备接收数据;write用来往设备发数据;ioctl是用来给设备发送命令的接口函数;mmap用来请求将设备内存映射到进程空间;poll是两个系统调用poll和select的背后支撑。如果驱动未定义,则假设设备既可读又可写。(2)嵌入式Linux下音频驱动的实现音频设备驱动程序主要通过对硬件的控制实现音频流的传输,同时向上层提供标准的音频接口。如上节所述,驱动的开发,实际上就是按Linux的驱动规范来编写相应的函数,提供打开、读、写、控制等功能。目前Linux下常用的声卡驱动程序模式主要有两种:OSS和ALSA。最早出现在Linux上的音频编程接口是OSS(OpenSoundSystem),它由一套完整的内核驱动程序模块组成,可以为绝大多数声卡提供统一的编程接口。OSS出现的历史相对较长,内核模块中的一部分(OSS/Free)是与Linux内核源码共同免费发布的,另外一些则以二进制的形式由4FrontTechnologies公司提供。由于得到了商业公司的鼎力支持,OSS已经成为在Linux下进行音频编程的事实标准,支持OSS的应用程序能够在绝大多数声卡上工作良好。本文中音频驱动按OSS的接口模式编写。OSS模式的驱动程序并不公开源码,但我们知道他的调用接口。所以我们编写的驱动程序只要支持同样的调用方式即可。也就做到和OSS规范兼容,给应用程序统一的接口。完整的OSS驱动程序要求支持的设备文件有/dev/dsp,/dev/mixer,/dev/sndstat,/dev/midi,/dev/sequencer,/dev/dmfm,/dev/dmmidi,/dev/music。根据我们的实际需要,我们只需要支持/dev/dsp即可。在原来的驱动中,也部分支持/dev/mixer的功能,但在我们的应用中没有用到。对于音频控制,要求支持的操作有:设置音频格式(SNDCTL_DSP_SETFMT),设置声道数量(单声道/立体声)(SNDCTL_DSP_CHANNELS),设置速率(SNDCTL_DSP_SPEED)。其它的还有:同步(SNDCTL_DSP_SYNC),复位(SND_DSP_RESET)等。在这次音频驱动开发中,我编写和修改的函数有:ints3c2410_udal341_init(void)voidinit_udal341(void)intsmdk2410_audio_open(structinode*inode,structfile*file)voidinit_s3c2410_iis_bus(void)intsmdk2410_audio_ioctl(structinode*inode,structfile*file,uintcmd,ulongarg)smdk2410_audio_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos)intcopy_fromusermono_stereo(char*to,constchar*from,intcount)smdk2410audio_read(structfile*file,char*buffer,size_tcount,loff_t*ppos)intcopy_to_user_stereo_mono(char*to.constchar*from,intcount)intsmdk2410_audio_release(structinode*inode,structfile*file)s3c2410_udal341_exit(void)整个音频驱动的实现分为初始化、打开设备、单声道/立体声转换、读写操作、设备查询/控制、释放设备和注销设备等部分。下面结合以上函数介绍驱动的工作流程。l、初始化、打开设备设备初始化包括对对S3C2410X的IIS接口的初始化、UDAl341芯片的初始化和分配DMA通道。并且在内核中注册设备。这部分的函数是s3c2410_udal341_init(void)和init_udal341(void)。其中后者是被前者调用。对IIS接口的初始化是指根据S3C2410X的数据手册的要求将相应引脚配置为IIS接口模式,对UDAl341的初始化是通过L3接口对芯片进行配置,也是根据UDAl341手册的要求写入相应指令,配置采样频率为384fs,设置为全双工,并打开内部增益和自动增益控制模式。最后为读、写操作分别分配一个DMA通道,并分配DMA缓冲区。2、打开设备打开设备时主要是初始化S3C2410X的IIS相关寄存器并使能IIS接口,并清除声音数据缓冲区。这部分的函数是smdk2410_audio_open(structinode*inode,structfile*file)和init_s3c2410_iis_bus(void),其中后者是被前者调用。对IIS寄存器的设置包括设置默认采样速率、设置为DMA模式、主从模式设定、速率设定等,最后使能接口。3、单声道/立体声转换由于UDAl341芯片本身不支持单声道模式。而在实际应用中,很多IP电话软件都使用的是单声道模式,因此要能和这些软件互通,就必须支持单声道。我的做法是通过软件来实现。简单的说就是在放音时,如果是单声道的声音数据,则创建一个双声道数据格式的字符变量,然后将两个声道的数据都复制为单声道数据。而在录音时,如果需要保存为单声道数据,则创建一个单声道数据格式的字符变量,去掉双声道声音数据其中一个声道的数据,然后再复制给单声道数据的变量。相应的函数为:单声道转换为立体声的copy_from_user_mono_stereo(char*to,constchar*from,intcount),和立体声为单声道的copy_to_stereo_mono(char*to,constchar*from,intcount)。4、读写设备读写操作也就是实现音频数据的传输即播放和录音的数据传输。这部分的函数是smdk2410_audio_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos)。驱动中通过结构staticaudiostate来描述整个音频系统的状态,其中最主要的是2个数据流结构audio_in和audio_out。这2个数据流结构分别描述输入音频流和输出音频流的信息。通过对audio_in和audio_out的操作分别实现音频的输入和输出(音频的播放和录音),本驱动的主要内容是数据流结构的设计和实现。该结构应该包含音频缓冲区的信息、DMA的相关信息、所用到的信号量及FIFO的入口寄存器的地址。为了提高系统的吞吐量,系统使用DMA技术直接将需要回放或录制的声音存放在内核的DMA缓存区中,由于S3C2410的DMA控制器没有内置的DMA存储区域,因而驱动程序必须在内存内为音频设备分配DMA缓存区。缓冲区设置是否合理非常关键因为音频数据量通常较大,而缓存太小容易造成缓存溢出,所以要采用较大的缓冲区。而要填充大的缓冲区,CPU就要一次处理大量的数据,这样处理数据时间较长,容易造成延迟,这在对实时性要求较高的语音通信中影响更为明显。因此采用多个缓存的机制,将缓冲区分为多个数据段。数据段的个数和大小分别在数据流结构中指定。这样把大的数据段分为几个小段处理,每处理一小段数据就可以通过DMA发送出去。同时,在smdk2410_audio_write()中如果操作对象是单声道数据,在放音时要调用copy_from_user_mono_stereo()函数,在smdk2410_audio_read()中如果生成目标是单声道数据,要调用copy_to_user_stereo_mono()函数。是否调用通过查询当前工作模式为单声道还是立体声来决定。而工作模式标记为全局变量audio_channels,变量为l时为单声道模式,为2时为立体声模式。5、设备查询/控制设备控制接口是提供给应用程序用来在使用声卡时随时查询和调整声卡的工作模式。相关函数为intsmdk2410_audio_ioctl(structinode*inode,structfile*file,uintcmd,ulongarg)。通过cmd参数的内容判断操作内容,包括查询/设置声音格式、查询/设置单声道/立体声模式、查询/设置采样速率、复位等选项。6、释放设备释放设备是在应用程序调用声卡结束后清除调用标记和清除缓冲区。由注销函数smdk2410audio_release(structinode*inodestructfile*file)来完成。7、注销设备注销设备是从系统中注销自身,注销后系统即无法再调用该设备。使用s3c2410_udal341_exit(void)函数,同时释放驱动程序使用的DMA和缓冲区。下图为驱动程序的工作流程图:4.3.3SIP协议栈与语音编解码库对于SIP协议栈的实现,如果采用自己从头开发的办法,不但费时费力,而且稳定性也需要在长期应用中才能得以验证。目前在网络上有很多开源的SIP协议栈,参与者众多,许多协议栈都已经得到了大量的应用与验证。因此本文采用移植开源协议栈到我们的嵌入式Linux下的方法来实现。(1)sip协议栈的选取与移植①开源协议栈的比较与选择目前的开源sip协议栈主要有OPAL,VOCAL,sipX,ReSIProcate,Osip2。5种SIP协议栈各有千秋,OPAL有发展潜力,VOCAL比较完善,sipX兼容性好,ReSIProcate教稳定,oSIP小巧而快速。所以要根据应用的不同选择恰当的协议栈进行研究开发。在选择时,我们认为方便、快速对于实际应用比较重要,同时由于是在嵌入式系统中应用,需要体积小,占用空间小。所以我们选择了Osip2和eXosip作为方案的SIP协议栈来完成应用程序的开发,同时按eXosip的推荐采用oRTP协议栈来实现实时传输协议RTP。②Osip2与eXosip协议栈分析Osip2是按照RFC3261(SIP)和RFC2327(SDP)标准,并使用标准c编写的开放源代码一个SIP协议栈。oSIP协议栈结构简单而小巧,它并不提供高层的SIP会话控制的API,它主要提供一些解析SIP/SDP消息的API和事务处理的状态机,它具有短小简洁的特点,专注于SIP底层解析使得它的效率比较高。eXosip是Osip2的一个扩展协议集,它部分封装了Osip2协议栈,使得它更容易被使用。eXosip增加了call、dialog、registration、subscription等过程的解析,使得实用性更强。Osip2支持RFC3261和RFC3265定义的sip协议消息,包括INVITE、ACK、OPTIONS、CANCEL、BYE、SUBSCRIBE、NOTIFY、MESSAGE、REFER和INFO。不支持RFC3262定义的PRACK。遵循REC3264关于SDP的offer/answer模式。带有SDP的语法分析。支持MD5加解密算法。支Authorization、www_authenticate和proxy_authenticate。Osip2基于RFC3261、RFC3264和RFC3265的SIP协议描述过程,围绕transaction这一层来实现SIP的解析。Transaction是指一个发送方和接收方的交互过程,由请求和应答组成。请求分为Invite类型和Non-Invite类型。应答分为响应型的应答和确认型的应答。响应型的应答是指这个应答仅代表对方收到请求。请求经过处理后都必须返回确认型的应答。Transaction根据请求的不同和发送/接收的不同可以分为四类:ict、nict、ist和nist。Ict是指Inviteclienttransaction,就是会话邀请的发起方。Nict是指Non-Inviteclienttransaction,是指非邀请会话的发起方。Ist是指Inviteservertranaction,是指会话邀请的接收方。Nist是指Non-InviteSel'vcrtransaction,是指非邀请会话的接收方。每种类型的transaction都有自己相应的状态机,Osip2协议栈根据状态机来处理所有的SIP事件。所以这部分就是整个协议栈的核心。但是因为Osip2只做到transaction这一层,所以它可以忽略掉call、registration等应用的复杂性,显得相当简单,这就使得需要使用它的应用必须要自己处理应用的逻辑。必须注意的一点是,transaction的资源在0sip里是由协议栈负责释放的,但是在Osip2里改成由使用的应用负责释放。协议栈框架主要有三部分:底层套接字接收/发送,模块间通信管道,上层调用API接口。Osip2并不实现底层套接字的接收/发送,由eXosip实现,现在只支持UDP的链路连接。模块间的通信管道包括:transaction的消息管道、jevent的消息管道。Transaction的消息管道是驱动其状态机的部件,通过不断的接收来自底层套接字的远端信令,或者来自上层调用的指令,根据上述的状态机制来驱动这个transaction的运转。Jevent的消息管道是eXosip实现的,用于汇报底层事件,使得调用程序能处理感兴趣的事件。上层调用的API接口大致有两类:SIP协议的调用接口和SDP协议的调用接口。eXosip封装了大部分的SIP协议调用接口,一般来说都不需要直接调用osip2的接口函数。接口函数很多,在这里就不详述了,函数定义请参照源代码部分的注释。eXosip是Osip2协议栈的封装和调用。它实现了作为单个sip终端的大部分功能,如register、call、subscription等。eXosip使用UDPsocket套接字实现底层sip协议的接收/发送。并且封装了SIP消息的解释器。eXosip使用定时轮循的方式调用Osip2的transaction处理函数,这部分是协议栈运转的核心。透过添加,读取transaction消息管道的方式,驱动transaction的状态机,使得来自远端的SIP信令能汇报给调用程序,来自调用程序的反馈能通过SIP信令回传给远端。eXosip增加了对各个类型transaction的超时处理,确保所有资源都能循环使用,不会被耗用殆尽。eXosip使用jevent消息管道来向上通知调用程序底层发生的事件,调用程序只要读取该消息管道,就能获得感兴趣的事件,进行相关的处理。eXosip里比较重要的应用有j_calls、j—subscribes、j_notifies、j_reg、j_pub、osip_negotiation和authinfos。J_calls对应呼叫链表,记录所有当前活动的呼叫。J_reg对应注册链表,记录所有当前活动的注册信息。Osip_negotiation记录本地的能力集,用于能力交换。Authinfos记录需要的认证信息。③协议栈的移植Osip2,eXosip和oRTP协议栈都是用标准c实现的协议栈,但其默认运行环境为PC上的Linux,要把它运用到方案的嵌入式环境中,就需要对其进行移植工作。移植的主要工作就是对其进行交叉编译,生成能够在ARM环境里运行的C语言库文件。在编译过程中,除了使用的编译器要用交叉编译器arm-1inux-gcc外,一些根据PC环境设定的选项也必须关掉,否则编译过程会因为出错中止。同时,如果编译的程序需要调用其它的库,那么被调用的库也必须是经过交叉编译的。通常的做法是建立一个安装树(buildtree),也就是个统一的目录,将交叉编译出的库都放到里面,需要调用时就将路径指向该安装树。这个过程中主要遇到的问题是编译器的版本冲突和参数配置问题。另外还有协议栈之间版本匹配的问题。最后确定的编译器版本为arm-1inux-gcc3.4.1,Osip2版本为2.2.1,eXosip版本为0.9.0,oRTP版本为0.9.1。以下为编译步骤l、建立安装树,并设定路径mkdir/armbuildexportARM_INSTALL_TREE=/armbuild2、编译osip2./configure--prefix=/usr--host=arm-linux--with-gnu-ld--disable-staticmakemakeinstallDESTDIR=$ARM_INSTALL_TREE3、编译eXosip./configure--prefix=/usr--host=arm-linux--with-gnu-ld—disable-static--disable-glib-with-osip=$ARM_INSTALL_TREE/usrmakemakeinstallDESTDIR=$ARM_INSTALL_TREE4、编译oRTP./configure--prefix=/usr--host=arm-linux--with-gnu-ld—disable-staticmakemakeinstallDESTDIR=$ARM_INSTALL_TREE最后将安装树目录内生成的库文件放到目标板根文件系统RAMDISK内的/usr目录下。协议栈的下载地址见附录。(2)语音编解码库的选择与移植SIP协议中并未规定所使用的编解码算法,但一般来说符合G.711协议规范的A律/u律PCM编码是必须的。其他的编解码算法则可选,只要UA双方都支持就可以使用。为了让终端能够适应不同的带宽环境,我们设计采用语音编解码库的方法。根据不同的带宽环境选择相应的编解码算法,同时可以根据SIP协议中消息体(SDP协议)的内容采用和对方相同的语音算法。目前我们选择了三种编解码算法:G.711A律/u律PCM编码、GSM06.10编码和SPEEX。G.71lA律/u律PCM编码采用的是和PSTN网络相同的语音编码格式,用于将12位或16位的声音采样值转换到8位数据值,它未对语音做任何压缩,只是做了压扩编码,占用带宽为64K。G.7ll的算法比较简单,也早已标准化,在ITU-U的G.191软件工具库里就提供了实现该算法的ANSIC代码,该代码由SUN公司最初发布,后由BorgeLindber更新并最终发布。由于G.191的文档是收费下载的,所以我们不能直接从ITU的网站上获取。不过在英国剑桥大学的网站上可以获取该代码。地址见附录。将相应的C文件包含进我们的工程文件中,通过调用里面的四个转换函数:linear2alaw0、alaw21inear0、linear2ulaw0、ulaw21inear0,即可实现相应得编解码算法。GSM06.10算法是一种基于RPE-LTP(RegularPulseExcitation,LongTermPredictor)算法的高效语音编解码算法,RPE-LTP是一个基于帧结构的编码器,每一次编码20ms长的语音帧,将每160个样本帧转化到一个260比特的比特流帧,解码时则用每260个比特流比特重建一个160样本的语音采样。由于它被3GPP组织采纳为GSM移动通信系统的标准语音压缩算法,并在协议文件06.10中加以阐述及规范,所以一般被称为GSM06.10算法。目前在其他很多数字语音系统中也得到了广泛的应用。其算法目前也已标准化,虽然它不是由ITU-T组织制定,但由于其优良的性能和广泛的应用,在

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论