天天看點

Linux輸入子系統(6):裝置驅動層之LED驅動

input輸入子系統不僅能夠處理輸入事件,也可以處理輸出事件,處理輸入事件最終會導緻input_handler的event函數被調用,處理輸出事件最終會導緻input_dev的event的函數被調用。下面以通過輸入子系統來控制led為例來說明。 注:核心:kernel-2.6.30.4 編譯器:arm-linux-gcc 4.3.3 目标闆:TQ2440 一、裝置驅動層程式 #include <linux/module.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/sysctl.h> #include <linux/input.h> #include <linux/gpio_keys.h> #include <mach/regs-gpio.h> #include <asm/gpio.h> #include <linux/kernel.h> #include <asm/uaccess.h> #include <mach/hardware.h> #include <linux/cdev.h>

static struct input_dev *input_led_dev;//輸入裝置 //這是重點,應用程式發過來的event事件最後會由該函數來進行處理 int input_led_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) {   printk("tq2440 input_led_event!\n");   if(type != EV_LED)       return -1;   //根據發過來的code和value值設定led的點滅   switch(code)   {    case LED_NUML              :{s3c2410_gpio_setpin(S3C2410_GPB5,value?0:1); break;}    case LED_CAPSL:{s3c2410_gpio_setpin(S3C2410_GPB6,value?0:1); break;}    case LED_SCROLLL:{s3c2410_gpio_setpin(S3C2410_GPB7,value?0:1); break;}    case LED_COMPOSE:{s3c2410_gpio_setpin(S3C2410_GPB8,value?0:1); break;}    } }

static int input_led_init(void) { //1. 配置設定一個input_dev結構體  input_led_dev = input_allocate_device();; //2. 設定  // 2.1 能産生哪類事件  set_bit(EV_LED, input_led_dev->evbit); //2.2 能産生這類操作裡的哪些事件 set_bit(LED_NUML, input_led_dev->ledbit); set_bit(LED_CAPSL, input_led_dev->ledbit); set_bit(LED_SCROLLL, input_led_dev->ledbit); set_bit(LED_COMPOSE, input_led_dev->ledbit); //3. 注冊  input_led_dev->event=input_led_event;//指定input_dev的event項 input_register_device(input_led_dev); printk("input_led_initsucceed!\n"); return 0; }

static void input_led_exit(void) { input_unregister_device(input_led_dev); input_free_device(input_led_dev); printk("input_led_exit succeed!\n"); }

module_init(input_led_init); module_exit(input_led_exit); MODULE_LICENSE("GPL"); 二、測試程式 #include<sys/types.h> #include<unistd.h> #include<fcntl.h> #include<linux/rtc.h> #include<linux/ioctl.h> #include<stdio.h> #include<stdlib.h> #include<linux/input.h> #include<signal.h>

int main(int argc,char *argv[]) {  int fd = -1;  if ((fd = open("/dev/event1", O_RDWR)) < 0)  //打開的event裝置,根據實際情況調整  {   printf("evdev open error!\n");   return -1;  }  if(argc!=3)  {   printf("the right Usage:input_led_test <num> <1:0>\n");   return -1 ;  }  struct input_event event[4];  event[0].type=EV_LED;  event[0].code=LED_NUML;    event[1].type=EV_LED;  event[1].code=LED_CAPSL;    event[2].type=EV_LED;  event[2].code=LED_SCROLLL;    event[3].type=EV_LED;  event[3].code=LED_COMPOSE;

 switch(*(argv[1]+0)-'0') //根據程式輸入的資料,給裝置驅動層發event  {    case 1:     {     event[0].value=*(argv[2]+0)-'0';     write(fd,&event[0],sizeof(struct input_event));     break;    }    case 2:     {     event[1].value=*(argv[2]+0)-'0';     write(fd,&event[1],sizeof(struct input_event));     break;    }    case 3:     {     event[2].value=*(argv[2]+0)-'0';     write(fd,&event[2],sizeof(struct input_event));     break;    }    case 4:     {     event[3].value=*(argv[2]+0)-'0';     write(fd,&event[3],sizeof(struct input_event));     break;    }  }  close(fd);  return 0; } 在開發闆測試 #insmod input_led.ko #./input_led_test   1 1(打開第一個led燈) #./input_led_test   1 0(關閉第一個led燈) #./input_led_test   2 1(打開第二個led燈) #./input_led_test   2 0(關閉第二個led燈) 程式源代碼連接配接: http://pan.baidu.com/share/link?shareid=395783&uk=101680913

繼續閱讀