2.3. 數據處理實現
執(zhí)行上述代碼后系統(tǒng)中就注冊了我們的input設備,接下來我們要做的是活得鍵盤的鍵值,zlg7290多可以支持64個按鍵,每個按鍵按下后都會產生一個中斷,我們寫驅動是可以使用輪詢不斷檢測是否有按鍵也可以觸發(fā)中斷來判斷是否有按鍵按下。本例使用中斷方式,當按鍵按下后會觸發(fā)終端,終端讀取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;
}
工作隊列處理函數:中斷返回后執(zhí)行,讀取設備的鍵值并提交給上層。
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;
}
執(zhí)行程序后終端會根據不同的按鍵打印出如下內容:
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