注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小白的博客

嵌入式爱好者

 
 
 

日志

 
 

按键驱动程序之异步通信机制  

2012-09-12 15:42:40|  分类: 韦东山视频第二轮 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
驱动程序:

#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>

#include <asm/uaccess.h>
#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <asm/poll.h>

static struct class *key_class;
static struct fasync_struct *key_async_queue;

static unsigned char key_val;

struct irq_desc {
unsigned long pin;
int num;
int key;
};
static struct irq_desc dev_id[4]=
{
{S3C2410_GPF(0) ,0  ,0},
{S3C2410_GPF(2) ,2  ,1},
{S3C2410_GPG(3) ,3  ,2},
{S3C2410_GPG(11),11 ,3}
};

static irqreturn_t key_handler(int irq, void *dev_id)
{
int val;
struct irq_desc *key_desc = (struct irq_desc *)dev_id;
val = s3c2410_gpio_getpin(key_desc->pin);
val=val>>key_desc->num;
if(val==0)
{
key_val=key_desc->key;
}
else if(val==1)
{
key_val=key_desc->key | 0x80;
}
kill_fasync(&key_async_queue, SIGIO, POLL_IN);//add
return 0;
}

static int key_open (struct inode *inode, struct file *file)
{
    s3c2410_gpio_cfgpin(S3C2410_GPF(0), S3C2410_GPIO_IRQ);
    s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_IRQ);
    s3c2410_gpio_cfgpin(S3C2410_GPG(3), S3C2410_GPIO_IRQ);
    s3c2410_gpio_cfgpin(S3C2410_GPG(11),S3C2410_GPIO_IRQ);

request_irq(IRQ_EINT0,  key_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"key1",&dev_id[0]);
request_irq(IRQ_EINT2,  key_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"key2",&dev_id[1]);
request_irq(IRQ_EINT11, key_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"key3",&dev_id[2]);
request_irq(IRQ_EINT19, key_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"key4",&dev_id[3]);

    return 0;
}

static int key_release(struct inode *inode, struct file *file)
{
free_irq(IRQ_EINT0 ,&dev_id[0]);
free_irq(IRQ_EINT2 ,&dev_id[1]);
free_irq(IRQ_EINT11,&dev_id[2]);
free_irq(IRQ_EINT19,&dev_id[3]);

return 0;
}

static ssize_t key_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
copy_to_user(buf,&key_val,1);
return 0;
}

static int key_fasync(int fd, struct file *file, int on)
{
    //主要是用于设置key_async_queue,在kill_fasync会用到它
return fasync_helper(fd, file, on, &key_async_queue);
}

static struct file_operations key_operation = {
    .owner   =  THIS_MODULE,
    .open    =  key_open,
    .read    =  key_read,
    .release =  key_release,
    .fasync   =  key_fasync,
};

static int major;
static int buttons_init(void)
{
    major=register_chrdev(0, "key", &key_operation);
    key_class=class_create(THIS_MODULE, "key_class");
    device_create(key_class, NULL, MKDEV(major , 0), NULL, "keys");

    return 0;
}

static void buttons_exit(void)
{
    unregister_chrdev(major , "key");
    device_destroy(key_class, MKDEV(major , 0));
    class_destroy(key_class);
}

module_init(buttons_init);
module_exit(buttons_exit);
MODULE_LICENSE("GPL");

用户程序:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <poll.h>
#include <signal.h>
#include <unistd.h>

int fd;
void signal_handle()
{
unsigned char val;
read(fd , &val ,1);
printf("key_val=0x%x\n",val);
}

int main(int argc , char **argv)
{
int Oflags;
    fd=open("/dev/keys" , O_RDWR);
    if(fd<0)
        {
            printf("can't open /dev/keys\n");
            return -1;
        }
signal(SIGIO, signal_handle);
         //设置将接收SIGIO和SIGURG信号的进程id,这里就是本进程
fcntl(fd, F_SETOWN, getpid());
        //取得fd的文件状态标志
Oflags = fcntl(fd, F_GETFL); 
        //为设备文件设置同步属性,即FASYNC,此时就会调用.fasync函数
fcntl(fd, F_SETFL, Oflags | FASYNC);
    while(1)
        {
        sleep(5000);
        }
    return 0;
}

总结一下,在用户程序里面我们设置了本进程为SIGIO信号的接收进程,同时把设备文件的状态属性设置为同步,此时就会调用.fasync函数,对key_async_queue进行设置;一旦发生中断,就会向用户进程发送SIGIO信号,用户进程接收到信号之后就会执行信号处理函数!
  评论这张
 
阅读(526)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017