6410之写查询方式的按键驱动

查询的方式获取按键值驱动的步骤大致如下:
一、框架
1.file_operations的填充
2.入口函数注册register_chrdev
3.修饰入口函数/出口函数
4.自动创建设备节点

二、硬件操作


一、框架:

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
#include <linux/notifier.h>
#include <linux/wait.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/kthread.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/uaccess.h>

struct class *buttons_class;
struct device *buttons_dev;

static int buttons_drv_open(struct inode *inode, struct file *file)
{
	printk("buttons_drv_open \n");
	return 0;
}

static ssize_t buttons_drv_read( struct file *file,
			  char __user *buffer,
			  size_t len,
			  loff_t *offset )
{
	printk("buttons_drv_read \n");
}


static struct file_operations buttons_fops = {
    .owner   =   THIS_MODULE,    
    .open    =   buttons_drv_open,
    .read    =   buttons_drv_read,
};


int major;
static int __init buttons_drv_init(void)
{
	major = register_chrdev(0,"buttons",&buttons_fops);
	buttons_class = class_create(THIS_MODULE,"buttons");
	buttons_dev = device_create(buttons_class,NULL,MKDEV(major,0),NULL,"buttons");
	return 0;
}

static void __exit buttons_drv_exit(void)
{
	device_destroy(buttons_class,MKDEV(major,0));
	class_destroy(buttons_class);
	unregister_chrdev(major,"buttons");
}

module_init(buttons_drv_init);
module_exit(buttons_drv_exit);

MODULE_LICENSE("GPL"); 


二、硬件操作:

查看SCH按键引脚对应的gpio如下:
KEYINT1----》GPN0
KEYINT2----》GPN1
KEYINT3----》GPN2
KEYINT4----》GPN3
KEYINT5----》GPN4
KEYINT6----》GPN5



物理地址:GPNCON 0x7F008830 
对物理地址进行映射:ioremap


open中配置为输入引脚:GPNCON &= ~0xfff 

没有按下时为高电平,按下后是低电平
read中读取引脚的状态: state = (GPNDAT | 1 << x) ? 1 : 0;

驱动代码如下:

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
#include <linux/notifier.h>
#include <linux/wait.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/kthread.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/uaccess.h>

struct class *buttons_class;
struct device *buttons_dev;

volatile unsigned long *gpncon = NULL;
volatile unsigned long *gpndat = NULL;

static int buttons_drv_open(struct inode *inode, struct file *file)
{
	printk("buttons_drv_open \n");
	//配置按键gpio引脚为输入引脚
	*gpncon &= ~0xfff;
	return 0;
}

static ssize_t buttons_drv_read( struct file *file,
			  char __user *buffer,
			  size_t len,
			  loff_t *offset )
{
//	printk("buttons_drv_read \n");
	char reg_val[6];
	
	if(len != sizeof(reg_val)){
		return -EINVAL;
	}
	
	int i;
	for(i = 0 ; i < 6 ; i++){
		reg_val[i] = (*gpndat & 1 << i ) ? 1 : 0;
	}

	copy_to_user(buffer,reg_val,sizeof(reg_val));

	return sizeof(reg_val);
}


static struct file_operations buttons_fops = {
    .owner   =   THIS_MODULE,    
    .open    =   buttons_drv_open,
    .read    =   buttons_drv_read,
};


int major;
static int __init buttons_drv_init(void)
{
	major = register_chrdev(0,"buttons",&buttons_fops);
	buttons_class = class_create(THIS_MODULE,"buttons");
	buttons_dev = device_create(buttons_class,NULL,MKDEV(major,0),NULL,"buttons");

	gpncon = (volatile unsigned long *)ioremap(0x7F008830 ,16);
	gpndat = gpncon + 1;
	
	return 0;
}

static void __exit buttons_drv_exit(void)
{
	device_destroy(buttons_class,MKDEV(major,0));
	class_destroy(buttons_class);
	unregister_chrdev(major,"buttons");
	iounmap(gpncon);
}

module_init(buttons_drv_init);
module_exit(buttons_drv_exit);

MODULE_LICENSE("GPL"); 

测试程序:

#include <stdio.h>
#include <fcntl.h>


int main(int argc ,char **argv)
{
	int fd ;
	int val;
	int cnt = 0;
	char key_val[6];
	char *filename = "/dev/buttons";
	
	fd = open(filename,O_RDWR);
	if(fd < 0){
		printf("Can not open devices\n");
		return -1;
	}

	while(1){
		read(fd,key_val,sizeof(key_val));
		if(!key_val[0] || !key_val[1] || !key_val[2] || !key_val[3] || !key_val[4] || !key_val[5]){
			printf(" %d  cnts Keypad are pressed %d %d %d %d %d %d \n",cnt++,!key_val[0],!key_val[1],!key_val[2],!key_val[3],!key_val[4],!key_val[5]);
		}
	}
	
	return 0;
}
这个是使用while循环的查询方式进行读取按键的值, 在驱动中的读操作也一直处于一直读的状态,这样会导致系统占用资源很多。

如下所示:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值