栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux下输入子系统案例

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux下输入子系统案例

文章目录
  • 前言
  • 一、代码编写
    • 1.input_subsystem.c文件
    • 2.Makefile文件
    • 3.app.c文件
  • 二、运行结果
  • 总结

前言

本文的主要内容是Linux下输入子系统的案例介绍。


一、代码编写

本代码的例程本来是带有定时器和按键消抖代码的,但是运行的过程有错误,因此,在超时处理函数中处理的内容调在了中断服务函数,将定时器和按键消抖一应代码都删掉了,但不影响最终的运行结果。

1.input_subsystem.c文件
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include 
#include 

struct input_dev *test_dev;
//static void timer_function(unsigned long data);
struct device_node *test_device_node;
struct property *test_node_property;
int gpio_num;
int irq;

//DEFINE_TIMER(test_timer,timer_function,0,0); //静态定义结构体变量并且初始化function,expires,data成员



irq_handler_t test_key(int irq, void *args)  //中断服务函数
{
	printk("test_key trigger off!n"); 
	//test_timer.expires = jiffies + msecs_to_jiffies(20); //延时20ms
	//add_timer(&test_timer);  //向Linux内核注册定时器
	int value;
	value = !gpio_get_value(gpio_num);
	input_report_key(test_dev,KEY_1,value);
	input_sync(test_dev);
	return IRQ_HANDLED;
}
int dts_probe(struct platform_device *pdev)
{
	int ret = 0;
	printk("dts_probe matching ok!n");

	
	test_device_node = of_find_node_by_path("/test_key");  //在设备树节点中查找test_key这个节点
	if(test_device_node == NULL){
		printk("of_find_node_by_path is error!n");
		return -1;
	}

	
	gpio_num = of_get_named_gpio(test_device_node,"key-gpio",0);
	if(gpio_num < 0){
		printk("of_get_named_gpio is error!n");
		return -1;
	}

	
	gpio_direction_input(gpio_num); //输入
	
	
	//irq = gpio_to_irq(gpio_num); 
	irq = irq_of_parse_and_map(test_device_node,0); //与上面这句代码的作用相同
	printk("irq is %dn", irq);

	
	ret = request_irq(irq, test_key, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "test_key", NULL); 
	//IRQF_TRIGGER_RISING为上升沿触发,定义在/linux-4.1.15/include/linux/interrupt.h中
	if(ret < 0){
		printk("request_irq is error!n");
		return -1;
	}

	test_dev = input_allocate_device();
	test_dev->name = "test_key";
	_set_bit(EV_KEY,test_dev->evbit);
	_set_bit(KEY_1,test_dev->keybit);
	ret = input_register_device(test_dev);
	if(ret < 0){
		printk("input_register_device is error!n");
		return -1;
	}
	return 0;
}

int dts_remove(struct platform_device *pdev)
{
	printk("dts_remove!n");
	return 0;
}

const struct platform_device_id dts_idtable = {
	.name = "dts_test1"  //匹配优先级 第二
};

const struct of_device_id of_match_table_test[] = {
	{.compatible = "led_keys"},   //匹配优先级 第一
	{}
};

struct platform_driver dts_device = {
	.probe = dts_probe,
	.remove = dts_remove,
	.driver = {
		.owner = THIS_MODULE,
		.name = "dts_test2", //匹配优先级 第三
		.of_match_table = of_match_table_test
	},
	.id_table = &dts_idtable
};

static int dts_driver_init(void)
{
	int ret = 0;
	ret = platform_driver_register(&dts_device);
	if(ret < 0) {
		printk("platform_driver_register error!n");
		return ret;
	}
	printk("platform_driver_register ok!n");
	return 0;
}
static int dts_driver_exit(void)
{
	printk("dts_driver_exit!n");
	free_irq(irq,NULL);
	//del_timer(&test_timer);
	platform_driver_unregister(&dts_device);
	input_unregister_device(test_dev);
}
module_init(dts_driver_init);
module_exit(dts_driver_exit);
MODULE_LICENSE("GPL");
2.Makefile文件
obj-m += input_subsystem.o
KDIR:=/linux/linux-4.1.15
PWD?=$(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	make -C $(KDIR) M=$(PWD) clean
3.app.c文件
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    int fd;
    struct input_event test_event;
    fd = open("/dev/input/event2", O_RDWR); //这里的"/dev/input/event2"根据开发板上新生成的输入设备添加
    if(fd < 0){
        perror("open errorn"); 
        return fd;
    }
    while(1){
        read(fd, &test_event, sizeof(test_event));
        if(test_event.type == EV_KEY)
        {
            printf("type is %#x.n",test_event.type);
            printf("code is %#x.n",test_event.code);
            printf("value is %#x.n",test_event.value);
        }
    }
    return 0;
}

二、运行结果

将上面的代码写好之后编译,然后将驱动和经arm编辑器编译的app文件发送至开发板。
先使用如下命令查看开发板上的输入节点有哪些。

ls /dev/input

然后用如下命令查看输入设备的详细信息。

cat /proc/bus/input/devices

打印结果如下。

加载驱动,再使用上述命令查看有没有新的输入设备生成,打印结果如下。

很明显,有event2这个输入设备新生成。
接着使用如下命令测试该输入设备是否可用。

hexdump /dev/input/event2

注意这里的event2,要根据自己新生成的输入设备名添加。
然后按下按键,打印结果如下。

这里的类型EV_KEY和按键KEY_1都是定义在/linux-4.1.15/include/uapi/linux/input.h文件中的,截图如下。


在驱动已经加载的情况下,运行app程序,多次按下按键后的部分结果如下图。


总结

以上就是Linux下输入子系统案例的所有内容了。
本文参考视频:https://www.bilibili.com/video/BV1Vy4y1B7ta?p=43。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/613826.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号