经过前面的装备,S5PV210开发现已能够成功进入Linux控制台了,那么,有了这个环境就能够开端学习Linux驱动的编写和测试了。学习Linux设备驱动,通常是从字符设备驱动开端。我写的第一个驱动程序是Led的,其实也便是了解下字符设备驱动的根本结构,本文以中止方法的按键驱动为例,简略的介绍下字符设备驱动程序。
一 按键驱动程序的简略完成
下面是根据中止和音讯的按键驱动程序,其作业原理是:当应用程序读取键值时,会调用按键驱动程序的read函数,而咱们完成的read函数检测完读取长度后没有直接读取键值而是等候按键音讯,假如没有按键,程序会进入休眠状况,这样能够节约很多的CPU,而当咱们按键时硬件会发生中止,程序主动进入中止处理函数,在中止处理函数中,驱动程序读取键值存入全局变量并激活read函数中等候的音讯,应用程序被敏捷唤醒并经过read函数读取键值,如此,完成了获取键值的作业。下面是源码,比较简略,也就不多说了。
源码:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- staticdev_tdevno;
- staticstructcdevcdev;
- staticstructclass*buttons_class;
- staticstructdevice*buttons_device;
- staticwait_queue_head_tbutton_waitq;
- staticvolatileintpressed=0;
- staticunsignedcharkey_val;
- structkey_desc{
- unsignedintpin;
- unsignedcharvalue;
- };
- staticstructkey_desckey_descs[8]={
- [0]={
- .pin=S5PV210_GPH0(0),
- .value=0x00,
- },
- [1]={
- .pin=S5PV210_GPH0(1),
- .value=0x01,
- },
- [2]={
- .pin=S5PV210_GPH0(2),
- .value=0x02,
- },
- [3]={
- .pin=S5PV210_GPH0(3),
- .value=0x03,
- },
- [4]={
- .pin=S5PV210_GPH0(4),
- .value=0x04,
- },
- [5]={
- .pin=S5PV210_GPH0(5),
- .value=0x05,
- },
- [6]={
- .pin=S5PV210_GPH2(6),
- .value=0x06,
- },
- [7]={
- .pin=S5PV210_GPH2(7),
- .value=0x07,
- },
- };
- staticirqreturn_tbuttons_irq(intirq,void*dev_id){
- volatilestructkey_desc*key=(volatilestructkey_desc*)dev_id;
- if(gpio_get_value(key->pin)){
- key_val=key->value|0x80;
- }
- else{
- key_val=key->value;
- }
- pressed=1;
- wake_up_interruptible(&button_waitq);
- returnIRQ_RETVAL(IRQ_HANDLED);
- }
- staticintbuttons_open(structinode*inode,structfile*file){
- intret;
- ret=request_irq(IRQ_EINT(0),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key1″,&key_descs[0]);
- if(ret)
- returnret;
- ret=request_irq(IRQ_EINT(1),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key2″,&key_descs[1]);
- if(ret)
- returnret;
- ret=request_irq(IRQ_EINT(2),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key3″,&key_descs[2]);
- if(ret)
- returnret;
- ret=request_irq(IRQ_EINT(3),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key4″,&key_descs[3]);
- if(ret)
- returnret;
- ret=request_irq(IRQ_EINT(4),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key5″,&key_descs[4]);
- if(ret)
- returnret;
- ret=request_irq(IRQ_EINT(5),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key6″,&key_descs[5]);
- if(ret)
- returnret;
- ret=request_irq(IRQ_EINT(22),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key7″,&key_descs[6]);
- if(ret)
- returnret;
- ret=request_irq(IRQ_EINT(23),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key8″,&key_descs[7]);
- if(ret)
- returnret;
- return0;
- }
- staticssize_tbuttons_read(structfile*file,char__user*data,size_tcount,loff_t*loff){
- if(count!=1){
- printk(KERN_ERR”Thedrivercanonlygiveonekeyvalueonce!”);
- return-ENOMEM;
- }
- wait_event_interruptible(button_waitq,pressed);
- pressed=0;
- if(copy_to_user(data,&key_val,1)){
- printk(KERN_ERR”Thedrivercannotcopythedatatouserarea!”);
- return-ENOMEM;
- }
- return0;
- }
- staticintbuttons_close(structinode*inode,structfile*file){
- free_irq(IRQ_EINT(0),&key_descs[0]);
- free_irq(IRQ_EINT(1),&key_descs[1]);
- free_irq(IRQ_EINT(2),&key_descs[2]);
- free_irq(IRQ_EINT(3),&key_descs[3]);
- free_irq(IRQ_EINT(4),&key_descs[4]);
- free_irq(IRQ_EINT(5),&key_descs[5]);
- free_irq(IRQ_EINT(22),&key_descs[6]);
- free_irq(IRQ_EINT(23),&key_descs[7]);
- return0;
- }
- structfile_operationsbuttons_ops={
- .open=buttons_open,
- .read=buttons_read,
- .release=buttons_close,
- };
- intbuttons_init(void){
- intret;
- cdev_init(&cdev,&buttons_ops);
- cdev.owner=THIS_MODULE;
- ret=alloc_chrdev_region(&devno,0,1,”buttons”);
- if(ret){
- printk(KERN_ERR”allocchardeviceregionfaild!”);
- returnret;
- }
- ret=cdev_add(&cdev,devno,1);
- if(ret){
- printk(KERN_ERR”addchardevicefaild!”);
- gotoadd_error;
- }
- buttons_class=class_create(THIS_MODULE,”buttonsdrv”);
- if(IS_ERR(buttons_class)){
- printk(KERN_ERR”createclasserror!”);
- gotoclass_error;
- }
- buttons_device=device_create(buttons_class,NULL,devno,NULL,”buttons”);
- if(IS_ERR(buttons_device)){
- printk(KERN_ERR”createbuttonsdeviceerror!”);
- gotodevice_error;
- }
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/256198.html