8.中断编程2——按键驱动之获取按键数据实验

本文介绍了如何在Linux环境下实现字符设备驱动,包括设置全局设备对象、申请设备号、创建设备节点、硬件初始化、中断申请。详细讲解了通过GPIO获取按键状态并在中断处理中传递给用户空间的方法。同时指出,当前实现可能导致频繁调用read函数,造成CPU占用率高,预告将在后续章节解决此问题,实现阻塞IO模型。
摘要由CSDN通过智能技术生成

实现字符设备驱动框架

1.设定一个全局的设备对象
(全局)
在这里插入图片描述

(init函数中)
在这里插入图片描述

2.申请主设备号
在这里插入图片描述

3.创建设备节点文件
在这里插入图片描述

4.硬件的初始化——地址映射或者中断申请
5.实现file_operations
6.释放资源(exit函数中)

驱动中获取硬件数据并传递给用户的方法

a,硬件如何获取数据
key: 按下和抬起: 1/0
读取key对应的gpio的状态,可以判断按下还是抬起

	读取key对应gpio的寄存器--数据寄存器
	
	//读取数据寄存器
	int value = readl(key_dev->reg_base + 4) & (1<<2);
//设计一个全局设备对象--描述按键信息
struct key_desc{
   
	unsigned int dev_major;
	struct class *cls;
	struct device *dev;
	int irqno;
	void *reg_base;
};

//init函数中
// a,硬件如何获取数据--gpx1
	key_dev->reg_base  = ioremap(GPXCON_REG, 8);


b,驱动如何传递给用户
在中断处理中填充数据:
key_dev->event.code = KEY_ENTER;
key_dev->event.value = 0;

	在xxx_read中奖数据传递给用户
		ret = copy_to_user(buf, &key_dev->event,  count);
// 设计一个描述按键的数据的对象
struct key_event{
   
	int code; // 表示按键的类型:  home, esc, Q,W,E,R,T, ENTER
	int value; // 表示按下还是抬起 1 / 0
};

//设计一个全局设备对象--描述按键信息
struct key_desc{
   
	unsigned int dev_major;
	struct class *cls;
	struct device *dev;
	int irqno;
	void *reg_base;
	struct key_event event;
};

irqreturn_t key_irq_handler(int irqno, void *devid)
{
   
	printk("-------%s-------------\n", __FUNCTION__);

	//读取数据寄存器
	int value = readl(key_dev->reg_base + 4) & (1<<2);

	if(value){
    // 抬起
		printk("key3 up\n");
		key_dev->event.code = KEY_ENTER;
		key_dev->event.value = 0;

	}else{
   //按下
		printk("key3 pressed\n");
		key_dev->event.code = KEY_ENTER;
		key_dev->event.value = 1;
	}
	
	return IRQ_HANDLED;
}

ssize_t key_drv_read(struct file *filp, char __user *buf, size_t count, loff_t *fpos)
{
   
	//printk("-------%s-------------\n", __FUNCTION__);
	int ret;

	ret = copy_to_user(buf, &key_dev->event,  count);
	if(ret > 0)
	{
   
		printk("copy_to_user error\n");
		return -EFAULT;
	}

	// 传递给用户数据之后,将数据清除掉
	memset(&key_dev->event, 0,  sizeof(key_dev->event));
	
	return count;
	
}

//释放资源
static void __exit key_drv_exit(void)
{
   
	iounmap(key_dev->reg_base);
	free_irq(key_dev->irqno, NULL);
	device_destroy(key_dev->cls
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值