Linux Driver 简单 按键驱动 - 1
来源:互联网 发布:复杂网络建模的研究生 编辑:程序博客网 时间:2024/05/21 04:39
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h> //file_operations结构
#include <linux/device.h> // 驱动模型相关device API和结构体
#include <linux/irq.h> //定义中断出发方式:电平触发、边沿触发
#include <asm/uaccess.h> //copy_to_user 和 copy_from_user
#include <linux/interrupt.h> //request_irq和free_irq
#include <plat/gpio-cfg.h> //s3c_gpio_cfgpin和s3c_gpio_getcfg
#include <plat/gpio-fns.h> //s3c2410_gpio_setpin、s3c2410_gpio_getpin
#include <mach/gpio-nrs.h> //定义gpio编号S3C2410_GPA(n)~S3C2410_GPJ(n)
static dev_t dev; //设备编号
static struct cdev *my_cdev = NULL;
static struct class *cdev_class = NULL;
static struct device *cdev_class_device = NULL;
static unsigned char key_val; //按键值
static volatile int condition = 0; //休眠条件,1是不休眠,0是休眠
static DECLARE_WAIT_QUEUE_HEAD(wq);//初始化休眠队列
struct key_desc //按键自描述结构体
{
int pin; //按键引脚值
char value; //按键返回值
};
static struct key_desc my_desc[4] = {
{ S3C2410_GPF(1), 0x01 },
{ S3C2410_GPF(4), 0x02 },
{ S3C2410_GPF(2), 0x03 },
{ S3C2410_GPF(0), 0x04 },
};
MODULE_LICENSE("GPL");
static irqreturn_t key_irq(int irq, void *dev_id) //按键中断处理函数
{
struct key_desc *tmp = (struct key_desc *)dev_id;
if(!s3c2410_gpio_getpin(tmp->pin))
{
key_val = tmp->value;//按下读取到低电平,返回0x01~0x04
}
else
{
key_val = 0xFF; //按键松开,读取到高电平,返回255
}
condition = 1; /* 有按键按下就唤醒app读取键值 */
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
static int key_open(struct inode *inode, struct file *file)
request_irq(IRQ_EINT4 , key_irq, IRQ_TYPE_EDGE_BOTH, "K2", &my_desc[1]);
request_irq(IRQ_EINT2 , key_irq, IRQ_TYPE_EDGE_BOTH, "K3", &my_desc[2]);
request_irq(IRQ_EINT0 , key_irq, IRQ_TYPE_EDGE_BOTH, "K4", &my_desc[3]);
return 0;
}
static ssize_t key_close(struct inode *inode, struct file *file)
free_irq(IRQ_EINT4, &my_desc[1]);
free_irq(IRQ_EINT2, &my_desc[2]);
free_irq(IRQ_EINT0, &my_desc[3]);
return 0;
}
static ssize_t key_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
if(count != 1)
{
return -EINVAL;
}
wait_event_interruptible(wq, condition); //等待按键按下
copy_to_user(buf, &key_val, 1); //获取按键的值
condition = 0; //重新等待
return 1;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = key_open,
.release= key_close,
.read = key_read,
};
static int key_drv_init(void)
{
int ret = 0;
ret = alloc_chrdev_region(&dev, 0, 4, "mykey");//注册设备编号
if(ret < 0)
{
printk("alloc_chrdev_region\n");
}
my_cdev = cdev_alloc();//分配字符设备结构体
cdev_init(my_cdev, &fops);
my_cdev->owner = THIS_MODULE;
cdev_add(my_cdev, dev, 4); //告知内核
cdev_class = class_create(THIS_MODULE, "mykey"); //创建设备类
cdev_class_device = device_create(cdev_class, NULL, dev, NULL, "keybutton");//创建设备对象,对应于/dev/keybutton
return 0;
}
static void key_drv_exit(void)
{
device_destroy(cdev_class, dev);
class_destroy(cdev_class);
cdev_del(my_cdev);
kzfree(my_cdev);
unregister_chrdev_region(dev, 4);
return ;
}
module_init(key_drv_init);
module_exit(key_drv_exit);
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/cdev.h> //cdev_init、cdev_alloc、cdev_add、cdev_del
#include <linux/fs.h> //file_operations结构
#include <linux/device.h> // 驱动模型相关device API和结构体
#include <linux/irq.h> //定义中断出发方式:电平触发、边沿触发
#include <asm/uaccess.h> //copy_to_user 和 copy_from_user
#include <linux/interrupt.h> //request_irq和free_irq
#include <plat/gpio-cfg.h> //s3c_gpio_cfgpin和s3c_gpio_getcfg
#include <plat/gpio-fns.h> //s3c2410_gpio_setpin、s3c2410_gpio_getpin
#include <mach/gpio-nrs.h> //定义gpio编号S3C2410_GPA(n)~S3C2410_GPJ(n)
#include <linux/wait.h> //休眠相关wait_event_interruptible(wq, condition)
DECLARE_WAIT_QUEUE_HEAD(name)、wake_up_interruptible(&wq)
#include <linux/sched.h> //signal_pendingstatic dev_t dev; //设备编号
static struct cdev *my_cdev = NULL;
static struct class *cdev_class = NULL;
static struct device *cdev_class_device = NULL;
static unsigned char key_val; //按键值
static volatile int condition = 0; //休眠条件,1是不休眠,0是休眠
static DECLARE_WAIT_QUEUE_HEAD(wq);//初始化休眠队列
struct key_desc //按键自描述结构体
{
int pin; //按键引脚值
char value; //按键返回值
};
static struct key_desc my_desc[4] = {
{ S3C2410_GPF(1), 0x01 },
{ S3C2410_GPF(4), 0x02 },
{ S3C2410_GPF(2), 0x03 },
{ S3C2410_GPF(0), 0x04 },
};
MODULE_LICENSE("GPL");
static irqreturn_t key_irq(int irq, void *dev_id) //按键中断处理函数
{
struct key_desc *tmp = (struct key_desc *)dev_id;
if(!s3c2410_gpio_getpin(tmp->pin))
{
key_val = tmp->value;//按下读取到低电平,返回0x01~0x04
}
else
{
key_val = 0xFF; //按键松开,读取到高电平,返回255
}
condition = 1; /* 有按键按下就唤醒app读取键值 */
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
static int key_open(struct inode *inode, struct file *file)
{
/* 申请中断,开启引脚的中断功能 */
request_irq(IRQ_EINT4 , key_irq, IRQ_TYPE_EDGE_BOTH, "K2", &my_desc[1]);
request_irq(IRQ_EINT2 , key_irq, IRQ_TYPE_EDGE_BOTH, "K3", &my_desc[2]);
request_irq(IRQ_EINT0 , key_irq, IRQ_TYPE_EDGE_BOTH, "K4", &my_desc[3]);
return 0;
}
static ssize_t key_close(struct inode *inode, struct file *file)
{
/* 释放中断资源,关中断 */
free_irq(IRQ_EINT4, &my_desc[1]);
free_irq(IRQ_EINT2, &my_desc[2]);
free_irq(IRQ_EINT0, &my_desc[3]);
return 0;
}
static ssize_t key_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
if(count != 1)
{
return -EINVAL;
}
wait_event_interruptible(wq, condition); //等待按键按下
copy_to_user(buf, &key_val, 1); //获取按键的值
condition = 0; //重新等待
return 1;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = key_open,
.release= key_close,
.read = key_read,
};
static int key_drv_init(void)
{
int ret = 0;
ret = alloc_chrdev_region(&dev, 0, 4, "mykey");//注册设备编号
if(ret < 0)
{
printk("alloc_chrdev_region\n");
}
my_cdev = cdev_alloc();//分配字符设备结构体
cdev_init(my_cdev, &fops);
my_cdev->owner = THIS_MODULE;
cdev_add(my_cdev, dev, 4); //告知内核
cdev_class = class_create(THIS_MODULE, "mykey"); //创建设备类
cdev_class_device = device_create(cdev_class, NULL, dev, NULL, "keybutton");//创建设备对象,对应于/dev/keybutton
return 0;
}
static void key_drv_exit(void)
{
device_destroy(cdev_class, dev);
class_destroy(cdev_class);
cdev_del(my_cdev);
kzfree(my_cdev);
unregister_chrdev_region(dev, 4);
return ;
}
module_init(key_drv_init);
module_exit(key_drv_exit);
- Linux Driver 简单 按键驱动 - 1
- linux 按键驱动简单实例
- Linux驱动---按键驱动
- linux device driver 3 简单的字符驱动
- linux按键驱动示例
- linux按键驱动示例
- linux按键驱动
- linux 按键驱动
- Linux系统按键驱动
- Linux按键驱动编写
- linux驱动之按键
- linux按键驱动
- linux中的按键驱动
- linux驱动:按键
- linux驱动之按键驱动
- linux driver 简单实例
- linux简单驱动1
- Linux驱动之Platform Driver
- http和https
- c++数据管理和驱动
- s3c6410 中断
- 第一篇文章,不知写什么。就写一些我最近在trswcm里遇到的问题吧。(没大用只是为了写而写)
- java native方法1
- Linux Driver 简单 按键驱动 - 1
- WordPress 设置评论数到达一定时关闭评论
- B-树
- 数据库优化
- Reporting Service 开发中的知识汇总
- C语言文件操作函数大全
- jquery+c# 分页列表模块
- CloudStack 4.0.2 vRouter导致重启后状态不正常
- 无需第三个变量实现两个数的交换