飞凌 ok6410 按键驱动源码及测试代码

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

由于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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试官 | 什么是递归算法?它有什么用?

前言递归是算法中一种非常重要的思想&#xff0c;应用也很广&#xff0c;小到阶乘,再在工作中用到的比如统计文件夹大小&#xff0c;大到 Google 的 PageRank 算法都能看到&#xff0c;也是面试官很喜欢的考点最近看了不少递归的文章&#xff0c;收获不小&#xff0c;不过我发现…

双缓冲技术绘图

2019独角兽企业重金招聘Python工程师标准>>> 一、双缓冲技术的应用 当数据量很大时&#xff0c;绘图可能需要几秒钟甚至更长的时间&#xff0c;而且有时还会出现闪烁现象&#xff0c;为了解决这些问题&#xff0c;可采用双缓冲技术来绘图。我们知道,如果窗体在响应W…

2.Pycharm + Django + Python进行WEB路由配置

一、普通路由配置 1.利用PyCharm创建工程名为mysite的Django项目&#xff0c;在mysite文件上新建views.py视图文件&#xff0c;如下图示&#xff1a; 2.在urls.py文件中导入view.py视图文件 from . import views3.在urls.py文件中添加新的路由&#xff0c;如下图示&#xff1…

面试官 | Oracle JDK 和 OpenJDK 有什么区别?

作者 | petercao来源 | urlify.cn/yAn6ruOpenJDK是Sun在2006年末把Java开源而形成的项目&#xff0c;这里的“开源”是通常意义上的源码开放形式&#xff0c;即源码是可被复用的&#xff0c;例如IcedTea、UltraViolet都是从OpenJDK源码衍生出的发行版。Oracle JDK采用了商业实现…

Python通过snmp获取交换机VLAN号、VLAN默认网关、VLAN子网掩码和ARP表中的IP地址与MAC对应记录数据

自己做项目时,自己封装的Python通过snmp获取交换机VLAN号、VLAN默认网关、VLAN子网掩码和ARP表中的IP地址与MAC对应记录数据。 myPySnmp.py源代码 """ mySnmpScan类,扫描核心交换机发送oid或MIB值获取对应数据 """ # -*- coding: utf-8 -*- i…

面试官 | 如何提高服务器的并发能力?

作者 | 潇洒一剑来源 | cnblogs.com/zengjin93/p/5569556.html什么是服务器并发处理能力一台服务器在单位时间里能处理的请求越多&#xff0c;服务器的能力越高&#xff0c;也就是服务器并发处理能力越强有什么方法衡量服务器并发处理能力1. 吞吐率吞吐率&#xff0c;单位时间里…

html网页的结构框架代码

推荐使用Notepad编辑器写HTML代码 Notepad官网下载地址 html学习网址&#xff1a; w3school在线教程 html网页的结构框架.html <!--文档声明&#xff0c;声明当前网页的版本--> <!DOCTYPE html> <!--html的根标签&#xff08;元素&#xff09;&#xff0c;网…

Spring 经典面试题汇总.pdf(2020版)

作者 | 静默虚空来源 | juejin.im/post/5cbda379f265da03ae74c2821、基础1.1. 不同版本的 Spring Framework 有哪些主要功能&#xff1f;Version FeatureSpring 2.5发布于 2007 年。这是第一个支持注解的版本。Spring 3.0发布于 2009 年。它完全利用了 Java…

面试官 | SpringBoot 中如何实现异步请求和异步调用?

作者 | 会炼钢的小白龙来源 | cnblogs.com/baixianlong/p/10661591.html一、SpringBoot中异步请求的使用1、异步请求与同步请求 特点&#xff1a;可以先释放容器分配给请求的线程与相关资源&#xff0c;减轻系统负担&#xff0c;释放了容器所分配线程的请求&#xff0c;其响应将…

HTML网页结构化框架、meta标签和语义化标签

1.HTML网页结构化框架代码示例 myhtml.html <!--文档声明&#xff0c;声明当前网页的版本--> <!DOCTYPE html> <!--html的根标签&#xff08;元素&#xff09;&#xff0c;网页中的所有内容都要写在根元素的里边--> <html lang"en"> <!…

Android之个性化ListView实现

2019独角兽企业重金招聘Python工程师标准>>> Android中提供的ListView部件&#xff0c;用来在android手机中展现一个列表&#xff0c;这个列表的表现形式&#xff0c;完全由你选择的Adapter有关系&#xff0c;android框架中已有的adapter&#xff0c;形式都比较单调…

面试官 | Class.forName 和 ClassLoader 有什么区别?

作者 | 纪莫来源 | dwz.date/eUc在 Java 中 Class.forName() 和 ClassLoader 都可以对类进行加载。ClassLoader 就是遵循双亲委派模型最终调用启动类加载器的类加载器&#xff0c;实现的功能是“通过一个类的全限定名来获取描述此类的二进制字节流”&#xff0c;获取到二进制流…

微信公众号使用Chrome插件:Markdown Nice优化微信公众号排版教程

Markdown Nice 是一个为了解决微信公众号排版而生的 Markdown 编辑器&#xff0c;当前有在线编辑器和 Chrome 插件 2 种产品形态。 下面介绍Chrome 插件&#xff1a;Markdown Nice 一、下载和安装Markdown Nice 1.从 墨滴 网站下载mdnice谷歌浏览器插件&#xff0c;如下图&a…

面试官 | 如何优雅的设计Java 异常?

作者 | lrwinx来源 | lrwinx.github.io异常处理是程序开发中必不可少操作之一&#xff0c;但如何正确优雅的对异常进行处理确是一门学问。异常的类别正如我们所知道的&#xff0c;java中的异常的超类是java.lang.Throwable(后文省略为Throwable),它有两个比较重要的子类,java.l…

3.Python Django之GET请求和POST请求及响应处理

一、请求中的方法 方法描述GET请求指定的页面信息&#xff0c;并返回实体主体。HEAD类似于GET请求&#xff0c;只不过返回的响应中没有具体的内容&#xff0c;用于获取报头。POST向指定资源提交数据进行处理请求&#xff08;例如&#xff1a;提交表单或者上传文件&#xff09;…

面试官 | Java中的注解是如何工作的?

自Java5.0版本引入注解之后&#xff0c;它就成为了Java平台中非常重要的一部分。开发过程中&#xff0c;我们也时常在应用代码中会看到诸如Override&#xff0c;Deprecated这样的注解。这篇文章中&#xff0c;我将向大家讲述到底什么是注解&#xff1f;为什么要引入注解&#x…

优秀的代码原来是这样分层的

作者 | 咖啡拿铁来源 | t.cn/RdrmI7i1、背景说起应用分层&#xff0c;大部分人都会认为这个不是很简单嘛 就controller&#xff0c;service, mapper三层。看起来简单&#xff0c;很多人其实并没有把他们职责划分开&#xff0c;在很多代码中,controller做的逻辑比service还多,se…

面试官 | 什么是 Lambda?该如何使用?

作者 | Mingqi来源 | zhihu.com/question/20125256/answer/3241213081.什么是Lambda?我们知道&#xff0c;对于一个Java变量&#xff0c;我们可以赋给其一个“值”。如果你想把“一块代码”赋给一个Java变量&#xff0c;应该怎么做呢&#xff1f;比如&#xff0c;我想把右边那…

面试官 | 线程间是如何通信的?

作者 | wingjay来源 | wingjay.com正常情况下&#xff0c;每个线程独立完成自己的任务就结束了&#xff0c;但某些特殊情况下&#xff0c;我们需要多个线程来共同完成某项任务&#xff0c;这时就涉及到了线程间通信了。本文涉及到的知识点&#xff1a;thread.join()object.wait…

Linux debian解压和压缩.rar文件教程

一、简介 我们上传到Linux服务器上的文件日常是.zip或.tat.gz的文件&#xff0c;我们可以用相应的命令对文件进行解压。有时会遇到.rar文件。本次使用rar软件版本是5.6.0。官方网站为http://www.rarlab.com/ 二、下载和安装rar文件 1.创建文件夹 [rootdoudou ~]# mkdir /us…