Linux 系统下4G 终端模块驱动的实现
Abstract: The device driver of Linux system is analyzed, and the USB interface device driver is compiled with the kernel principle. The 4G module is compiled with an example. The Linux system is verified by the 4G system. The system kernel can correctly identify the 4G module and allocate memory..
Linux系统以其良好的可剪裁性、强稳定性以及易操作等特点,已在物联网,程序控制,电子消费,智能家居等领域得到广泛的使用。4G网络的推广和应用也在各领域展开。因此,将Linux设备与4G网络有机地结合起来,为新一代物联网构造一个更加高速,更加安全,更加稳定的网络通信环境,将会成为一个应用热点。
本文介绍了一种Linux系统驱动4G模块的方法,Linux系统通过USB 接口驱动4G终端模块,实现4G网络的接入。首先,文章介绍了整体的软硬件应用环境,然后分析了Linux系统下的设备驱动以及USB接口设备驱动的编写原理,完成了4G终端模块在Linux系统中的驱动程序编写和内核编译,并且最后对驱动的内核烧入进行了验证性测试。
1 Linux系统设备驱动原理
当一个新的硬件设备接入Linux系统时[1],我们需要加载与其对应的驱动程序,之后驱动程序会根据自己的类型向Linux系统注册,注册成功后系统会为驱动程序配置与其类型相应的软件接口以及反馈一个主设
备号给驱动程序,然后驱动程序会根据这个主设备号在/dev目录下创建一个设备文件,这样,我们就可以通过这个设备文件来对接入的硬件设备进
行控制了。
1.1 Linux系统设备驱动类型
Linux采用的是整体式的内核结构[3],这种结构的内核一般不能动态的增加新的功能。为此,Linux提供了一种叫可安装“模块”的机制,这种机制可以根据需要,在不必对内核重新编译连接的条件下,将可安装模块从运行的内核中动态的插入或移除。使得内核的内存映象保持最小,又同时具有很大的灵活性和可扩充性。绝大多数的设备驱动程序便是以内核模块的形式存在于系统当中的。
驱动程序的类型主要有三种:字符设备、块设备或网络设备。驱动示原理结构如图1所示。
字符设备是指在I/O传输中使用字符为单位进行传输的设备,可以在/dev目录下通过对应的设备文件去访问。由字符设备驱动程序来实现,字符设备驱动程序通常需要至少实现open、close、read和write系
统调用。
块设备是为大量数据的传输和慢速设备为设计的,能够容纳文件系统,也可以通过/dev目录下的文件系统节点来访问。和字符设备驱动程序相比,块设备驱动程序与内核之间的软件接口完全不同。
网络设备是指一个经过形成网络接口,能够和其他主机交换数据的设备。与字符设备或块设备不同的是网络设备不能通过对应的设备文件去访问。
在Linux系统中,终端属于字符型设备,它有多种类型,通常使用tty 来简称各种类型的终端设备。
1.2 USB驱动终端模块原理
Linux内核支持两种方式的USB驱动程序[4][5]:作为主机的驱动程序和作为设备的驱动程序。从主机观点来看,主机的驱动程序控制插入其中的设备,而设备上的驱动程序控制该设备如何与主机通信。设备上的驱动程序都是由产商在生产时写入设备的,我们需要编写的就是主机系统上的驱动程序。
在Linux系统中[5],USB驱动程序存在于不同的内核子系统和USB硬件控制器之间,如图2所示,USB核心为USB驱动程序提供了一个用于访问和控制USB硬件的接口,而不必考虑系统当前存在的各种不同类型的USB 硬件控制器。可以大大减少驱动开发的工作量。
在Linux USB子系统中,USB主机控制驱动直接和硬件进行交互,是USB协议栈的最底层部分,是USB主机控制器硬件和数据传输的一种抽象。USB主机控制驱动向上仅对USB核心服务。HCD向下则直接管理和检测主控制器硬件的各种行为。
USB核心(USBD)是对整个USB子系统的抽象,在整个子系统中起着承上启下的作用,USBD通过定义一组宏、数据结构和函数来抽象出所有硬件或是设备具有依赖关系的部分。USBD中主要有四个数据结构,如图3所示。
其中,usb_device保存USB设备的信息,包括设备地址,设备描述符,配置描述符等。usb_bus保存一个USB总线系统的信息,包括总线上设备地址信息,根集线器,带宽使用情况等。usb_driver保存客户驱动信息,包括驱动名称,以及驱动提供给USB内核使用的函数指针等。URB (Universal Request Block)是进行USB通信的数据结构,USBD通过URB
在USB设备类驱动和USBD、USBD和HCD间进行数据传输。
1.3驱动程序的编译Linux驱动程序有2种编译方式,一种是直接与内核一同编译,与内核同时启动,这样在硬件设备连接上主机后,主机能够自动识别,并通过驱动设备来使用硬件资源;另一种是生成模块,当应用程序需要使用硬件资源的时候调用ko文件加载驱动模块,加载后便可对硬件设备进行控制与操作了,但每次模块卸载或主机重启后,需对驱动模块重新加载才能使用硬件设备。这种情况能保
证内核镜像的最小,但是每次使用之前需要编译,使用起来较为繁琐。
在这里我们以第一种方式,即与内核一同编译作为实例。
2 4G模块驱动的实现
2.1 驱动程序的编写
在Linux kernel源码目录中的driver/usb/usb-skeleton.c文件为我们提供了一个最基础的USB驱动程序。我们称为USB骨架。为我们提供了良好的驱动编写框架,根据以联芯4G终端模块LC1761为例[2],完成驱动程序的主要内容如下。
1)通过创建结构体struct usb_driver,来注册(init)或注销(exit)USB驱动程序。
static struct usb_driver usb2com_driver = {
.name = "lc_ltetty",
.probe = usb2com_probe,
.disconnect = usb2com_disconnect,
.id_table = usb2com_table,
.suspend = usb2com_suspend,
.resume = usb2com_resume,
static int __init usb2com_init(void)
static void __exit usb2com_exit(void)
usb_driver结构体向USB子系统提供各种相关信息,当中的每个成员都需要单独实现
static int usb2com_probe(struct usb_interface *interface,const struct usb_device_id *id)
linux终端下载软件static void usb2com_disconnect(struct usb_interface
*interface)
static struct usb_device_id usb2com_table[]=
static int usb2com_suspend(struct usb_interface *intf,
pm_message_t message)
static int usb2com_resume(struct usb_interface *intf)
其中,探测(probe)函数通过检测每个端点的的信号结构类型,用于判断本驱动是否适合这个设备
static inline int usb_endpoint_type(const struct
usb_endpoint_descriptor *epd)
static inline int usb_endpoint_dir_in(const struct
usb_endpoint_descriptor *epd)
static inline int usb_endpoint_dir_out(const struct
usb_endpoint_descriptor *epd)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论