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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值