Linux下编写zlg7290驱动(3)-键盘驱动编写

2023-12-23 06:35:41

2.3.?数据处理实现

执行上述代码后系统中就注册了我们的input设备,接下来我们要做的是活得键盘的键值,zlg7290多可以支持64个按键,每个按键按下后都会产生一个中断,我们写驱动是可以使用轮询不断检测是否有按键也可以触发中断来判断是否有按键按下。

本例使用中断方式,当按键按下后会触发终端,终端读取zlg7290相应寄存器,读出键值,然后将键值提交给上层。这写这个中断处理函数是需要注意,zlg7290是使用i2c总线通信的,但是linux内核提供的i2c数据交互函数i2c_transfer是一个可能引起睡眠的操作,所以不能出现在终端处理函数中,但是我们又需要通过这个函数从设备上读出我们的键值,所以我们在这里需要使用linux内核为我们提供的下半部机制工作队列。

中断处理函数:启动工作队列

irqreturn_t?zlg7290_interrupt(int?irq,?void?*devid)

{

printk("irq?=?%d\n",?irq);

schedule_work(&zlg7290->work);

return?IRQ_HANDLED;

}

工作队列处理函数:中断返回后执行,读取设备的键值并提交给上层。

static?void?zlg7290_work(struct?work_struct?*work)

{

struct?zlg7290?*ctr_zlg7290?=?container_of(work,?struct?zlg7290,?work);

unsigned?char?val?=?0;

size_t?len;

unsigned?char?status?=?0;

zlg7290_hw_read(ctr_zlg7290,?1,?&len,?&status);

if(status?&?0x1)?{

val?=?1;

zlg7290_hw_read(ctr_zlg7290,?1,?&len,?&val);

if?(val?==?0)?{

val?=?3;

zlg7290_hw_read(ctr_zlg7290,?1,?&len,?&val);

if?(val?==?0?||?val?==?0xFF)

goto?out;

}

if?(val?>?56)?{

switch?(val)?{

case?0xFE:?val?=?57;?break;

case?0xFD:?val?=?58;?break;

case?0xFB:?val?=?59;?break;

case?0xF7:?val?=?60;?break;

case?0xEF:?val?=?61;?break;

case?0xDF:?val?=?62;?break;

case?0xBF:?val?=?63;?break;

case?0x7F:?val?=?64;?break;

}

}

input_report_key(ctr_zlg7290->key,?key_value[val],?1);

input_report_key(ctr_zlg7290->key,?key_value[val],?0);

input_sync(ctr_zlg7290->key);

}

out:

return;

}

input_report_key,提交键值到上层,input_sync提交同步事件。类似的函数还有如下:

input_report_rel(struct?input_dev?*dev,?unsigned?int?code,?int?value)

input_report_abs(struct?input_dev?*dev,?unsigned?int?code,?int?value);

input_report_ff_status(struct?input_dev?*dev,?unsigned?int?code,?int?value);

input_report_switch(struct?input_dev?*dev,?unsigned?int?code,?int?value);

到此这个键盘的驱动就完成了。

2.3.?测试

测试程序如下:

#include

#include

#include

#include

#include

#include

int?main(int?argc,?const?char?*argv[])

{

struct?input_event?ev;

int?fd?=?open("/dev/input/event1",?O_RDWR);

if?(fd?<?0)?{

perror("open");

exit(1);

}

while(1)?{

read(fd,?&ev,?sizeof(ev));

switch(ev.type)

{

case?EV_KEY:

printf("user:key_val?=?%d?%d\n",?ev.code,?ev.value);

break;

default:

break;

}

}

return?0;

}

执行程序后终端会根据不同的按键打印出如下内容:

user:key_val?=?1?1

user:key_val?=?1?0

user:key_val?=?2?1

user:key_val?=?2?0

user:key_val?=?3?1

user:key_val?=?3?0

……

user:key_val?=?64?1

user:key_val?=?64?0

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,

差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。(点击找小助理领取)

扫码进群领资料icon-default.png?t=N7T8https://s.pdb2.com/pages/20230519/16QijNiGb32IFIn.html

文章来源:https://blog.csdn.net/D_ovis/article/details/135163433
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。