OK6410按键驱动程序(改)亲测可以运行

发布者:Xiaoxue666最新更新时间:2024-10-18 来源: cnblogs关键字:OK6410  运行 手机看文章 扫描二维码
随时随地手机看文章

#include <linux/kernel.h>  

 #include   

 #include   

 #include   

 #include gpio.h>  

 #include   

 #include   

 #include   

 #include   

 #include   

 #include   

 #include   

 #include   

  

 #include   

 #include   

  

 //#include   

 #include   

  

  

 #define DEVICE_NAME 'keyint'  

 #define KEYNUM 6  

 dev_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 num  

     unsigned long flags;    //irq flags,identified the way of irq here,eq.edge,level  

     char *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 10ms  

  

     return 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_fasyncn');  

     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 waitn');  

  

     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       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 irqsn');  

  

     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_cntn');  

  

     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 errorn');  

     }  

  

     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 errorn');  

     }  

  

     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);  

 }  

  

[1] [2]
关键字:OK6410  运行 引用地址:OK6410按键驱动程序(改)亲测可以运行

上一篇:WINCE 开机自动弹USB连接窗口问题(已解决)
下一篇:Uboot makefile学习记录

推荐阅读最新更新时间:2026-03-22 11:09

S5PV210(TQ210)学习笔记——按键驱动程序
经过前面的配置,S5PV210开发已经可以成功进入Linux控制台了,那么,有了这个环境就可以开始学习Linux驱动的编写和测试了。学习Linux设备驱动,通常是从字符设备驱动开始。由于linux驱动开发具有比较系统的体系结构,我很难在一篇文章中阐述其开发思路,为了简单起见,从本文开始,自行编写的驱动将直接附上代码,对开发过程中感触比较深的地方稍作陈述。 我写的第一个驱动程序是Led的,但是感觉没有必要发出来了,S5PV210(TQ210)的按键驱动程序源码,仅供参考: #include linux/types.h #include linux/module.h #include linux/cdev.h #incl
[单片机]
字符设备驱动程序按键驱动---中断方式
中断函数:包含#include linux/irq.h request_irq(irq,handle,irqflag,name,dev_id) { 1,分配一个irqaction结构体 2、把这个结构体放到irq_desc (action链表)中 3、设置引脚 4、使能中断 } free_irq(irq,dev_id) { 1、irqaciton出链 2、禁止中断 } ----------------------------------------------------------------------------------------------------------------------
[单片机]
51单片机入门 - 按键驱动程序设计实验
独立按键原理是这样的:按键没按下的时候,相应端口是高电平状态,而当按键按下的时候,相应的端口则是低电平。所以可以根据这个现象,实现相应的功能。 还有一点应该注意的是:按键在闭合和断开时,触点会存在抖动现象。 在实际情况下,我们需要的是稳定闭合的那部分状态。所以可以采用延时的方法来解决这个问题,具体的过程就是先看看有没有键按下,有键按下了,再延迟一段时间,再看看有没有键按下, 这时候如果还是有键按下的话那就真的是有键按下了。 而这个抖动的时间大概是10ms,所以只要用一个延时10ms的子函数就行。 上面代码的第66行那个判断按键是否松开也是必要的,虽然在这个程序中
[单片机]
51单片机入门 - <font color='red'>按键</font><font color='red'>驱动程序</font>设计实验
5.9UDP客户端服务器-基于OK6410
实验4-3:UDP客户端服务器 实验目的: 熟悉UDP客户端服务器编程 实验要求: 1、实现UDP客户端服务器回显程序 2、传输信息要求如下 (1)尝试用C语言结构去发送或接收一个信息包 (2)将服务器运行于开发板,客服端运行于ubuntu 12.04,抓包分析UDP协议 实验步骤: 服务端的程序: #include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/types.h #include sys/socket.h #include netinet/in.h #include ar
[单片机]
5.9UDP客户端服务器-基于<font color='red'>OK6410</font>
基于Ok6410开发板u-boot的移植
前提环境:Win7+VirsualBox+ok6410+u-boot-2010.03 一,下载u-boot-2010.03源码 ftp://ftp.denx.de/pub/u-boot 解压,我这里为了避免麻烦,更改了所有文件的权限 tar jxvf u-boot-2010.03.tar.bz2 sudo chmod -R 777 u-boot-2010.03/* 二,修改源码 为了方便修改,查找代码,你看到u-boot下包含了支持众多CPU和不同架构的代码,这里我根据Ok6410开发板的自身情况,将u-boot下代码进行精简: 1,进入u-boot-2010.03/board,把除samsu
[单片机]
Ubuntu下移植内核到OK6410开发板
环境:Win7+virsualBox+ubuntu12.04+ok6410开发板 一,下载源码:我这里下载的版本是--linux-3.12.7 http://www.kernel.org/ 二,解压内核: tar -xvf linux-3.12.7-tar.xz 三,更改权限(最好赋予全部权限) sudo chmod -R 777 linux-3.12.7/* 四,修改源码(针对基于smdk6410架构的ok6410开发板) 1,在arch/arm/mach-s3c64xx/目录下的mach-smdk6410.c 复制一份在当前文件下命名为mach-ok6410.c wu@wu-VirtualBox:/opt
[单片机]
Ubuntu下移植内核到<font color='red'>OK6410</font>开发板
ok6410如何从sdram中启动uboot 调试 这是一个猜想还没有验证
1在smdk6410.h中定义宏 //#define CONFIG_SKIP_LOWLEVEL_INIT 1 //#define CONFIG_SKIP_RELOCATE_UBOOT 1 2将编译的uboot.bin下载到text_base的地址 3准备好调试环境之后 指令 gp+地址运行sdram中的uboot
[单片机]
记录ok6410 jlink 命令行调试uboot
1启动ok6410 进入uboot命令行 2\启动JLinkGDBServer -device ARM11 3arm-none-eabi-gdb u-boot 初始化脚本 # Connect to the J-Link GDBServer target remote localhost:2331 # Set JTAG speed to 30 kHz monitor endian little monitor speed 30 # Reset the target monitor reset monitor sleep 10 # # CPU core initialization # # Set the processor to s
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved