栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

查询方式的按键驱动

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

查询方式的按键驱动

查询方式的按键驱动
  • 前言
  • 一、思维导图
  • 二、代码
    • 1.按键驱动代码
    • 2.测试驱动
    • 3.Makefile
  • 总结


前言 基于JZ2440开发板
一、思维导图

二、代码 1.按键驱动代码

代码如下(key_drv.c):

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

static struct class *keydrv_class;
static struct class_device	*keydrv_class_dev;

volatile unsigned long *gpfcon;
volatile unsigned long *gpfdat;

volatile unsigned long *gpgcon;
volatile unsigned long *gpgdat;
static int key_drv_open(struct inode* inode, struct file *file){
	
	*gpfcon &= ~( ( 3 << 0 ) | ( 3 << 4 ) );		//bit1~bit0 置00  bit5~bit4 置00
	
	
	*gpgcon &= ~( ( 3 << 6 ) | ( 3 << 22 ) );		//bit7~6 和 bit23~22 置00
	
	return 0;
}

static ssize_t key_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) {

	
	unsigned char key_vals[4];
	int regval;

	if(size != sizeof( key_vals ) ) {
		return -EINVAL;
	}


	
	regval = *gpfdat;
	key_vals[0] = (regval & (1<<0)) ? 1 : 0;
	key_vals[1] = (regval & (1<<2)) ? 1 : 0;
	

	
	regval = *gpgdat;
	key_vals[2] = (regval & (1<<3)) ? 1 : 0;
	key_vals[3] = (regval & (1<<11)) ? 1 : 0;

	//unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
	copy_to_user( buf, key_vals, sizeof( key_vals ) );
	return sizeof( key_vals );


}


static struct file_operations key_drv_fops = {
	.owner = THIS_MODULE,
	.open  = key_drv_open,
	.read = key_drv_read,
};

int major;
static int key_drv_init(void) {
	major = register_chrdev(0, "key_drv", &key_drv_fops);	//注册驱动程序,告诉内核
	
	keydrv_class = class_create(THIS_MODULE, "key_drv");

	keydrv_class_dev = class_device_create(keydrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); 

	gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);		//物理地址映射成虚拟地址
	gpfdat = gpfcon + 1;

	gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);		//物理地址映射成虚拟地址
	gpgdat = gpgcon + 1;
	
	return 0;
}

static void key_drv_exit(void) {
	unregister_chrdev(major, "key_drv");	//卸载驱动
	
	class_device_unregister(keydrv_class_dev);	
	
	class_destroy(keydrv_class);

	iounmap(gpfcon);	//解除映射关系
	iounmap(gpgcon);	//解除映射关系
	
}

module_init(key_drv_init);
module_exit(key_drv_exit);

MODULE_LICENSE("GPL");		//让linux识别定义的类






2.测试驱动

代码如下(keydrvtest.c):

#include 
#include 
#include 
#include 


int main(int argc, char **argv)
{
	int fd, cnt = 0;
	unsigned char key_vals[4];
	
	fd = open("/dev/buttons", O_RDWR);
	if (fd < 0) {
		printf("can't open!n");
	}

	while(1) {
		read(fd, key_vals, sizeof( key_vals ) );
		if( !key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3] ) {
			printf("%04d key pressed: %d %d %d %dn", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]);
		}
	}
	return 0;
}

3.Makefile

代码如下:

KERN_DIR = /home/book/work/system/linux-2.6.22.6

all:
	make -C $(KERN_DIR) M=`pwd` modules 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-m	+= key_drv.o



KERN_DIR是内核的路径


总结 大致熟悉如何写驱动代码的流程。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/297272.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号