文档章节

手把手教你使用pcDuino的外部中断(3)

simpower
 simpower
发布于 2014/11/01 13:10
字数 874
阅读 92
收藏 0

按键中断—poll机制

我们尝试让按键具有这样一种功能,如果一定的时间内没有人去按按键,内核就提醒一下,然后我们应用程序得到提醒之后打印time out。
驱动程序     key.c (3.77 KB, 下载次数: 0, 售价: 5 金钱) 
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/io.h>
#include <linux/platform_device.h>
//#include <mach/gpio.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <linux/syscalls.h>
#include <linux/reboot.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/completion.h>
#include <asm/uaccess.h>
#include <mach/irqs.h>
#include <mach/system.h>
#include <mach/hardware.h>
#include <plat/sys_config.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/poll.h>
#define GPIO_IRQ  28
#define GPIO_TEST_BASE 0xf1c20800
#define PH_CFG2                     (GPIO_TEST_BASE + 0x104)
#define PIO_INT_CFG2    (GPIO_TEST_BASE+ 0x208)
#define PIO_INT_CTL                (GPIO_TEST_BASE+ 0x210)
#define PH17_SELECT (6 << 4)
#define PH18_SELECT (6 << 8)
#define PH19_SELECT (6 << 12)
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
/* 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 */
static volatile int ev_press = 0;
static struct class *keydrv_class;
static unsigned int status;
static irqreturn_t key_irq(int irq, void *dev_id)
{
         status =readl(GPIO_TEST_BASE + 0x214 ) ;
         
         ev_press = 1;                  /* 表示中断发生了 */
             wake_up_interruptible(&button_waitq);   /* 唤醒休眠的进程 */
         writel(status,GPIO_TEST_BASE + 0x214);      
         return IRQ_HANDLED;
}
static int key_drv_open(struct inode *inode, struct file *file)
{
         int error;
         int irq_ctl;
         /*1,设置中断位*/
         irq_ctl =readl(PH_CFG2);
         writel(PH19_SELECT|PH17_SELECT|PH18_SELECT| irq_ctl ,PH_CFG2);
         /*2,设置中断方式*/
         irq_ctl =readl(PIO_INT_CFG2);
         writel((0x4<<(1*4))|(0x4 <<(2*4))|(0x4 <<(3*4)) | irq_ctl,PIO_INT_CFG2);
         /*3,开中断*/        
         irq_ctl =readl(PIO_INT_CTL);
         writel((0xf <<16)|irq_ctl,PIO_INT_CTL);
         error =request_irq(GPIO_IRQ, key_irq,0, "button", 1);
    if (error) {
        printk("failed toregister keypad interrupt\n");
    }
         
         printk(KERN_ALERT"keyopeni\n");
         
         return 0;
}
static unsigned key_drv_poll(struct file *file, poll_table *wait)
{
         unsigned int mask = 0;
         poll_wait(file,&button_waitq, wait); // 不会立即休眠
         if (ev_press)
                   mask |=POLLIN | POLLRDNORM;
         return mask;
}
ssize_t key_drv_read(struct file *file, char __user *buf, size_tsize, loff_t *ppos)
{
         /* 如果没有按键动作, 休眠 */
         wait_event_interruptible(button_waitq,ev_press);
         /* 如果有按键动作, 返回键值 */
         copy_to_user(buf,&status, sizeof(unsigned int));
         ev_press = 0;
         
         return 1;
}
static ssize_t key_drv_write(struct file *file, const char __user*buf, size_t count, loff_t * ppos)
{
         printk(KERN_ALERT"keywrite\n");
         return 0;
}
int key_drv_close(struct inode *inode, struct file *file)
{
         free_irq(GPIO_IRQ,1);
         return 0;
}
static struct file_operations key_drv_fops = {
    .owner  =  THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =  key_drv_open,     
    .write  =          key_drv_write,         
    .read   =       key_drv_read,
         .release =  key_drv_close,
         .poll    = key_drv_poll,
};
int major;
static int key_drv_init(void)
{        
         major =register_chrdev(0, "key_drv", &key_drv_fops);
         keydrv_class =class_create(THIS_MODULE,"key_drv");
         device_create(keydrv_class,NULL,MKDEV(major,0),NULL,"key");
         printk(KERN_ALERT"register\n");
         return 0;
}
static void key_drv_exit(void)
{
         unregister_chrdev(major,"key_drv"); // 卸载
         device_destroy(keydrv_class,MKDEV(major,0));
         class_destroy(keydrv_class);
         printk(KERN_ALERT"unregister\n");
}
module_init(key_drv_init);
module_exit(key_drv_exit);
MODULE_LICENSE("GPL");


测试程序     test_key.c (706 Bytes, 下载次数: 0, 售价: 5 金钱) 
#include<stdio.h>
#include<stdlib.h>
#include <poll.h>
         int kbit = 0;
void PrintBinary(unsigned int c)
{
    if (c>>1)PrintBinary(c>>1);
    printf("%d:%d",kbit, c&1);
         kbit++;
}
int main()
{
         int fd;
         unsigned int val = 1;
         int ret;
         struct pollfd fds[1];
         fd =open("/dev/key",0666);
         if(fd < 0)
         {
                   printf("cannotopen\n");
                   return 0;
         }
         fds[0].fd     = fd;
         fds[0].events =POLLIN;
         while(1)
         {
                   kbit = 0;
                   ret =poll(fds, 1, 5000);
                   if (ret ==0)
                   {
                            printf("timeout\n");
                   }
                   else
                   {
                            read(fd,&val,sizeof(unsignedint));
                            PrintBinary(val);
                            if(val&(1<<17))printf("Back\n");
                            if(val&(1<<18))printf("home\n");
                            if(val&(1<<19))printf("menu\n");
                   }
         }
         close(fd);
         return 0;
}


编译:
gcc test_key.c
测试:
root @ubuntu :/home/ubuntu/driver/key_02# ./a.out
[10049.740000] key openi
0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 18:0 home
0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 18:0 home
time out
time out
time out
time out
0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 Back
0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 Back


本文转载自:http://www.pcduino.org/forum.php?mod=viewthread&tid=439

simpower
粉丝 28
博文 669
码字总数 50544
作品 0
海淀
程序员
私信 提问
在pcDuino上使用Arduino风格的中断处理

外部中断是pcDuino处理突发外部突发事件的重要机制。pcDuino的 Arduino风格编程机制提供了两个外部中断引脚 (管脚 2 和 3)。 在这里,我们来看看如何使用这些中断机制。 什么事中断? 中断...

酸酸苹果汁
2013/12/27
568
0
手把手教你在pcduino上实现uspip--USB网络重定向

我们经常碰到一种情况,我们需要往pcduino上拷贝东西,新手都用U盘,高手一般都用samba这样的高级玩意儿。拷贝一次倒也无所谓,关键是有些情况下,我们需要多次测试,多次拷贝。pcduino的USB...

pc朵拉
2013/08/16
2.6K
0
手把手教你在pcduino上实现uspip--USB网络重定向

我们经常碰到一种情况,我们需要往pcduino上拷贝东西,新手都用U盘,高手一般都用samba这样的高级玩意儿。拷贝一次倒也无所谓,关键是有些情况下,我们需要多次测试,多次拷贝。pcduino的USB...

pc朵拉
2013/08/27
532
0
关于pcDuino调试串口的一些知识(二)

什么事pcDuino的调试串口? 上图中蓝色圈中的引脚即为pcDuino的串行数据通信引脚和其对应的功能。TX为pcDuino的数据发送引脚,即pcDuino向外发送数据;RX为pcDuino的数据接收引脚,即pcDuino...

酸酸苹果汁
2014/03/01
1K
0
pcduino使用时需注意的硬件问题之ADC

我们一直说pcduino兼容arduino平台,但有写地方还是有区别的,这里我就给大家介绍下pcduino跟arduino的模数转换(ADC)的区别,以及在平常应用时有哪些要注意的。 1:精度差别:arduino平台一般...

雨后的彩虹桥
2014/03/12
545
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
23分钟前
4
0
Spring Boot 如何部署到 Linux 中的服务

打包完成后的 Spring Boot 程序如何部署到 Linux 上的服务? 你可以参考官方的有关部署 Spring Boot 为 Linux 服务的文档。 文档链接如下: https://docs.ossez.com/spring-boot-docs/docs/r...

honeymoose
26分钟前
4
0
Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
6
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
4
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部