Computer Knowledge and Technology 电脑知识与技术电子商务与电子政务本栏目责任编辑:万艳丽第6卷第20期(2010年7月)基于嵌入式Linux 的3G 技术的应用和研究
彭海文
(武汉大学信息管理学院,湖北武汉430072)
摘要:该文介绍了在嵌入式linux 的平台下,如何通过3G USB Dongle 来进行网络连接。介绍了目前主流3G USB Dongle 的工作模式,分析了linux 的USB 热插拔在用户空间的处理流程,并引入一个轻量级的热插拔事件处理框架,最后介绍3G USB Dongle 通过PPP 套件的拨号处理流程。
关键词:嵌入式;linux ;3G ;USB
中图分类号:TP393文献标识码:A 文章编号:1009-3044(2010)20-5655-03
第三代移动通信技术(3rd-generation ,3G ),是指支持高速数据传输的蜂窝移动通讯技术。3G 服务能够同时传送声音(通话)及数据信息(、即时通信等)。3G 的代表特征是提供高速数据业务,速率一般在几百kbps 以上。3G 的标志性业务包括:无线宽带上网、手机电视以及视频通话等。目前在中国运营的共有三种制式的3G 网络:中国移动TD-SCDMA 网络,中国联通WCDMA 网络,中国电信CDMA2000网络。Linux 是目前嵌入操作系统的一个极有吸引力的选择。它支持广泛的计算机硬件,
除了PC 平台的x86系列cpu 外,嵌入式平台常见的ARM 和MIPS 核心的cpu 都能得到很好的支持。Linux 提供了完整内存保护,是一个多任务,多进程的操作系统。它不仅是免费的,其程序源码全部公开,任何人可以修改并在GPL 下发行,这样开发人员可以对操作系统进行定制。其强大的语言编译器GCC 等也可以很容易得到,不但成熟完善、而且使用方便。3G 技术的引入使得其有了更大的用武之地。各个公司正在结合这两个技术开发很多新的应用为人们提供更好的服务,目前的应用主要有3G 路由器,3G 视频服务器,3G 工业数据采集系统,3G 无线网络视频监控,3G 媒体广告发布等。3G 连接可采用通用的USB 无线上网模块(本文中也称作3G USB Dongle ),只要嵌入式产品具有linux 操作系统和USB HOST 接口就立即可以使用。
1配置内核
在编译内核时进入“Device Drivers ”选项,再进入“USB support ”子菜单,把以下的条目选中编译进内核,或者把这些条目编译成模块形式。
[*]Support for Host-side USB
[*]USB device filesystem
[*]EHCI HCD (USB 2.0)support
[*]OHCI HCD support
[*]USB Mass Storage support
USB Serial Converter support -->
[*]USB driver for GSM and CDMA modems
再进入“SCSI device support ”子菜单,把以下的条目选中编译进内核,或者把这些条目编译成模块形式。
[*]SCSI device support
[*]SCSI disk support
[*]Probe all LUNs on each SCSI device
现对这些选项介绍做些说明。目前有两种主控制器接口,Compaq 的OHCI (Open HCI),Intel 的UHCI (Universal HCI)和EHCI (Enhanced HCI)。OHCI/UHCI 是针对USB 1.1的工业标准,而EHCI 是针对USB 2.0的。启用EHCI 和OHCI 确保所有接口规范的USB 设备都能够得到支持。启用USB device file
system 选项可以让我们在/porc/bus/usb 中查看USB 设备。USB driver for GSM and CDMA modems 又名option ,是USB 3G dongle 的核心驱动,几乎现在市面上所有USB 3G dongle 都通过这个驱动来支持,无论它是哪个网络制式,最终都是通过USB Serial 的option 驱动来和内核通信。USB Mass Storage 和SCSI device support 是为了支持一些Dongle 上自带的USB Mass-storage 设备,Probe all LUNs on each SCSI device 是为了支持Dongle 上读卡器。
当你碰到一个内核并不支持的新设备后,只需要把该Dongle 3G 接口的Vendor ID 和Product ID 添加到linux-2.6.x/drivers/usb/serial/option.c 中的option_ids[]数组即可。以华为K3765举例,其3G 接口的Vendor ID 为0x12D1,Product ID 为0x1465,
#define HUAWEI_VENDOR_ID 0x12D1/*add to ID table */
static struct usb_device_id option_ids[]={韦东山嵌入式linux视频
……
{USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID,0x1465,0xff,0xff,0xff)},
……};
重新编译内核后,内核部分的配置工作就做完了,我们还需要通过下面的命令来创建设备文件给用户空间的拨号程序来访问。mknod /dev/ttyUSB0c 1880
……
mknod /dev/ttyUSB3c 1883
收稿日期:2010-04-10
ISSN 1009-3044Computer Knowledge and Technology
电脑知识与技术Vol.6,No.20,July 2010,pp.5655-5657E-mail:wyl@cccc www.dnzs Tel:+86-551-569096356909645655
Computer Knowledge and Technology 电脑知识与技术电子商务与电子政务本栏目责任编辑:万艳丽
第6卷第20期(2010年7月)
最后在系统初始化的脚本中,我们还必须挂载usb 虚拟文件系统:
mount -t usbfs usbfs /proc/bus/usb/
23G USB Dongle 的工作模式研究
一些新的USB 3G Dongle 都板载了Windows 的驱动程序,因此不需要额外的CD 来放驱动程序。当Dongle 第一次插上的时候,它会被当做一个Flash 储存设备,然后windows 的autorun 机制会自动执行安装驱动程序。在驱动程序安装之后,每次插入Dongle 时候,驱动会自动在内部切换模式,由储存模式变成USB Modem 模式。然而这些驱动都只工作在windows 下,厂商并没有提供linux 下的驱动或者相关文档。幸运的是,一些热忱的hacker 利用USB 嗅探工具通过分析windows 驱动的行为和动作,然后再linux 下复制这些行为和动作来做切换动作。
usb_modeswitch 是linux 下面对USB 设备的工作模式进行转换一种工具,它可以把3G USB Dongle 从储存设备模式切换到mo -dem 模式。它只需要libusb 的支持,把这个程序移植到嵌入式平台是个很容易的事。我们只需要提供一个配置文件来给usb_mod -eswitch 。配置文件应该至少包含以下的一些参数:DefaultVendor 和DefaultProduct 是3G USB Dongle 插入时没有做模式切换前的USB ID,这个ID 我们能够在/proc/bus/usb/devices 中到。程序需要这两个参数来做匹配。TargetVendor 和TargetProduct 是3G USB Dongle 在成功切换到modem 模式的USB ID.程序可以通过这两个参数来判断是否切换成功。最重要的参数是MessageContent ,它是一个16进制的字符串,这个字符串会发送给3G USB Dongle ,让其切换模式。
从上文usb_modeswitch 的配置文件的介绍,我们差不多能够了解到usb_modeswitch 的工作流程:先匹配储存模式的USB ID ,如果匹配上,向设备发送MessageContent 消息来切换模式,然后通过检测modem 模式的USB ID 来判断模式切换是否成功。usb_mod -eswitch 已经自带目前市面上常见的3G USB Dongle 的配置文件。如果碰到一个新设备,我们可以在windows 下使用sniffusb 程序来获取参数,安装驱动前,我们能获得DefaultVendor 和DefaultProduct 参数;安装驱动后,我们能获得TargetVendor 和TargetProduct 参数;sniffusb 程序来监听所有的主机和USB 设备之间的通讯信息,然后出模式切换的MessageContent 消息。
3USB 热插拔事件检测
上面讨论了usb_modeswitch 的原理之后,现在来讨论usb_modeswitch 使用的时机。usb_modeswitch 应该在usb 设备插入的时候,检测到Vendor ID 和Product ID 后,用这两者作为命令行参数来调用usb_modeswitch 。udev 可以帮我们实现USB 热插拔并自动调用usb_modeswitch 的功能,但是在一些内存和闪存紧缺的解决方案中,并没有提供udev 工具。笔者在这里介绍一种轻量级的linux 热插拔方案。
简单的linux 内核的USB 的热插拔通知可以通过调用/proc/sys/kernel/hotplug 中注册的程序来实现,它通常是/sbin/hotplug 。当有USB 设备插上时,内核的会把该设备的一些信息填入字符串数组,然后把
这个字符串数组作为/sbin/hotplug 进程的环境变量并开始执行这个进程。而sysfs 的出现会报告更多的内核hotplug 事件给/sbin/hotplug ,只要实现了kobject 模型的设备驱动都会产生该事件,/sbin/hotplug 开始变得复杂,又由于/sbin/hotplug 都是bash 所写,因此变得没有效率。
内核在2.6.15之后,/proc/sys/kernel/hotplug 会成空的,因为内核通知用户空间还用了netlink 接口,而且最新的udev 也采用了netlink 接口去写,废弃了/sbin/hotplug 。我们可以直接通过netlink 监听设备事件,然后过滤出我们关心的3G USB Dongle 热插拔事件并作出相应的处理,下面是程序的初始化和主循环框架:
/*netlink socket 的创建和绑定*/
int netlinkfd,fdmax;
fd_set fdset;
struct sockaddr_nl snl;
memset(&snl,0,sizeof(struct sockaddr_nl));
snl.nl_family =AF_NETLINK;
snl.nl_pid =getpid();
snl.nl_groups =1;
netlinkfd =socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT );
bind(netlinkfd,(struct sockaddr *)&snl,sizeof(struct sockaddr_nl));
/*netlink 数据侦听检测*/
while (1){
tv.tv_sec =0;
tv.tv_usec =1000*50;
FD_ZERO (&fdset );
FD_SET (netlinkfd,&fdset );
retval =select(fdmax,&fdset,NULL,NULL,&tv );
if (retval >0){
if (FD_ISSET(netlinkfd,&fdset )){
recv(netlinkfd,buff,sizeof(buff)-1,0);
/*处理netlink 数据*/}}}
通过上面的程序框架,我们能够获得所有的内核热插拔的事件通知,我们还需要做的就是把netlink 传到用户空间的数据分析出来,然后过滤出我们需要的数据。前文提到过内核把该设备的一些信息填入字符串数组,然后把这个字符串数组作为的环境变量传递给/sbin/hotplug ,内核还会把这个字符串数组通过netlink 结果传给用户空间的程序,上面的recv 函数收到的数据就是这个字符串数组,因而很容易被分析出来。同/sbin/hotplug 的方案相比,netlink 的方案不用反复创建新进程,效率提高的很多,一个单线程就可以收到所有的热插拔通知消息,除了去检查是否调用usb_modeswitch 来切换3G USB Dongle 的工作模式,我们还可以利用这个框架来做USB Mass Storage 自动挂载等。
我们目前只需要注意的就是ADD 事件,当一个USB ADD 设备的通知收到后,我们结合上下文得到这个新添加设备的Vendor 5656
Computer Knowledge and Technology 电脑知识与技术电子商务与电子政务本栏目责任编辑:万艳丽
第6卷第20期(2010年7月)ID 和Product ID ,如果他们正好匹配华为K3765储存接口的Vendor ID 0x12D1和Product ID 0x1465,那我们就直接调用usb_mod -eswitch 来做工作模式切换:
usb_modeswitch -c /etc/usb/usb_modeswitch.d/12D1:1465
4使用ppp 套件拨号
虽然WCDMA ,TD-SCDMA,CDMA2000,这三种网络制式并不兼容,但是它们的USB Dongle 的linux 驱动接口都是一样的,用户空间的控制程序也只是配置上的不同。在这里我们还是以华为K3765来举例,它支持WCDMA 的网络。通过对华为K3765拨号流程介绍,读者可以举一反三的了解到3G USB Dongle 的拨号流程,并很容易从网络上到TD-SCDMA,CDMA2000,USB Dongle 的配置数据。
在前文中我们提到如何去创建设备驱动文件ttyUSB0,接下来我们将探讨如何使用ppp 套件(只使用了chat 和pppd )。虽然华为K3765提供了4个ttyUSB 接口,但是我们只用使用第一个就可以了。chat 命令用来和modem 通过一系列AT 命令集交互,当底层拨号连接成功后在通过pppd 在ttyUSB0设备上进行数据收发。
ppp 的配置文件如下(/etc/ppp/peer/wcdma ):
nodetach
lock
/dev/ttyUSB0
modem
115200
user "card"
password "card"
crtscts
usepeerdns
noauth
noipdefault
novj
novjccomp
noccp
defaultroute
connect 'chat -s -v -f wcdma-connect'
disconnect 'chat -s -v -f wcdma-disconnect'
wcdma-connect 脚本如下(/etc/ppp/wcdma-connect ):
TIMEOUT 5
ABORT 'NO CARRIER'
ABORT 'ERROR'
ABORT 'NO DIALTONE'
ABORT 'BUSY'
ABORT 'NO ANSWER'
''\rAT
OK \rATZ
OK \rAT+CGDCONT=1,"IP","3gnet",,0,0
OK-AT-OK ATDT*99#
CONNECT \d\c
wcdma-disconnect 脚本如下(/etc/ppp/wcdma-disconnect ):
ABORT "BUSY"
ABORT "ERROR"
ABORT "NO DIALTONE"
''"\K"
''"+++ATH"
SAY "\ndisconnected\n"
最后我们只用通过下面的命令来进行拨号和连接:pppd call wcdma 。
5结束语
3G 的出现使得移动的无线宽带成为可能,借助无线宽带连接,嵌入式的linux 有了更大的应用空间。通过把这两种技术结合,不但可以改进现有的一些网络应用,比如我们可以把传统的有线视频监控改造成3G ,不但省去了布线的麻烦,而且更容易部署。有了3G ,嵌入式linux 能开展无限的应用。
参考文献:
[1]
第三代行动通讯[EB/OL]./zh-hans/3G.[2]
Carla Schroder.Linux Networking Cookbook :中文版.[M].南京:东南大学出版社.2009.[3]
Jonathan Corbet.Linux 设备驱动程序[M].3版.北京:中国电力出版社.2006.[4]usb_modeswitch[EB/OL]
.www.draisberghof.de/usb_modeswitch/.
5657

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。