2019独角兽企业重金招聘Python工程师标准>>>

由于OK6410的GPIO按键中断已经被飞凌自带的按键驱动注册,所以运行我们编写的按键驱动前要先去掉飞凌自带的按键驱动,方法:make menuconfig->Device Drivers->input device support->Key Boards->GPIO Buttons 去掉前面的*,即不选该项即可。

key.c

#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/gpio.h>#include <linux/types.h>#include <linux/cdev.h>#include <linux/interrupt.h>#include <linux/sched.h>#include <linux/device.h>#include <linux/poll.h>#include <linux/semaphore.h>#include <linux/timer.h>#include <asm/irq.h>#include <asm/uaccess.h>//#include <mach/hardware.h>#include <mach/irqs.h>#define DEVICE_NAME "keyint"#define KEYNUM 6dev_t devid;//static DEFINE_SEMAPHORE(key_lock);  //declare a mutex lock for keyint//定义一个信号量struct semaphore key_lock;static struct fasync_struct *key_async;static struct timer_list key_timer;struct key_irq_desc {int irq;        //irq numunsigned long flags;    //irq flags,identified the way of irq here,eq.edge,levelchar *name;        //irq name};static struct key_irq_desc key_irqs[] = {//下降沿产生中断{IRQ_EINT(0), IRQF_TRIGGER_FALLING, "KEY1"},{IRQ_EINT(1), IRQF_TRIGGER_FALLING, "KEY2"},{IRQ_EINT(2), IRQF_TRIGGER_FALLING, "KEY3"},{IRQ_EINT(3), IRQF_TRIGGER_FALLING, "KEY4"},{IRQ_EINT(4), IRQF_TRIGGER_FALLING, "KEY5"},{IRQ_EINT(5), IRQF_TRIGGER_FALLING, "KEY6"},};/*define a waiting queue here*/static DECLARE_WAIT_QUEUE_HEAD(key_waitq);/*define a event flag ev_press*/static volatile int ev_press = 0;static volatile int press_cnt[KEYNUM] = {0,0,0,0,0,0};/*中断处理函数*/static irqreturn_t keys_interrupt(int irq, void *dev_id){volatile int *press_cnt = (volatile int *) dev_id;/*set the pressed key flag(must do here due to not be static value)*/*press_cnt = *press_cnt + 1;//延时10ms后执行定时器处理函数mod_timer(&key_timer,jiffies+HZ/100);        //start timer after 10msreturn IRQ_RETVAL(IRQ_HANDLED);}//定时器处理函数static void key_timer_func(unsigned long data){ev_press = 1;//唤醒等待队列wake_up_interruptible(&key_waitq);kill_fasync(&key_async, SIGIO, POLL_IN);}static int key_fasync(int fd, struct file *filp, int on){printk("Function key_fasync\n");return fasync_helper(fd,filp,on,&key_async);}static unsigned key_poll(struct file *file, poll_table *wait){unsigned int mask=0;//指明要使用的等待队列poll_wait(file,&key_waitq,wait);//返回掩码if(ev_press)mask |= POLL_IN | POLLRDNORM;printk("poll wait\n");return mask;}static int key_open(struct inode *inode, struct file *file){int num;if(file->f_flags & O_NONBLOCK) {if(down_trylock(&key_lock)) return -EBUSY;}else {down(&key_lock);}//为每个按键注册中断处理程序for(num=0;num<KEYNUM;num++) {request_irq(key_irqs[num].irq, keys_interrupt, key_irqs[num].flags, key_irqs[num].name, (void *)&press_cnt[num]);}return 0;}static int key_close(struct inode *inode, struct file *file){int num;//释放中断号for(num=0;num<6;num++) {free_irq(key_irqs[num].irq, (void *)&press_cnt[num]);}up(&key_lock);printk("key_close free irqs\n");return 0;}static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp){//    unsigned int err;//判断是阻塞读还是非阻塞读if(filp->f_flags & O_NONBLOCK) {if(!ev_press)  return -EAGAIN;}else {/*if ev_press==0,then sleep*//*阻塞,当有按键按下时(中断)被唤醒*/wait_event_interruptible(key_waitq,ev_press);}//阻塞结束,有键按下了ev_press = 0;//拷贝数据到用户空间copy_to_user(buff,(const void *)press_cnt,min(sizeof(press_cnt),count));memset((void *)press_cnt,0,sizeof(press_cnt));//    printk("read and clean press_cnt\n");return 1;}static struct file_operations key_ops = {.owner     = THIS_MODULE,.open     = key_open,.release = key_close,.read     = key_read,.poll     = key_poll,.fasync     = key_fasync,};static struct cdev *cdev_keyint;static struct class *keyint_class;//模块初始化函数static int __init s3c6410_keyint_init(void) {int val;/*timer initial */init_timer(&key_timer);key_timer.function = key_timer_func;add_timer(&key_timer);/*初始化信号量*/init_MUTEX(&key_lock);/*register device*/val = alloc_chrdev_region(&devid,0,1,DEVICE_NAME);if(val) {return -1;printk("register keyint error\n");}cdev_keyint = cdev_alloc();cdev_init(cdev_keyint, &key_ops);cdev_keyint->owner = THIS_MODULE;cdev_keyint->ops   = &key_ops;val = cdev_add(cdev_keyint,devid,1);if(val) {return -1;printk("add device error\n");}keyint_class = class_create(THIS_MODULE,DEVICE_NAME);device_create(keyint_class,NULL,devid,NULL,"%s",DEVICE_NAME);printk("KEY initialezed ^_^\n");return 0;}static void __exit s3c6410_keyint_exit(void){cdev_del(cdev_keyint);device_destroy(keyint_class,devid);class_destroy(keyint_class);unregister_chrdev_region(devid,1);}module_init(s3c6410_keyint_init);module_exit(s3c6410_keyint_exit);MODULE_LICENSE("GPL");

Makefile

ifneq ($(KERNELRELEASE),)obj-m := key.o
elseKDIR := /forlinux/linux-3.0.1
all:make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif

产生.ko文件进行安装模块和设备 insmod,这里不需要mknod因为函数里调用了class_create和device_create会自动创建设备节点。

测试代码

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>int main(int argc, char **argv){int fd;int val;int i;int key_value[6];fd = open("/dev/keybutton",0);if(fd<0) {printf("open devie error\n");return -1;}while(1) {val = read(fd,key_value, sizeof(key_value));if(val<0) {printf("read error\n");continue;}for(i=0;i<6;i++) {if(key_value[i])printf("KEY%d pressed\n",(i+1),key_value[i]);}  }close(fd);return 0;}

转载于:https://my.oschina.net/u/274829/blog/286067

飞凌 ok6410 按键驱动源码及测试代码相关推荐

  1. S5PV210 按键驱动源码、应用程序解析(重点:中断、休眠唤醒、定时器)

    按键驱动是最简单的功能,一旦使用linux来做就需要做很多功课.anyway,逻辑层还是前年不变的.先贴上驱动层代码. /** linux/drivers/char/mini210_buttons.c ...

  2. sm4算法(附源码、测试代码)

    from:http://blog.csdn.net/mao0514/article/details/52930944 SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的.网址戳 ...

  3. java 获取包下的所有类,附完整源码和测试代码

    java 获取包下的所有类,完整Java代码如下: package com.example.demo.util;import java.io.File; import java.io.FileFilt ...

  4. linux内核移植与开发板,Linux 2.6.36内核移植飞凌OK6410开发板完整步骤详解

    Linux 2.6.36内核移植飞凌OK6410开发板完整步骤详解 [复制链接] 今天终于让Linux内核在飞凌的板子上跑起来了,想来也是艰辛,为了移植成功,断断续续做了将近两个月的努力,期间郁闷不可 ...

  5. Davinci DM6446开发攻略——LINUX GPIO驱动源码移植

    一.             DM6446 GPIO的介绍 说到LINUX 驱动移植,没有移植过的朋友,或刚刚进入LINUX领域的朋友,最好去看看<LINUX 设备驱动程序>第三版,有个理 ...

  6. 【内核配置】六、修改内核自带的的LCD驱动源码并编译进内核 | 烧写到Mini2440__TD35 完整攻略...

    主   机:VMWare--Ubuntu-16.04.2-x64-100ask 开发板:Mini2440--256M NandFlash, 2M NorFlash, 64M SDRAM, LCD-TD ...

  7. ADSP-21489的开发详解:SPIflash的硬件设计及程序烧写详解(含Flash驱动源码)

    硬件准备 ADSP-21489EVB:ADI 21489处理器的开发板 AD-HP530ICE:ADI DSP专用仿真器 USBi:ADI SigmaDSP和SHARC DSP的图形化编程调试器 软件 ...

  8. 12864液晶驱动源码,独创中英文混合输出

    12864液晶驱动源码,独创中英文混合输出 51单片机学习笔记:ST7920控制器的12864液晶使用总结 转载于:https://www.cnblogs.com/LittleTiger/p/4724 ...

  9. (转)Linux设备驱动之HID驱动 源码分析

    //Linux设备驱动之HID驱动 源码分析 http://blog.chinaunix.net/uid-20543183-id-1930836.html HID是Human Interface De ...

最新文章

  1. android之PackageManager简单介绍
  2. Netflix Zuul与Nginx的性能对比
  3. 使用Flex Bison 和LLVM编写自己的编译器[zz]
  4. webpack --- 发布环境的配置 代码压缩 代码分类
  5. 取出重复记录的第一条
  6. 编写一份代码,支持多种布署方式
  7. 2010计算机网络考研真题及答案,2010年计算机考研统考真题参考答案
  8. VIO-为什么要进行在线时间标定
  9. windows 7 多国语言包官方下载资源共享(32/64位)
  10. html背景图怎么做成水印,如何制作出有水印feel的PPT背景图片
  11. IPV6个人使用,实测电脑ping通联通手机
  12. Red5与Nginx Rtmp性能对比
  13. html返回顶部按钮图片,goToTop(回到顶部)按钮的制作
  14. 机械硬盘结构与固态硬盘
  15. 解决Markdown在线编辑器不能换行的问题
  16. [附源码]java毕业设计校园超市进销存管理系统
  17. LabVIEW控制Arduino实现RGB调色灯(基础篇—6)
  18. android入门-MMS-短彩信发送/接收流程【图】
  19. 金融反作弊中的设备指纹
  20. 移动硬盘中装linux,移动硬盘中安装Linux(CentOS)

热门文章

  1. 18f458中断入口C语言_操作系统开发之——中断
  2. w7计算机的收藏夹里弄出桌面,Win7电脑桌面的便签怎么弄出来?
  3. java趣味_Java趣味分享:try finally
  4. mysql orm c语言_【译】Simple MySQL ORM for C
  5. linux wifi ip,Linux环境下使用WIFI模块:使用DHCP工具动态获得IP地址
  6. 华为A1路由器虚拟服务器,华为a1路由器怎么设置 华为路由器a1怎么安装视频-192路由网...
  7. Android渠道包自动发布市场,Android Gradle实现打包指定渠道后自动上传到fir
  8. mysql-5.5.56配置_mysql 5.5.56免安装版配置方法
  9. docker 安装nacos_康过来!Nacos配置和管理微服务的使用
  10. deepin系统转为windows_windows系统下安装深度系统deepin