S3C2440驱动之按键驱动(一)
来源:互联网 发布:淘宝买家要发票怎么办 编辑:程序博客网 时间:2024/04/30 11:32
上一章写了一篇LED驱动,里面填充了file_operations结构体的.write .open .ioctl函数,现在为了继续填充这个结构体部分,填充下.read函数。所以想到了按键属于输入设备 需要用.read函数。
整个框架和上一篇的一样,只是加了一个.read函数,这里先采用查询法来实现。在下一篇时采用中断法,不多说,上代码。
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
/*#define definition*/
#define DEVICE_NAME "button_drv" //设备名称 和文件系统里设备节点名称区分开
//#define BUTTON_MAJOR 0 //主设备号
static unsigned long led_table[] =
{
S3C2410_GPF0,
S3C2410_GPF1,
S3C2410_GPF2,
S3C2410_GPF4,
};
static unsigned int led_cfg_table[] =
{
S3C2410_GPF0_INP,
S3C2410_GPF1_INP,
S3C2410_GPF2_INP,
S3C2410_GPF4_INP ,
};
//.open func 打开设备时 将四个按键置于输入状态
static int button_drv_open(struct inode *inode, struct file *filp)
{
int i;
for(i = 0; i < 4; i++)
{
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
}
printk("button_drv_open\n");
/*配置GPIF0 1 2 4 为输入*/
return 0;
}
//系统.read函数,read要做的就是返回数据到内核空间,这里是按键,那么肯定返回按键状态到用户空间
ssize_t button_read_drv(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
//int regval; //接收GPIO的数据
unsigned char key_vals[4]; //保存要传递给用户空间的4个按键口
if(size != sizeof(key_vals)) //size为用户空间返回的字长度
{
return -EINVAL;
}
key_vals[0] = s3c2410_gpio_getpin(S3C2410_GPF0) & (1 << 0) ? 1:0;
key_vals[1] = s3c2410_gpio_getpin(S3C2410_GPF1) & (1 << 1) ? 1:0;
key_vals[2] = s3c2410_gpio_getpin(S3C2410_GPF2) & (1 << 2) ? 1:0;
key_vals[3] = s3c2410_gpio_getpin(S3C2410_GPF4) & (1 << 4) ? 1:0;
copy_to_user(buf, key_vals, sizeof(key_vals)); //返回key_vals数组数据到用户空间
return (sizeof(key_vals));
}
//define the file_operations
static struct file_operations button_drv_fops = {
.owner = THIS_MODULE,
.open = button_drv_open,
.read = button_read_drv,
};
static struct class *button_drv_class; //定义一个类 方便在/dev目录下建立一个节点
int major; //自动分配主设备号
int button_drv_init(void)
{
//int ret;
//ret = register_chrdev(FIRST_MAJOR, DEVICE_NAME, &myfirst_drv_fops);
major = register_chrdev(0, DEVICE_NAME, &button_drv_fops);
//if(ret < 0)//
if(major < 0)
{
printk("button_drv can not register major number!\n");
return major;
}
/*注册一个类 使得mdev可以在/dev目录下自动建立设备节点 不需要手动mknod dev c 224 0这样的操作*/
button_drv_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(button_drv_class))
{
printk("error, fail to init button_drv_class");
return -1;
}
/*如果上面成功注册进mdev的话 下面自动在/dev目录下创建一个设备节点*/
device_create(button_drv_class, NULL, MKDEV(major, 0), NULL, "BUTTON_TEST"); //这个就是在/dev下创建的BUTTON_TEST 设备节点了 应用程序调用
printk("BUTTON_DRV initialized! \n");
return 0;
}
void button_drv_exit(void)
{
unregister_chrdev(major, DEVICE_NAME); //卸载驱动
device_destroy(button_drv_class, MKDEV(major, 0)); //删掉设备节点
class_destroy(button_drv_class); //注销类
printk("rm -rf BUTTON_DRV! \n");
}
module_init(button_drv_init);
module_exit(button_drv_exit);
MODULE_LICENSE("GPL"); //获得授权
/*以后的makefile文件都不用贴出来了,因为和上一篇的都一样 只是函数名改了下而已*/
/*用户测试程序*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
static int fd; //用于存放打开设备时返回的文件句柄
unsigned char key_vals[4];
int cnt = 0;
int main(int argc, char **argv)
{
fd = open("/dev/BUTTON_TEST", O_RDWR); //打开设备 并读写权限
if(fd < 0)
{
perror("open device failed");
exit(1);
}
while(1)
{
read(fd, key_vals, sizeof(key_vals)); //执行读函数,将内核数据交互到用户空间
if(!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3])
{
printf("%d key pressed %d %d %d %d \n", cnt++, key_vals[0] , key_vals[1], key_vals[2], key_vals[3]);
}
}
return 0;
}
我们将测试程序和驱动拷到文件系统 执行 发现每按下一个按键 相应的数据显示为0
但是查询法最大的弊端就是:这个应用程序将一直占用cpu资源 我们将程序运行于后台./button_test & 而用采用top命令查看 这个进程占用cpu资源90%以上 在top下按q退出监视状态,所以下一篇我们就开始着手基于中断法的按键驱动了
- S3C2440驱动之按键驱动(一)
- S3C2440按键驱动之中断法
- s3c2440按键驱动
- 05-S3C2440学习之内核(移植)linux3.4.2移植(4)支持LED驱动、按键驱动
- s3c2440串口驱动(一)
- s3c2440 按键驱动 -- 字符设备
- s3c2440按键驱动 -- 混杂设备
- Linux驱动开发之S3C2440按键点亮LED
- Linux驱动开发之S3C2440按键点亮LED
- Linux驱动开发之S3C2440按键点亮LED
- 07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-查询+中断+引入poll机制的按键驱动程序
- 按键驱动(一)-中断
- 写一个具体的按键驱动(WinCE5.0 S3C2440)
- S3C2440 Linux驱动移植——按键
- S3C2440 Linux驱动移植——按键
- linux驱动之按键驱动
- 07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-按键驱动程序之异步通知机制+原子操作+互斥信号量+阻塞与非阻塞+定时器去抖
- OSAL之按键驱动
- ajax心得1--ajax入门介绍
- ajax心得2--ajax主要对象、方法以及属性的介绍
- ajax心得3--编写ajax同用工具代码以及案例分析
- 地面网络传输层之TCP、UDP详解
- 用图片隐藏信息的技术实现
- S3C2440驱动之按键驱动(一)
- Android---把数据保存到数据库中(二)
- NtQueryInformationProcess用法
- 电话用语
- 更好的内存管理-jemalloc
- 如果有一天你没有了动力,可以看看这篇文章。
- 349. Out of debt, out of danger. 无债一身轻
- 动态控制表格列
- 题目1072: 括号匹配问题