按键驱动代码:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define DEVICE_BUTTON "mybtn"
- #define BTN_MAJOR 255
- static char keybuf[] = {"0"};
- static struct miscdevice misc = {
- .minor = BTN_MAJOR,
- .name = DEVICE_BUTTON,
- };
- irqreturn_t key_isr(int irq, void* dev)
- {
- int btn = 0;
- //读取按键状态
- btn= !gpio_get_value(GPIOL(14));
- printk("key %srn", btn ? "down" : "up");
- //把按键状态更新到对应的按缓冲中
- keybuf = “0” + btn;
- return IRQ_HANDLED;
- }
- static ssize_t btn_read (struct file *flp, char __user *buff, size_t count, loff_t * off)
- {
- int ret ;
- if(!count) {
- return 0;
- }
- ret = copy_to_user(buff, keybuf, count);
- if(ret) {
- printk("error:copy_to_userrn");
- return -EFAULT;
- }
- return count;
- }
- static const struct file_operations dev_fops = {
- .read = btn_read ,
- .owner = THIS_MODULE,
- };
- static int __init btn_init(void)
- {
- int ret;
- int irq;
- int flags;
- flags = IRQ_TYPE_EDGE_BOTH;
- irq = gpio_to_irq( GPIOL(14) );
- //发生中断号为irq的中断会执行key_isr函数。注册成功会在/proc/irq号/KEY文件夹出现或 cat /proc/interrupts, 记录了本中断发生的次数cat /proc/irq/442/spurious
- ret = request_irq(irq,key_isr, flags, "KEY",NULL);
- if(ret < 0)
- {
- irq = gpio_to_irq( GPIOL(14) );
- disable_irq(irq);
- free_irq(irq, NULL);
- return ret;
- }
- ret = misc_register(&misc);
- printk(KERN_EMERG " Device registered n ");
- return ret;
- }
- static void __exit btn_exit(void)
- {
- int irq;
- irq = gpio_to_irq( GPIOL(14) );
- disable_irq(irq);
- free_irq(irq, NULL);
- misc_deregister(&misc);
- printk(KERN_EMERG " Equipment logged out n");
- }
- module_init(btn_init);
- module_exit(btn_exit);
- MODULE_LICENSE("GPL");
复制代码
测试应用代码:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define DEV_NAME "/dev/mybtn"
- int main(int argc, char *args[])
- {
- int fd = 0;
- int ret = 0;
- unsigned char recv_buf[1] = {"0"};
- fd = open(DEV_NAME, O_RDONLY);
- //fd = open(DEV_NAME, O_RDONLY|O_NONBLOCK);
- if(fd < 0) {
- perror("open");
- }
- while(1) {
- strcpy(recv_buf, "0000");
- //读取按键数据
- ret = read(fd, recv_buf, 1);
- if((ret < 0) && (errno != EAGAIN)) {
- perror("read");
- exit(-1);
- }
- //输出按键状态
- printf("%srn", recv_buf);
- }
- return 0;
- }
复制代码
Makefile代码:
- KERN_DIR = /work/lichee/linux-3.4
- all:
- make -C $(KERN_DIR) M=`pwd` modules
- ARM-none-linux-gnueabi-gcc btntest.c -o btntest
- clean:
- make -C $(KERN_DIR) M=`pwd` modules clean
- rm -rf modules.order
- obj-m += btn_drv.o
复制代码
遗憾的是,代码虽然能编译成功,但是驱动加载有错误,等找出原因再发帖补充,同时也希望大神指点开发板交流群 QQ:641395230
|