按键驱动——查询方式实现

OK6410总共有6个按键,按键分别接在GPN0~GPN5,原理图上根本没有这么说,原理图上说的是KEYINT!~KEYINT6,很明显这里是接在中断引脚上的,直接查询S3C6410的中断引脚就可以知道这个6个按键的接法,一下是用查询方法实现的按键驱动:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/device.h>//新版内核

static struct class *key_drv_class;
static struct class_device	*key_class_dev;
volatile unsigned long  *gpncon=NULL;
volatile unsigned long  *gpndat=NULL;


static int key_drv_open(struct inode  * inode, struct file * file)
{
	*gpncon &=~((0x3<<0)|(0x3<<2)|(0x3<<4)|(0x3<<6));
	return 0;
}
static ssize_t key_drv_write(struct inode * file, const char __user *buf, size_t count, loff_t *ppos)
{

	return 0;
}
ssize_t key_drv_read (struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	//返回四个引脚的电平
	unsigned char key_val[4];
	int regval;

	if(size != sizeof(key_val))
		return -EINVAL;
	regval=*gpndat;
	key_val[0]  = (regval & (1<<0))?1:0;
	key_val[1]  = (regval & (1<<1))?1:0;
	key_val[2]  = (regval & (1<<2))?1:0;
	key_val[3]  = (regval & (1<<3))?1:0;
	copy_to_user(buf,key_val,sizeof(key_val));
	
	return sizeof(key_val);
}

static struct file_operations key_drv_openration ={
	.owner = THIS_MODULE,
	.open = key_drv_open,
	.write =key_drv_write,
	.read=key_drv_read,
};
int major;
static int key_drv_init(void)
{
	major=register_chrdev(0,"key_drv",&key_drv_openration);
	
	key_drv_class = class_create(THIS_MODULE, "key_drv");
		//自动创建设备节点
	/* 新版的内核不能用class_device_create 要用device_create*/
	key_class_dev = device_create(key_drv_class, NULL, MKDEV(major, 0), NULL, "key"); /* /dev/xyz */
		
	gpncon = (volatile unsigned long*)ioremap(0x7F008830,16);
	gpndat=gpncon+1;//指针的操作是按照指针指向的长度为单位?
						/*本例中使用的是unsigned long类型刚好是4个字节*/

	return 0;
}
static void key_drv_exit(void)
{
	unregister_chrdev(major,"key_drv");
	device_unregister(key_class_dev);
	class_destroy(key_drv_class);

	iounmap(gpncon);
	return 0;
}

module_init(key_drv_init);
module_exit(key_drv_exit);
MODULE_LICENSE("GPL");

一下是测试程序:

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

int main(int argc,char **argv)
{
	int fd;
	unsigned char key_val[4];
	int cnt;
	fd=open("/dev/key",O_RDWR);
	if(fd < 0)
		printf("can not open!!!\n");
	while(1)
		{
			read(fd,key_val,sizeof(key_val));
			if(!key_val[0]||!key_val[1]||!key_val[2]||!key_val[3])
				{
					printf("%04d key pressed :%d %d %d %d\n\n",cnt++,key_val[0],key_val[1],key_val[2],key_val[3]);
				}
		}
	return 0;
}

一下是测试运行结果:



1452 key pressed :1 0 1 1


1453 key pressed :1 0 1 1


1454 key pressed :1 0 1 1


1455 key pressed :1 0 1 1


1456 key pressed :1 0 1 1


1457 key pressed :1 0 1 1


1458 key pressed :1 0 1 1


1459 key pressed :1 0 1 1


1460 key pressed :1 0 1 1


1461 key pressed :1 0 1 1

让测试程序后台运行,查看CPU的运行状态:



Mem: 7968K used, 246548K free, 0K shrd, 0K buff, 2096K cached
CPU:  9.1% usr 90.8% sys  0.0% nic  0.0% idle  0.0% io  0.0% irq  0.0% sirq
Load average: 0.34 0.13 0.07 2/25 984
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
  983   969 root     R      792  0.3   0 99.6 ./main
  984   969 root     R     2268  0.8   0  0.2 top
  969     1 root     S     2268  0.8   0  0.0 -/bin/sh
    1     0 root     S     2264  0.8   0  0.0 init
    4     2 root     SW       0  0.0   0  0.0 [kworker/0:0]
    5     2 root     SW       0  0.0   0  0.0 [kworker/u:0]

可以看出按键 程序的CPU占用率很大,这种驱动方式很不好。

你可能感兴趣的:(struct,File,Module,user,测试,Class)