输入子系统(二)-35
程序员文章站
2024-02-26 21:28:04
...
输入子系统(二)
使用输入子系统设计按键驱动
- 我们可以将开发板上的按键值设置为input.h文件里面的宏定义的任意一个,比如我们本
次实验将开发板_上的KEY按键值设置为KEY__0 -
在编写input设备驱动的时候我们需要先申请一个input dev结构体变量,使用
input allocate device 函数来申请一个input dev. - 此函数原型如下所示:
struct input dev *input_allocate_device(void)
- 函数参数和返回值含义如下:
- 参数:无。
- 返回值:申请到的 input dev.
-
如果要注销的input设备的话需要使用input_ free_ device函数来释放掉前面申请到的input_ dev,
-
input_ free_ _device函数原型如下:
void input_free_device(struct input dev *dev)
函数参数和返回值含义如下:
-
dev:要注册的input dev。
-
返回值: 0, input_ dev注册成功;负值,input_ dev注册失败。
- 同样的,注销input 驱动的时候也需要使用input unregister _device 函数来注销掉前面注册
input_ unregister _device函数原型如下:
void input_unregister_device(struct input dev *dev)
- 函数参数和返回值含义如下:
- dev:要注销的input dev。
- 返回值:无。
最终我们需要把事件上报上去,,上报事件我们使用的函数要针对具体的时间来 上报。比
如,按键我们使用input _report. _key 函数。同样的还有一- 些其他的事件上报函数,函数如下
图所示:
void input_report_rel(struct input dev *dev, unsigned int code, int value)
void input_report_abs(struct input dev *dev, unsigned int code, int value)
void input_report_ff_status(struct input dev *dev, unsigned int code, int value)
void input_report_switch(struct input dev *dev, unsigned int code, int value)
void input_mt_sync(struct input dev *dev)
当我们上报事件以后还需要使用input_ sync函数来告诉Linux内核input 子系统上
报结束,input. sync函数本质是上报一个同步事件,
此函数原型如下所示:
void input sync(struct input dev *dev)
- 函数参数和返回值含义如下:
- dev:需要上报同步事件的input dev
代码
- input_test.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>
#include <linux/time.h>
#include <linux/input.h>
int gpio_num;
int irq = 0;
struct device_node *test_device_node;
struct property *test_node_property;
struct input_dev *test_dev;
static void timer_function(unsigned long data);
DEFINE_TIMER(test_timer, timer_function, 0, 0);
static void timer_function(unsigned long data){
int value;
printk("timer_function \n");
// mod_timer(&test_timer, jiffies + 1*HZ);
value = !gpio_get_value(gpio_num);
input_report_key(test_dev,KEY_1,value);
input_sync(test_dev);
}
struct of_device_id of_match_table[] = {
{.compatible = "test_keys"},
{}
};
irq_handler_t test_key(int irq, void *args){
printk("test_key \n");
test_timer.expires = jiffies + msecs_to_jiffies(20);
add_timer(&test_timer);
return IRQ_HANDLED;
}
int beep_probe(struct platform_device *pdev){
int ret = 0;
printk("beep_probe 匹配成功了 \n");
test_device_node = of_find_node_by_path("/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, "touch-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 %d \n", irq);
ret = request_irq(irq, test_key, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "test_key", NULL);
if (ret < 0)
{
printk("request_irq is error \n");
return ret;
}
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");
goto error_input_register;
}
return 0;
error_input_register:
input_unregister_device(test_dev);
}
int beep_remove(struct platform_device *pdev){
printk("beep_remove \n");
return 0;
}
const struct platform_device_id beep_idtable = {
.name = "test_keys"
};
struct platform_driver beep_device =
{
.probe = beep_probe,
.remove = beep_remove,
.driver = {
.name = "123",
.owner = THIS_MODULE,
.of_match_table = of_match_table
},
.id_table = &beep_idtable
};
static int beep_driver_init(void){
printk(KERN_EMERG "hello world enter \n");
int ret = 0;
ret = platform_driver_register(&beep_device);
if (ret < 0)
{
printk("platform_driver_register 失败\n");
}
printk("platform_driver_register ok\n");
return 0;
}
static void beep_driver_exit(void){
printk(KERN_EMERG "hello world exit! \n");
del_timer(&test_timer);
free_irq(irq, NULL);
input_unregister_device(test_dev);
platform_driver_unregister(&beep_device);
}
module_init(beep_driver_init);
module_exit(beep_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("LIYU");
- app.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
int main(int argc, char * argv[]){
int fd;
int value;
fd = open("/dev/input/event3", O_RDWR);
struct input_event test_event;
if (fd <0)
{
perror("open error \n");
return fd;
}
while (1)
{
read(fd, &test_event, sizeof(test_event));
printf("type all is %#x \n", test_event.type);
if (test_event.type == EV_KEY)
{
printf("type KEY is %#x \n", test_event.type);
printf("type value is %#x \n", test_event.value);
printf("type code is %#x \n", test_event.code);
}
}
return 0;
}
推荐阅读
-
输入子系统(二)-35
-
《嵌入式-STM32开发指南》第二部分 基础篇 - 第8章 模拟输入输出-ADC(HAL库)
-
java常用类解析二:IO系统输入输出类 博客分类: java javainputstreambytearrayinputstreamoutputstreambytearrayoutputstream
-
Java I/O 深入学习( 二)之数组类输入输出流 博客分类: J2EE ByteArrayInputStreamByteArrayOutputStream
-
linux驱动input子系统学习二(框架)
-
第二章 stm32 cubemx GPIO输入输出实验以及proteus仿真
-
输入一个数组,判断该数组是不是二叉搜索树的后序遍历的结果。
-
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
-
停止启用了安全性的WAS Server而不手动输入密码之第二种选择 博客分类: Java SOAPWebsphereIBMPHPBBS
-
停止启用了安全性的WAS Server而不手动输入密码之第二种选择 博客分类: Java SOAPWebsphereIBMPHPBBS