一 . 驱动框架:
①file_operation结构体,里面包含open,read,write等操作函数
②写出open,read,write等函数
③结构体要告诉内核,所以要写入口函数,最重要的是register_chrdev(设备号,“设备名”,&xxx_drv_fops)
④对入口函数继续宁修饰后,让内核识别 module_init (xxx_drv_init)
⑤对应的入口函数,同样需要出口函数,unregister_chrdev(设备号,“设备名”)
⑥对出口函数的修饰module_exit(xxx_drv_exit)
⑦内核自动分配设备号。方法:创建一个全局变量 int major 将注册函数中的设备号写0 major=register/_chrdev(0,"设备名",&xxx_drv_fops)
⑧利用mdev机制,可以自动创建设备节点,根据内核自动分配的设备号
方法:创建一个类 static struct class *xxxx_class;
static struct class_device *xxxx_class_dev; 在类下面创建一个设备
seconddrv_class = class_create(THIS_MODULE, "xxx"); xxx代表类名 创建一个类
seconddrv_class_dev = class_device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "aaa"); 在类下面创建一个设备 aaa设备名
这个要写在入口函数中
⑨相应的在出口函数中要删除相应的类 class_device_unregister(seconddrv_class_dev);
class_destroy(seconddrv_class);
二 .硬件操作:
①看原理图,在这里看原理图中按键所对应的IO口 EINT0 GPF0 EINT2 GPF2 EINT11 GPG3 EINT19 GPG19
②看2440手册 操作寄存器 GPXCON和GPXDAT
③写代码:a.单片机程序是直接操作物理地址 b.驱动程序操作虚拟地址 虚拟地址就用到ioremap(地址,长度)对物理地址进行映射在入口函数中。对应的在出口函数
中要将映射的地址取消iounmap
④在open函数中要将IO口设置为输入模式 输入模式对应的位为 00 例:*gpfcon &=~((0x3<<(0*2))|(0x3<<(2*2))) 所以GPF0和GPF2设置为输入模式
⑤在相应的read函数中写读按键电平的程序 重要的语句:unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) 实现将内核的数据传入到用户空间 可以将读到的相应引脚的电平存入数组中传给应用函数
三.应用函数
①fd = open("/dev/buttons", O_RDWR);
②read(fd, key_vals, sizeof(key_vals)); 将驱动程序中的数组传入到应用程序中的数组中
用while死循环的形式实现按键的查询
总结:查询读模式对CPU占用很大在arm板上可以后台运行查看 例:seconddrvtest & top便可查看