Linux输入子系统(input subsystem)之按键输入和LE(2)

/* [cgw]: 设置支持的事件类型 */
    set_bit(EV_KEY, input_subsys_dev->evbit);
    //set_bit(EV_REP, input_subsys_dev->evbit);
   
    set_bit(EV_LED, input_subsys_dev->evbit);
    //set_bit(EV_SND, input_subsys_dev->evbit);

/* [cgw]: 设置支持的事件码 */
    set_bit(KEY_L, input_subsys_dev->keybit);
    set_bit(KEY_S, input_subsys_dev->keybit);
    set_bit(KEY_ENTER, input_subsys_dev->keybit);
    set_bit(KEY_LEFTSHIFT, input_subsys_dev->keybit);

set_bit(LED_MUTE, input_subsys_dev->ledbit);
    //set_bit(SND_BELL, input_subsys_dev->sndbit);

/* [cgw]: 分配输入设备的open方法,用户操作open(/dev/xxx, ...)时调用 */
    input_subsys_dev->open = input_subsys_open;
    /* [cgw]: 分配输入设备的event方法,用户在应用程序write()时 */
    input_subsys_dev->event = led_event;

/* [cgw]: 注册输入设备 */
    input_register_device(input_subsys_dev);

/* [cgw]: 初始化定时器,用于按键消抖 */
    init_timer(&buttons_timer);
    buttons_timer.function = buttons_timer_function;
    add_timer(&buttons_timer);

printk("input subsys init!\n");
   
    return 0;
}

static void input_subsys_exit(void)
{
    int i;

/* [cgw]: 释放按键IO中断 */
    for (i = 0; i < 4; i++)
    {
        free_irq(pins_desc[i].irq, &pins_desc[i]);
    }

/* [cgw]: 删除定时器 */
    del_timer(&buttons_timer);
    /* [cgw]: 注销输入设备 */
    input_unregister_device(input_subsys_dev);
    /* [cgw]: 释放输入设备内存空间 */
    input_free_device(input_subsys_dev);   
}

module_init(input_subsys_init);

module_exit(input_subsys_exit);

MODULE_LICENSE("GPL");

input_subsys_test.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#include <linux/input.h>

int fd;

void my_signal_fun(int signum)
{
    struct input_event buttons_event, leds_event;

/* [cgw]: 异步通知产生时返回的数据 */
    read(fd, &buttons_event, sizeof(struct input_event));

/* [cgw]: 打印事件类型,事件码,事件值 */
    printf("type: 0x%x code: 0x%x value: 0x%x\n",
          buttons_event.type,
          buttons_event.code, 
          buttons_event.value);

/* [cgw]: 返回的是KEY_L或KEY_S值 */
    if (buttons_event.code == KEY_L || buttons_event.code == KEY_S) {
        /* [cgw]: 按键弹起 */
        if (buttons_event.value == 0) {

/* [cgw]: 构造一个EV_LED事件 */
           
            //leds_event.type = EV_SND;
            leds_event.type = EV_LED;
            //leds_event.code = SND_BELL;
            leds_event.code = LED_MUTE;

/* [cgw]: KEY_L和KEY_S控制LED的亮灭 */
            if (buttons_event.code == KEY_L) {
                leds_event.value = 0xAA;
            } else if (buttons_event.code == KEY_S) {
                leds_event.value = 0xEE;   
            }

/* [cgw]: 发送LED控制事件 */
            write(fd, &leds_event, sizeof(struct input_event));
           
            printf("led write!\n");
        }
    }
}

int main(int argc, char **argv)
{
    int Oflags;

/* [cgw]: 设置需要处理的信号SIGIO,即输入文件会请求一个SIGIO
    * 信号,当有新数据到来这个信号会发给filp->f_owner进程
    */
    signal(SIGIO, my_signal_fun);
   
    fd = open("/dev/event1", O_RDWR | O_NONBLOCK);
   
    //printf("fd = 0x%x\n", fd);
   
    if (fd < 0)
    {
        printf("can't open!\n");
    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/41ad193549dc2e8766bf450b628a3b4c.html