Linux的input輸入子系統:裝置驅動之按鍵驅動
環境:kernel-2.6.30.4,arm-linux-gcc-4.3.3,目標板TQ2440
一、裝置層驅動程式:
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <mach/regs-gpio.h>/*暫存器設定*/
#include <mach/hardware.h> /*hardware*/
struct pin_desc { //引腳描述,將一個引腳和一箇中斷號、名字、按鍵值進行繫結
int irq;
char *name;
unsigned int pin;
unsigned int key_val;
};
struct pin_desc pins_desc[4] = {//繫結四個引腳
{IRQ_EINT1, "K1", S3C2410_GPF1, KEY_L},
{IRQ_EINT4, "K2", S3C2410_GPF4, KEY_S},
{IRQ_EINT2, "K3", S3C2410_GPF2, KEY_ENTER},
{IRQ_EINT0, "K4", S3C2410_GPF0, KEY_LEFTSHIFT},
};
static struct input_dev *buttons_dev;
static struct pin_desc *irq_pd;
static struct timer_list buttons_timer;
//中斷執行函式,當設定的4個外部中斷被觸發後將執行該函式
static irqreturn_t buttons_irq(int irq, void *dev_id)
{
irq_pd = (struct pin_desc *)dev_id;//獲得相應中斷的相應引數
mod_timer(&buttons_timer, jiffies+HZ/100);//開啟定時器,時間到將執行定時器處理函式,時間為10ms
return IRQ_RETVAL(IRQ_HANDLED);
}
//定時器處理函式
static void buttons_timer_function(unsigned long data)
{
struct pin_desc * pindesc = irq_pd;//發生中斷的那個引腳的資訊
unsigned int pinval;
if (!pindesc)
return;
pinval = s3c2410_gpio_getpin(pindesc->pin);//獲得發生中斷的那個引腳的值
if (pinval)
{
input_event(buttons_dev, EV_KEY, pindesc->key_val, 0);//按下
input_sync(buttons_dev);
}
else
{
input_event(buttons_dev, EV_KEY, pindesc->key_val, 1);//鬆開
input_sync(buttons_dev);
}
}
static int buttons_open(struct input_dev *dev)
{ return 0;}
static void buttons_close(struct input_dev *dev) {}
static int buttons_init(void)
{
int i;
// 1. 分配一個input_dev結構體
buttons_dev = input_allocate_device();
//2. 設定
//2.1 能產生哪類事件
set_bit(EV_KEY, buttons_dev->evbit);//能產生按鍵類事件
set_bit(EV_REP, buttons_dev->evbit);//內產生重複類事件
//2.2 能產生這類操作裡的哪些事件
set_bit(KEY_L, buttons_dev->keybit);
set_bit(KEY_S, buttons_dev->keybit);
set_bit(KEY_ENTER, buttons_dev->keybit);
set_bit(KEY_LEFTSHIFT, buttons_dev->keybit);
buttons_dev->name = "buttons_input";
buttons_dev->dev.init_name = "buttons_input";
buttons_dev->name = "buttons_input";
buttons_dev->dev.init_name = "buttons_input";
buttons_dev->open = buttons_open;
buttons_dev->close = buttons_close;
//3. 註冊input_dev:將該裝置加入到input_dev_list列表中,找尋和它匹配的input_handler
input_register_device(buttons_dev);
init_timer(&buttons_timer);//初始化一個定時器
buttons_timer.function = buttons_timer_function;//設定定時器的處理函式
add_timer(&buttons_timer);//將該定時器器加入到核心
//註冊中斷
//pins_desc引數就是當相應的中斷髮生,該值將成為對應中斷函式的引數
for (i = 0; i < 4; i++)
{
request_irq(pins_desc[i].irq, buttons_irq, IRQ_TYPE_EDGE_BOTH, pins_desc[i].name, &pins_desc[i]);
}
printk("按鍵驅動輸入子系統初始化成功!\n");
return 0;
}
static void buttons_exit(void)
{
int i;
for (i = 0;i < 4;i++)//中斷登出
free_irq(pins_desc[i].irq, &pins_desc[i]);
del_timer(&buttons_timer);//刪除定時器
input_unregister_device(buttons_dev);//登出驅動
input_free_device(buttons_dev);//釋放記憶體
printk("按鍵驅動輸入子系統解除安裝成功!\n");
}
module_init(buttons_init);
module_exit(buttons_exit);
MODULE_LICENSE("GPL");
Makefile:
ERN_DIR = /lib/modules/2.6.30.4-EmbedSky/build
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += buttons.o
二、測試程式
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>
#include <linux/input.h>
int main(void)
{
int fd;
int key_value,i=0,count;
struct input_event ev_key;
fd = open("/dev/event1", 666);
if (fd < 0)
{
printf("can't open device buttons!\n");
exit(1);
}
for (;;)
{
count = read(fd,&ev_key,sizeof(struct input_event));
for(i=0; i<(int)count/sizeof(struct input_event); i++)
if(EV_KEY==ev_key.type)
printf("type:%d,code:%d,value:%d\n", ev_key.type,ev_key.code,ev_key.value);
if(EV_SYN==ev_key.type)
printf("syn event\n\n");
}
close(fd);
return 0;
}
我們也可以在開發板上:
#cat /dev/tty //事件將上傳到shell程式的控制終端
原始碼下載:http://download.csdn.net/detail/hbuxiaofei/7903951
相關文章
- Linux裝置驅動之字元裝置驅動Linux字元
- 驅動Driver-input子系統
- 深入淺出:Linux裝置驅動之字元裝置驅動Linux字元
- 乾坤合一:Linux裝置驅動之塊裝置驅動Linux
- 蛻變成蝶:Linux裝置驅動之字元裝置驅動Linux字元
- 蛻變成蝶~Linux裝置驅動之字元裝置驅動Linux字元
- 基於匯流排裝置驅動模型的按鍵讀取驅動程式模型
- 乾坤合一:Linux裝置驅動之USB主機和裝置驅動Linux
- Linux驅動之GPIO子系統和pinctrl子系統Linux
- 無作業系統時的裝置驅動和有作業系統時的裝置驅動作業系統
- 字元裝置驅動 —— 字元裝置驅動框架字元框架
- 【linux】驅動-7-平臺裝置驅動Linux
- linux裝置驅動編寫入門Linux
- Linux塊裝置驅動Linux
- 【linux】驅動-6-匯流排-裝置-驅動Linux
- Linux驅動之I2C匯流排裝置以及驅動Linux
- Linux裝置驅動程式學習----1.裝置驅動程式簡介Linux
- Linux裝置驅動探究第1天----spi驅動(1)Linux
- linux驅動之獲取裝置樹資訊Linux
- Linux裝置驅動程式 (轉)Linux
- 【linux】驅動-10-pinctrl子系統Linux
- 【linux】驅動-11-gpio子系統Linux
- Linux驅動實踐:如何編寫【 GPIO 】裝置的驅動程式?Linux
- linux驅動之LED驅動Linux
- 按鍵中斷驅動程式
- 作業系統——裝置驅動和檔案系統作業系統
- 驅動Driver-MISC雜項驅動裝置
- Linux驅動之裝置樹的基礎知識Linux
- LINUX下的裝置驅動程式 (轉)Linux
- 蛻變成蝶:Linux裝置驅動之DMALinux
- Linux下的硬體驅動——USB裝置(上)(驅動配置部分)(轉)Linux
- Linux驅動開發筆記(四):裝置驅動介紹、熟悉雜項裝置驅動和ubuntu開發雜項裝置DemoLinux筆記Ubuntu
- linux 裝置驅動基本概念Linux
- liunx驅動之字元裝置的註冊字元
- 開發Linux系統裝置驅動程式並不難(轉)Linux
- LED字元裝置驅動字元
- 《Linux裝置驅動開發詳解(第2版)》——第1章Linux裝置驅動概述及開發環境構建1.1裝置驅動的作用Linux開發環境
- 如何編寫一個簡單的Linux驅動(三)——完善裝置驅動Linux