1导言
跟着嵌入式体系的开展,嵌入式 Linux以其稳定性和开放源代码的优点在嵌入式体系的开发中得到广泛运用。越来越多的软硬件厂商运用嵌入式 Linux来开发自己的产品,对根据嵌入式 Linux渠道开发设备的驱动程序和运用程序的需求在成倍增长。本文经过完结对 PXA255开发板外围字符设备(电机、数码管、串口和 mini键盘)的操作和控制,详细评论了嵌入式 linux字符设备驱动的规划与运用。
2体系的规划结构
体系的规划分为字符设备驱动程序和人机交互界面两部分。驱动程序为运用程序供给了操作设备的接口;人机交互界面的规划完结设备运用程序并完结人机交互的功用。整个体系软硬件的联系如图 1:字符设备被映射到 Linux文件体系的文件和目录,经过文件体系的体系调用接口 open(),write(),read(),close()等函数拜访字符设备,完结设备的操作。
图 1 体系软硬件的联系
3体系字符设备驱动程序的规划办法
Linux驱动程序是设备与详细的运用程序的中间层,它供给操作设备的接口,运用程序员不需求知道详细设备作业细节,只需调用一组标准化的函数就能完结对设备的操作,这些标准化的函数与详细的驱动没有联系,而将这些函数映射到效果于详细设备上的操作则与驱动程序相关[1]。Linux设备分为字符设备,块设备和网络设备,字符设备是能够像字节省相同被拜访的设备。以下经过描绘字符设备(电动机、数码管、串口、mini键盘)驱动的完结办法,深化评论了根据嵌入式 linux的字符设备驱动的规划办法和完结进程。
3.1初始化函数与铲除函数
Linux体系中,设备驱动的初始化函数担任注册设备,并完结驱动程序必要的初始化以及请求中止等[2],Linux体系运用 module_init宏指定初始化函数。在初始化函数中调用 regiSTer_chrdev函数向体系注册字符设备,经过 request_IRq 函数请求中止。例如电机设备的初始化函数如下:
static int __init moto_init(void){
int ret;
ret = register_chrdev(MOTO_MAJOR, “moto”, &moto_fops);//注册电机设备
if (ret) {
printk(KERN_ERR “%s: can‘t get major %d.n”,
__func__, MOTO_MAJOR);
return ret;
}
printk(KERN_INFO “%s: register moto device successfully.n”, __func__);
return 0;
} 其间,register_chrdev函数的第一个参数为主设备号,假如为0 则体系为此驱动程序动态地分配一个主设备号;第二个参数是设备称号,这儿是以moto为设备称号;第三个参数moto_fops是默许的struct file_operaTIons结构体 。
铲除函数的功用和初始化函数的功用相反,它将驱动程序所占用的体系资源、中止号进行开释。Linux体系运用 module_exit宏指定铲除函数。
3.2中止
在 Linux 体系中,中止是由体系来办理与保护的。中止服务子程序在初始化函数中调用 request_irq 函数与相应中止号相关,并将该中止的相关信息添加到体系的中止信息列表中。中止发生时, Linux体系呼应中止号来完结中止处理程序的履行。mini键盘按键触发发生中止号为 SIMPLE_KEY_IRQ的中止,体系主动检索并调用键盘中止服务子程序。键盘中止处理流程如图 2:
3.3 设备驱动接口的完结
在Linux内核中,字符设备运用 struct file_operaTIons结构体来完结设备的各种操作接口,这些操作首要用来完结体系调用,命名为 open、read等等。file_operaTIons结构是界说在 《linux/fs.h》中的函数指针数组,每个设备文件都与它自己的操作函数相相关。编写字符设备驱动程序,首要是完结 struct file_operaTIons结构中的各个函数。
本体系各设备驱动的规划首要完结 open、read、write和 release这四个办法接口。 file_operation结构成员如下: /* DEVICE驱动程序设备操作办法集 */ struct file_operations device_fops = {
open办法供给给驱动程序以初始化的才干,然后为今后的操作完结初始化做准备。本体系中存在多个设备共用一个驱动的状况,驱动中的 open办法程序结构如下:
int device_open(struct inode *inode, struct file *filp){ int minor = MINOR(kdev); //次设备号的读取 switch(minor) {
case first_device: device_first_vaddr = (unsigned long)ioremap (DEVICE_ FIRST _ADDR, 2);
……
case second_device:
……
default:
……
} MOD_INC_USE_COUNT; // 递加模块引证计数 , 避免模块在运用中被卸载 if (down_interruptible(&device_mutex)) { …… }; }
1)open办法调用 MINOR(kdev)宏完结次设备号的读取,运用 switch句子完结设备的匹配初始化。Linux体系为每一个设备分配了一个主设备号和次设备号。主设备号标识详细的设备驱动程序,次设备号标识详细设备。开发板电机设备有直流电机和步进电机,它们的主设备号都是 252,次设备号分别为 0和 1。数码管、串口、 mini键盘的驱动规划只针对单个设备,次设备号规划为 0。
2)ioremap函数在 open办法中完结对电机、数码管、串口、mini键盘寄存器的拜访。 PXA255处理器有专门的存储器办理单元(MMU),在驱动中不能直接对设备 I/O内存的物理地址进行读写,需求调用ioremap 等内核函数将寄存器的实践物理地址映射到内核一致的地址空间中,然后完结了对物理地址的直接调用。例如寄存器 DEVICE_ FIRST _ADDR的读写操作,经过读写 device_first_vaddr变量完结。在 asm/arch/pxa-regs.h头文件中界说了各种寄存器的宏,文件中的宏变量都是经过地址映射的能够直接运用。
release办法的效果正好与 open相反,经过调用 iounmap函数吊销 device设备的虚拟地址映射,一起开释互斥锁,递减模块引证计数,当模块引证计数减到 0时,close函数才干真实的封闭设备。read和 write办法的使命是相似的,首要完结用户空间和内核空间之间的数据复制。
read办法程序结构如下:
ssize_t device_read(struct file *filp, char *buf, size_t count, loff_t *offp){
……
if (copy_to_user(buf, (u8 *)&BUF, count)) { ……} //写数据给用户空间
return count; // 回来成功读取的字节数 }
其间,copy_to_user函数完结内核空间到用户空间的数据复制。运用程序调用该办法接口完结串口数据的接纳。
write办法的完结同read办法相似。经过调用 copy_from_user函数完结用户空间到内核空间的数据复制。该办法接口完结串口数据的发送、LED和MOTO控制寄存器的设置。
3.4 驱动的装载和卸载
Linux驱动程序的编译加载有两种办法。一种是编译成模块在运转时加载,不需求从头启动内核,它运用 insmod东西将驱动模块加载进内核,运用 rmmod从内核中卸载模块。该办法完结如下:1)编译驱动并下载驱动到开发板:$ arm-linux-gcc device_driver.c -I /home/eflag/kernel/include/ -c生成 device_driver.o文件,经过 tftp东西下载到开发板;2)驱动的加载:$ insmod device_driver.o。设备驱动的加载成功后,能够编写运用程序进行设备驱动的检测;3)驱动的卸载:$ rmmod device_driver。
另一种是将驱动程序静态编译进内核,再运转新的内核来测验驱动,该办法是在linux体系字符设备驱动文件夹linux/driver/char/中参加设备驱动源程序,一起修正 makefile文件,从头编译内核,下载新内核到开发板,体系启动后主动加载设备驱动 [3]。在驱动加载成功后就能够对该驱动的设备进行读写等操作。 4 Qt人机界面的完结
Qt是由 Troolltech公司开发的一套开源图形用户界面库。它给运用程序开发者供给了开发图形界面所需的各种功用。Qtopia core是嵌入式环境下所运用的 Qt,许多嵌入式产品如 PDA、手机都选用 qtopia core的图形库作为人机界面规划的结构。本体系运用 qtopia core的图形库进行用户界面的开发。
4.1 Qt运用程序的规划
Qt的事情驱动机制是 single/slot(信号/槽)机制,经过 connect函数衔接控件信号(Single)与槽函数(slot)。首要控件触发发生 Single信号,然后由 signal信号触发履行槽函数[4]。本体系中槽函数为详细设备运用程序。
设备运用程序的开发首要是体系函数的调用,如 open(翻开设备),read/write(读写设备),close(封闭设备)等。本体系设备运用程序开发如下: RS232收发数据功用; LED跑马灯功用;控制电机滚动功用;mini键盘键值读取功用。
Linux体系中设备作为文件被拜访,对设备进行拜访前需树立设备节点:
$mknod /dev/device_name c MAJOR MINOR
其间 device_name是设备节点名, c是字符设备标志, MAJOR是主设备号,MINOR是
次设备号。open函数运用/dev/device_name作为文件途径来翻开设备。
4.2Qt运用程序的运转
1)编译 Qtopia core运用程序生成可履行文件 application。经过 tftp东西下载可履行文件到开发板;2)开发板中 application可履行文件的运转: $ chomd +x application $ 。/application –qws。
LCD显现器显现人机交互界面如图 3,经过输入设备如鼠标、键盘、触摸屏能够完结设备的操作。
5 总结
完结了电机、数码管、串口和 mini键盘的驱动程序和运用程序的开发,规划了人机交互界面。
本文立异点:详细分析了嵌入式 Linux下字符设备驱动程序的构建进程。整个体系的规划和完结进程对嵌入式 Linux体系的开发有必定的参考价值。