闫敬文,李明峰
(汕头大学工学院电子系,广东 汕头 515063)
随着3G网络的大范围覆盖,加上Android、IOS、WindowsPhone等智能手机的普及,通过3G网络来观看网络视频已经越来越普遍了.但由于可以运行Android等界面操作系统的设备,一般都采用具有较高主频和较强处理能力的处理器,内存和Flash容量至少在128MB以上[1],成本较高,不适宜大量应用于某些场合,如移动电视,网络广告机,视频会议等.在这些场合中,往往需要用到一些廉价的专用型设备,本文介绍的3G移动媒体播放终端采用S3C2410作为处理器,内存和Flash也只需64MB,在满足系统需求的前提下很大程度地降低了系统的成本.
硬件框架如下图1-1所示.
图1 -1硬件框架图
硬件部分是由一个带显示器的ARM9开发板加上一个3G上网卡组成.开发板包括了嵌入式的基本系统,例如CPU、内存、Flash、稳压电源、USB接口、网卡、声卡等[2].软件框架如图1-2所示.软件部分主要包括以下四个部分:一是驱动部分,二是chat和PPP拨号软件部分,三是MPlayer播放器部分,四是QT界面部分.接下来的内容,将会围绕这几个部分进行详细的分析.
图1 -2 软件框架图
由于关于ZTE AC580 3G网卡硬件组成方面的资料较少,所以笔者决定拆解该网卡,其拆解图如图1-3所示.
图1 -3 AC580 3G网卡硬件拆解图
AC580 3G网卡的硬件组成框架图如图1-4所示.这款3G网卡主要由以下5个部分组成:QUALCOMM QSC6085处理器,Hynix Flash芯片,电源管理器,射频收发器和一个多用的读卡器.QSC6085芯片集成了ARM926EJS~192MHz,QDSP~100MHz两个处理器.支持EVDOrA标准,支持MP3,MPEG4,H.263,H.264的解码等等[3].虽然3G网卡的内部结构看似复杂,但从本质上来看,它只是一个Modem加上一个串口转USB而已.Modem通过串口转USB来与用户设备连接.要说明的是AC580 3G网卡是一个混合USB设备,Modem只是它的其中一个功能模块.
从3G网卡的硬件分析得知,3G网卡使用的虽然是一个USB接口,但实质上是一个虚拟的串口.该3G网卡在Linux底层是一个USB串口设备,所以在开发板端需要进行加载USBSerial的驱动.在Linux中,串口属于tty设备,对于一个USB串口设备而言,其驱动主要由两部分组成:usb_driver的成员函数和tty设备的tty_operations结构体成员函数[4].在USB串口设备驱动的模块加载函数中,将注册对应于USB串口的usb_driver,并初始化和注册tty驱动.在Linux内核里,自带USBSerial驱动,所在的路径为driversusbserial,AC580 3G网卡只要用内核自带的USBSerial驱动就可以了.
我们可以把USBSerial驱动程序编译成模块,或者将其直接编进内核.由于AC580 3G网卡是一个USB混合设备,系统在设备识别方面与一般设备不一样,USB串口设备模块需要在系统识别到Modem后才能起作用,所以,针对AC580 3G网卡的这种情况,选择把编译成模块,然后再等网卡被识别为Modem后才进行加载.把USBSerial驱动编译成模块一般使用以下两种方式:一是直接从内核中编译出来;二是自己编写Makefile,再使用编译模块命令来调动内核机制来编译.下面只对直接从内核中编译进行说明.
首先要配置内核:
[*]Enable loadable module support---> //启用可装载模块支持
---Enable loadable module support
[*]Module unloading //支持模块卸载
[*]Automatic kernel module loading //自动加载的内核模块
Device Drivers --->
[*]USB support--->
***USB port drivers***
---USB SerialConverter support
[*]USB Generic Serial Driver
然后,进入内核所在的目录,运行以下命令:
#make modules //开始编译模块
在编译的信息中看到
CC drivers/usb/serial/usbserial.mod.o
LD[M]drivers/usb/serial/usbserial.ko
证明USBSerial驱动已经编译成usbserial.ko了,此时可以在drivers/usb/serial目录下找到它.当然在编译之前请确保选择的是交叉编译.也就是说在Linux内核目录中要把Makefile中的ARCH和CROSS_COMPILE改为以下信息.
ARCH ?=arm
CROSS_COMPILE ?=arm-linux
arm-linux-gcc的版本可以用以下命令查看
#arm-linux-gcc-v //查看交叉编译器的版本文中用的arm-liunx-gcc版本为3.4.1
AC580 3G网卡是一个混合设备,它既是CD-ROM,也是USB Mass Storage,也是Modem.在PC机上,有强大的操作系统支持下我们使用起来觉得很方便,但是在嵌入式环境下,就不一样了,因为嵌入式系统在同一时间内只能使用某一个设备,如果不对设备进行切换的话那就不能使用另外的设备.在该文使用的嵌入式平台中,一插入网卡,系统只识别它为CD-ROM.并不是所想要的Modem.如果直接加载驱动模块,则无法建立与Modem的连接.以下介绍一种可行的驱动加载方法.网卡驱动的加载流程如图2-1所示.
图2 -1 3G网卡的驱动加载流
到这里,可以查看到/dev目录下多了ttyUSB0这个设备.这个ttyUSB0其实就是Modem的接口.这样3G网卡的驱动就加载成功了.但是,此时还不能上网,要上网还要进行拨号.
2.3.1 拨号软件编译
文中使用的ppp软件版本为ppp-2.4.5.ppp-2.4.5软件包中含有很多个独立的程序代码包,包括chat,pppd,pppdump,pppstats等.2.4.5版本的pppd可以跟好地支持3G的调制解调器.这里只需要chat和pppd两个软件包[5].
图2-2为拨号软件编译流程图.打开chat软件包,里面除了有源代码外,还有for linux系统的Makefile和for sol2系统的Makefile,因为该文用的是linux系统,所以,这里使用for linux Makefile.
图2 -2拨号软件编译流程
看到图2-2最后的输出信息则表明chat二进制文件已经编译成了.编译出来的chat二进制文件就可以直接在嵌入式平台中使用了.编译pppd的步骤跟chat的编译步骤一样.
要进行3G上网,以下的配置是必不可少的,在内核配置中要打开PPP支持:Networking --->
[*]Network device support---><*>PPP(point-to-point protocol)support //支持点对点协议[*]PPP multilink support(EXPERIMENTAL) //支持多链路
另外,需要在文件系统加入chat、pppd程序,同时需要创建他们所依赖的文件目录.该文使用的根文件系统为cramfs,在博创的cramfs根文件系统的基础上,加入需要的命令和目录.这里要做的是,把前面编译好的chat和pppd复制到/bin目录下,同时,在/etc下添加一个ppp文件夹,并且把它链接到/mnt/yaffs/ppp.同时在/etc下建立一个resolv.conf文件,并且把它链接到/mnt/yaffs/resolv.conf.等到启动系统后,再创建/mnt/yaffs/ppp文件夹和文件/mnt/yaffs/resolv.conf,resolv.conf用于保存DNS等信息.
AC580 3G网卡与GRPS,GSM模块都是同样使用AT指令进行拨号连接.由于篇幅有限,具体的指令使用,在这里就不一一介绍了.下面是AC580 3G上网的拨号脚本.
/bin/pppd connect'/bin/chat-v"""AT""""ATE0 OK""""AT+CMGF=1 OK""""AT^PREFMODE=8 OK""""AT+CSQ OK""""ATDT#777 CONNECT"'user ctnet@mycdma.cn password vnet.mobi/dev/ttyUSB0 115200 nodetach nocrtscts debug usepeerdns defaultroute ipcp-accept-local ipcp-accept-remote&
3G网卡的拨号连接过程如图2-3所示.
运行拨号脚本后,终端会显示连接过程的相关信息.连接成功后会显示所获取的IP和DNS.
用ifconfig命令查看网络接口的信息可以发现在网络信息中多了一个ppp0设备,显示的IP跟拨号时获取后的IP一样.这证明ppp0就是系统通过3G网络连接Internet的设备了.同时在/etc/ppp目录下,自动生成了一个resolv.conf文件,里面有DNS的地址信息,只要把/etc/ppp/resolv.conf复制到/etc/resolv.conf,这样就可以实现域名解析了,现用ping命令来测试一下.
[root@/mnt/yaffs]#ping www.baidu.com
PING www.baidu.com(121.14.89.10):56 data bytes
64 bytes from 121.14.89.10:seq=0 ttl=56 time=61.818 ms
Ping测试成功,3G上网已经实现了.如果需要断开网络连接则运行kill来关掉pppd的线程就可以了.
#kill$(pidof pppd)
MPlayer是一款开源多媒体播放器,支持大部分常用的视频格式,同时支持RTP、RTSP、HTTP、FTP、MMS等网络协议,所以大部分的网络流媒体都可以通过直接输入URL的方式来进行播放[6].在X11,Xmga,DirectX等显示架构中可以通过-geometry控制视频的定位输出.而在嵌入式系统中使用的显示设备为fbdev,MPlayer源码不支持在fbdev的定位播放.笔者通过分析MPlayer源码,添加了fbdev定位播放的功能.MPlayer播放流程如下图3-1所示.
图3 -1 MPlayer的播放流程
在嵌入式环境下,视频输出主要通过vo_s3cfb.c和vo_fbdev.c控制.而实际的输出由vo_fbdev.c中的draw_slice函数控制.要实现视频输出的定位则要从这个函数入手.可以通过在vo_fbdev,c中添加geometry的库从而实现定位播放.添加流程如下图3-2所示.
其中,fb_x、fb_y为自定义的以像素为单位的定位平移量.偏移的参考原点为LCD的最左上角.修改完源代码之后就可以进行交叉编译了.MPlayer的移植过程不会太复杂,关键是配置.下面简单介绍一下如何配置MPlayer,由于篇幅有限这里只列出部分内容.
./configure--cc=arm-linux-gcc //选用系统默认交叉编译器,笔者使用的是3.4.1
--target=arm-armv4-linux //支持armv4架构的arm-linux
--enable-fbdev //支持开发板的fb设备
--disable-mp3lib //不使用内部的MP3界面库
--disable-mad //支持mad作为MP3解码的库,这个需要另外编译的
--enable-static //静态编译
--with-extraincdir=/usr/local/arm/3.4.1/arm-linux/sys-include/:/usr/local/arm/3.4.1/lib/include //指明libmad的头文件--with-extralibdir=/usr/local/arm/3.4.1/arm-liunx/lib:/usr/local/arm/3.4.1/lib/lib//指明libmad的库地址
配置的时候可以建一个脚本文件.这里就不详细讲述了.配置完之后就直接make.中途可能会出现一些错误.可以根据具体情况对源代码进行修改,直到编译成功为止.编译成功后,需要把生成的可执行程序mplayer放到嵌入式系统中进行测试运行.视频输出位置是通过-geometry参数进行输出位置控制.例如,执行./mplayer panda.mpg-vo fbdev-geometry+50+50,这样视频的输出参考点就会从原来的最左上角(0,0)的位置移动到(50,50)的位置.具体播放定位位置要根据QT的显示窗口位置来设定.
3.2.1 UI设计
由于整个播放器的界面所占篇幅较大,这里只截取按钮布局,如图3-3所示.
图3 -3 播放器按钮布局
在MPlayer的基础上,用QT界面对播放器实现来播放、暂停、停止、全屏播放的控制功能.同时,还增加了播放列表功能,可以通过选择播放列表中的文件来实现本地以及URL的播放.
3.2.2 控制原理
在这个播放器中QT界面用于实现对MPlayer的可视化控制.在QT中创建一个线程调用MPlayer并且通过输入MPlayer的控制命令来实现暂停,停止等功能.具体的控制原理如图3-4所示.
图3 -4 QT对MPlayer实现控制
在s_mp中如果需要可以根据QT播放器窗口的位置来控制MPlayer视频的输出位置.图中的s_mp输入命令为640x480全屏显示.如果需要定位视频输出位置,则在后面添加-vo fbdev-geometry+x+y参数(x、y为具体偏移量)即可.详细的控制参数可以参考MPlayer的使用说明.
3.2.3 Qt移植
播放界面的具体移植过程分为3个骤步,分别为:交叉编译、寻找需要的库文件和编写运行脚本.下面就每一步进行简单的说明.
(1)交叉编译.QT官网中有提供QtEmbedded的开发包,安装成功后,用里面的命令编译出来的程序可以在ARM-linux嵌入式系统中运行.可以输入以下命令进行编译.
#/opt/local/Trolltech/QtEmbedded-4.5.3/bin/qmake-project//建立工程,需要制定为QtEmbedded的make.
#/opt/local/Trolltech/QtEmbedded-4.5.3/bin/qmake //生成头文件和Makefile
#make //编译
在编译成Embedded版之前,最好make clean一下,同时确保所写的程序可以编译成x86或x11的版本,而且编译后可以在PC中运行.成功编译之后,在播放器的工程目录下就会有一个二进制可执行文件.但是直接下载到板上运行会出错的,原因是它依赖于很多库文件.必须指定了库文件的路径,程序才可以正常运行.
(2)寻找需要的库文件.在工程目录下运行arm-linux-readelf命令可以查看文件所依赖的库文件.
#arm-linux-readelf-d MicrophoneTV
Dynamic segment at offset 0x17340 contains 31 entries:
Tag Type Name/Value
0x00000001(NEEDED) Shared library:[libQtGui.so.4]
0x00000001(NEEDED) Shared library:[libts-0.0.so.0]
......
0x00000001(NEEDED) Shared library:[libc.so.6]
0x0000000f(RPATH) Library rpath:[/opt/local/Trolltech/Qtarm-4.5.3/lib]
这里的库文件有四类:一是QtEmbedded的库文件,二是arm-linux-gcc的库文件,三是触摸屏的库文件,四是字体的库文件.可以分别到各个对应的目录去复制需要的库文件.然后把它整理到一个文件夹,笔者用的文件夹命名为Qtlib.前面三类可以在上面的列表中看到,文字库需要另外制作或者到网上去下载.把字体的库文件放到Qtlib/fonts目录下.另外还需要一个触摸屏的校正程序,笔者用的版本为tslib-1.4,交叉编译tslib之后把它里面的文件放到Qtlib/ts中.
(3)编写运行脚本.这一步最为关键,这个要根据具体的嵌入式环境来编写.下面是笔者根据使用的系统编写的脚本.这个脚本的作用是设定环境变量,实质是指定程序运行所依赖的文件的路径.
#!/bin/sh
rm-fr/tmp/* //清除内存
export TSLIB_CONSOLEDEVICE=none
//tslib运行需要的控制台,默认为/dev/tty,none则为LCD;
export TSLIB_FBDEVICE='/dev/fb0'//这是LCD的设备名
export TSLIB_TSDEVICE='/dev/event0'//这是触摸屏的设备名
export TSLIB_PLUGINDIR='/mnt/yaffs/Qtlib/ts/lib/ts'//触摸屏的库
export TSLIB_CALIBFILE='/mnt/yaffs/pointercal' //校正文件
export TSLIB_CONFFILE='/mnt/yaffs/Qtlib/ts/etc/ts.conf'//触摸屏配置
export QTDIR='/mnt/yaffs/Qtlib' //Qt库
export QT_QWS_FONTDIR='/mnt/yaffs/Qtlib/fonts'//字体库
export PATH=$QTDIR/BIN:$PATH //命令程序
export QWS_DISPLAY=LinuxFb:/dev/fb0 //设定显示设备
export QWS_SIZE=640x480 //分辨率
export QWS_SW_CURSOR=1 //显示鼠标
export QT_ONSCREEN_PAINT=0
export POINTERCAL_FILE='/mnt/yaffs/pointercal'//触摸校正值
export QWS_MOUSE_PROTO='tslib:/dev/event0'//触摸屏为鼠标
export LD_LIBRARY_PATH=$QTDIR/:/lib:/usr/lib:$LD_LIBRARY_PATH
cd /mnt/yaffs/Microphone
./MicrophoneTV qws //运行播放界面程序
运行命令中的-qws参数是用来解除所运行程序对原来系统库依赖关系.
按照本文中的方法重新配置内核,文件系统,然后写到嵌入式系统中,同时把qt程序,程序所以依赖的库,mplayer等文件拷贝到相应的文件夹,运行以上的脚本就可以让播放器运行起来.
4结语
最后来看一下系统的运行效果.在运行播放界面之前,要先运行触摸校正程序,然后进行网卡驱动加载和3G拨号,确保连接上互联网后,可以直接在列表中添加一些URL或者本地文件.添加完成后,可以在列表中选择要播放的频道,然后点击OK按钮.播放列表如图4-1所示.选择完播放频道后,点击播放按钮,就可以播放相应的视频.在开发板的LCD中可以看到流畅的网络电视画面.图4-2中为播放厦门卫视的效果图.
到这里整个系统的设计已经完成了.本文介绍了在嵌入式linux平台上3G网络媒体移动播放终端的实现技术方案.详细分析了3G网卡的硬件和驱动,3G网络接入的ppp拨号实现,MPlayer嵌入式系统下定位播放,QT可视化控制MPlayer,QT移植等主要技术,在嵌入式平台实现了3G网络流媒体的播放功能.实验测试结果表明,本终端既可以流畅播放本地视频,也可以通过3G网络实现在线视频点播.经过转化可以做成移动电视,网络广告机,视频会议等终端设备.值得一提的是,整个系统的硬件配置还不到Android平台最低配置要求的一半,可见若能实现本终端的产业化,无疑可以有效地降低生产成本,从而促进移动电视,网络广告机等产品的普及.
[1]Google公司,Android Porting Guide,[EB/OL].[2008-06-09].http://www.netmite.com/android/mydroid/development/pdk/docs/index.html
[2]北京博创.S2410经典实验指导书[M].北京博创兴业科技有限公司,2009.
[3]QUALCOMM公司,QSC6085 Hardware Training,[EB/OL].[2007-04].http://www.datasheet.co.kr/datasheet-html/Q/S/C/QSC6055_QUALCOMM.pdf.html
[4]宋宝华.Linux设备驱动开发详解[M].北京:人民邮电出版社,2008.
[5]李善平,浏文峰,王焕龙.Linux与嵌入式系统[M].北京:清华大学出版社,2006.
[6]MPlayer工作组,MPlayer-电影播放器,[EB/OL].[2010-02].http://www.mplayerhq.hu/DOCS/HTML/zh_CN/index.html