符合input子系统的设备驱动之按键驱动(二)

发布时间 2023-07-12 18:02:53作者: Bright-Ho~蜗牛~

作者:Bright-Ho

联系方式:836665637@qq.com



符合input子系统的设备驱动之按键驱动(二)


上一节,我们大概的回顾了裸板按键驱动的方法,这一节,我们继续回顾,不带input子系统的按键字符设备驱动是怎么实现的?

 

这里直接上流程:

1)构造file_operstions结构;

static struct file_operations second_drv_fops = {

.owner = THIS_MODULE,

.open = second_drv_open,

.read = second_drv_read,

};

2)注册设备驱动;

major = register_chrdev(0,"second_drv",&second_drv_fops);

3)创建类,会在sys/class下生成;

class_create(THIS_MODULE,"seconddrv");

4)在类下面创建设备;

class_device_create(seconddrv_class,NULL,MKDEV(major,0),NULL,"buttons");

5)映射寄存器地址

gpfcon = (volatile unsigned long *)ioremap(0x56000050,16); gpfdat = gpfcon + 1;

gpgcon = (volatile unsigned long *)ioremap(0x56000060,16); gpgdat = gpgcon + 1;


6.open = second_drv_open函数实现什么内容?

static int second_drv_open(struct inode *inode,struct file *file){

 

printk("second drv open\n");

/*配置GPF02为输入引脚*/

*gpfcon &= ~((3<<0) | (3<<4));

/*配置GPG311为输入引脚*/

*gpgcon &= ~((3<<6) | (3<<22));

return 0;

}

    1.  .read = second_drv_read函数实现什么内容?

static ssize_t second_drv_read(struct inode *inode, const char __user *buf, size_t count, loff_t * ppos){

31

32 //printk("second drv write\n");

33

34 /*返回 4个引脚的电平*/

35 unsigned char key_vals[4];

36 int vals;

37

38 if(count != sizeof(key_vals)){

39 return -EINVAL;

40 }

41

42 /*读取GPF02*/

43 vals = *gpfdat;

44 key_vals[0] = (vals & (1<<0)) ? 1 : 0;

45 key_vals[1] = (vals & (1<<2)) ? 1 : 0;

46

47 /*读取GPG311*/

48 vals = *gpgdat;

49 key_vals[2] = (vals & (1<<3)) ? 1 : 0;

50 key_vals[3] = (vals & (1<<11)) ? 1 : 0;

51

52 copy_to_user(buf,key_vals,sizeof(key_vals)); /*从内核空间把参数传给用户空间*/

54 return 0;

55 }

 

 


整体流程来看,就是构造一个file_operations结构,并实现open,read等驱动接口,把该结构注册进内核;然后MDEV机制产生设备节点以备应用程序访问;映射寄存器地址;


open函数中:设置“控制寄存器”,把按键配置成输入引脚;

read函数中:通过“数据寄存器”来获得按键值;并通过copy_to_user()函数把按键值传递给用户空间的buf;


这一节有个重要的问题:在内核空间访问寄存器为什么要先ioremap?

这里大概说一下原因,原因是有mmu,地址都重映射了,datesheet中查到的寄存器地址,直接访问是访问不到的.所以需要ioremap !! 在内核中操作的都是虚拟地址,内核访问不到物理地址,只能通过ioremap映射为虚拟地址 内核才能访问此内存空间;

那么至于他是怎么映射的以后有时间我们再深入分析研究!!!


下一节,我们就来实现设备层;