【北京迅为】《iTOP-3588开发板系统编程手册》-第18章 输入设备应用编程

RK3588是一款低功耗、高性能的处理器,适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用,RK3588支持8K视频编解码,内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP,内置NPU,支持INT4/INT8/INT16/FP16混合运算能力,支持安卓12和、Debian11、Build root、Ubuntu20和22版本登系统。了解更多信息可点击迅为官网   

【粉丝群】824412014

【实验平台】:迅为RK3588开发板

【内容来源】《iTOP-3588开发板系统编程手册》

【全套资料及网盘获取方式】联系淘宝客服加入售后技术支持群内下载

【视频介绍】:【强者之芯】 新一代AIOT高端应用芯片 iTOP -3588人工智能工业AI主板


第18章 输入设备应用编程

18.1输入设备介绍

输入设备是指可以接收用户输入的设备,例如键盘、鼠标、触摸屏等。这些设备可以通过Linux内核提供的输入子系统与应用程序进行交互。输入子系统是一个内核模块,它负责管理输入设备和应用程序之间的通信。

在Linux中,每个输入设备都被表示为一个字符设备文件。这些文件通常位于/dev/input目录下,如下图所示:

当输入设备产生一个事件时,它会将事件数据写入该设备的输入队列中。应用程序可以通过读取该设备的输入队列来获得有关事件的信息。事件包括按键按下、松开、鼠标移动、触摸屏触摸等。

18.2 input子系统

input子系统是一种负责管理输入设备的子系统,它提供了一组用于读取和控制输入设备的API和机制,包括设备注册、事件读取和处理等。在Linux中,所有的输入设备都被视为一个事件源,例如键盘、鼠标、触摸屏、游戏手柄等。这些输入设备会产生各种各样的事件,例如按键按下、松开、鼠标移动、滚轮滚动等。输入子系统可以将这些事件收集起来,交给用户空间的应用程序处理,以实现各种不同的功能。

input子系统的核心是input驱动程序,它是Linux内核中的一个模块,主要负责与硬件进行通信,从硬件读取输入事件,并将其转换为标准的输入事件格式,并向内核的输入子系统发送事件。每个输入设备都需要有一个相应的input驱动程序进行管理和处理。例如,对于USB鼠标,需要加载相应的hid驱动程序,对于触摸屏,需要加载相应的触摸屏驱动程序。

除了驱动程序,input子系统还包括了一个输入事件处理程序,负责将输入事件传递给应用程序进行处理。输入事件处理程序会将所有的输入事件存储在一个FIFO队列中,并向用户空间的应用程序发送相应的信号。在用户空间,可以通过读取/dev/input/eventX文件,其中X是输入设备的编号,来获取输入事件。如下图所示:

18.3读取输入设备

如果要读取某个输入设备的数据对应的流程如下所示:

步骤

描述

1

应用程序打开/dev/input/eventX设备文件,X为对应的输入设备编号。

2

应用程序使用read函数从设备文件中读取数据。如果设备上没有数据可读,则read函数会一直阻塞等待,直到数据可用。

3

读取的数据为一个input_event结构体,其包含事件类型、事件码和事件值三个字段,用于描述输入设备发生的事件信息。事件类型指示事件的分类,例如按键事件、鼠标事件、触摸屏事件等;事件码指示事件的具体类型,例如按下键盘上的某个键、移动鼠标等;事件值表示事件的取值,例如按键按下/释放、鼠标移动的距离、触摸屏触点的坐标等。

4

应用程序根据读取到的事件数据进行处理,例如根据事件类型和事件码判断是哪个键被按下、鼠标移动的距离等,并进行相应的操作。

5

在使用完输入设备后,使用close系统调用关闭输入设备文件。

每一步骤实现的具体代码,在之后的实验小节中会进行演示。

在第二步中,通过read函数进行读取输入设备数据的读取,每一次 read 操作获取的都是一个 struct input_event 结构体类型数据,struct input_event 是 Linux 内核中用于描述输入事件的结构体类型。它定义在 <linux/input.h> 头文件中,用于在内核和用户空间之间传递输入事件的信息。在用户空间中,应用程序通过读取输入设备文件获得 struct input_event 数据,并解析其中的事件类型、事件码和事件值等信息,以进行相应的处理。结构体struct input_event 定义如下:

struct input_event {
	struct timeval time;
	__u16 type;// 类型
	__u16 code;// 具体事件
	__s32 value;// 对应的取值
};

下面对struct input_event结构体的三个字段及其相应的宏进行详细的讲解:

type:type 用于描述发生了哪一种类型的事件(对事件的分类),Linux 系统所支持的输入事件类型如下所示:

#define EV_SYN          0x00	//同步类事件,用于同步事件
#define EV_KEY          0x01	//按键类事件
#define EV_REL          0x02	//相对位移类事件(譬如鼠标)
#define EV_ABS          0x03	//绝对位移类事件(譬如触摸屏)
#define EV_MSC          0x04	//其它杂类事件
#define EV_SW           0x05
#define EV_LED          0x11
#define EV_SND          0x12
#define EV_REP          0x14
#define EV_FF           0x15
#define EV_PWR          0x16
#define EV_FF_STATUS        0x17
#define EV_MAX          0x1f
#define EV_CNT          (EV_MAX+1)

以上这些宏定义同样在<linux/input.h>头文件中,所以在应用程序中需要包含该头文件;一种输入设备 通常可以产生多种不同类型的事件,譬如点击鼠标按键(左键、右键,或鼠标上的其它按键)时会上报按键类事件,移动鼠标时则会上报相对位移类事件。

code:code 表示该类事件中的哪一个具体事件,以上列举的每一种事件类型中都包含了一系列具体事件,譬如一个键盘上通常有很多按键,而 code变量则告知应用程序是哪一个按键发生了输入事件。每一种事件类型都包含多种不同的事件,以按键类事件为例,对应的具体事件如下所示: 

#define KEY_RESERVED        0
#define KEY_ESC         1	//ESC 键
#define KEY_1           2	//数字 1 键
#define KEY_2           3	//数字 2 键
#define KEY_3           4	//数字 3 键
#define KEY_4           5	//数字 4 键
#define KEY_5           6	//数字 5 键
#define KEY_6           7	//数字 6 键
#define KEY_7           8	//数字 7 键
#define KEY_8           9	//数字 8 键
#define KEY_9           10	//数字 9 键
#define KEY_0           11	//数字 0 键
#define KEY_MINUS       12	//减号键
#define KEY_EQUAL       13	//加号键
#define KEY_BACKSPACE       14	//回退键
    ................................

对于其他输入事件的code值,可以查看input-event-codes.h 头文件(该头文件被<linux/input.h>所包含)。

value:内核每次上报事件都会向应用层发送一个数据 value,对 value 值的解释随着 code 的变化而变化。譬如对于按键事件来说,如果 value 等于 1,则表示按键按下;value 等于 0 表示按键松开,如果 value 等于 2则表示按键长按。而在绝对位移事件中(type=3),如果 code=0(触摸点 X 坐标 ABS_X),那么 value 值就等于触摸点的 X 轴坐标值;如果 code=1(触摸点 Y 坐标 ABS_Y),此时value 值便等于触摸点的 Y 轴坐标值。

18.4按键应用编程

18.4.1编写应用程序 

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\68”目录下,如下图所示:

实验要求:

打印开发板按键按下后的type、code、value值,并打印按键的状态(按下、弹起和长按)及对应的功能。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建 demo68_input.c文件,如下图所示:

vim  demo68_input.c

然后向该文件中添加以下内容: 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <linux/input.h>

int main(int argc, char *argv[]) 
{
    int fd, ret;
    struct input_event in_ev = {0}; //初始化 input_event 结构体

    fd = open(argv[1], O_RDONLY); //打开输入设备文件
    if (fd < 0) 
	{ //文件打开失败
        printf("文件打开失败\n");
        return -1;
    }

    while (1) 
	{
        ret = read(fd, &in_ev, sizeof(struct input_event)); //读取数据
        if (ret < 0) 
		{ //读取失败
            printf("读取数据失败\n");
        }

        // 打印读取到的事件信息
        printf("type:%d code:%d value:%d\n", in_ev.type, in_ev.code, in_ev.value);

        if (EV_KEY == in_ev.type) 
		{ //检测到按键事件
            switch (in_ev.value) 
			{
                case 0: //松开按键
                    printf("code<%d>: 松开", in_ev.code);
                    break;
                case 1: //按下按键
                    printf("code<%d>: 按下", in_ev.code);
                    break;
                case 2: //长按按键
                    printf("code<%d>: 长按", in_ev.code);
                    break;
            }

            // 根据按键码打印按键功能
            switch (in_ev.code) 
			{
                case KEY_MENU:
                    printf(": HOME键\n");
                    break;
				case KEY_BACK:
                    printf(": BACK键\n");
                    break;
                case KEY_VOLUMEUP:
                    printf(": 音量增加键\n");
                    break;
                case KEY_VOLUMEDOWN:
                    printf(": 音量减小键\n");
                    break;
                // 其他按键码对应的功能在这里添加
                default:
                    printf(": 未知键\n");
                    break;
            }
        }
    }

    close(fd); //关闭输入设备文件
    return 0;
}

第23行对输入设备的信息进行读取,第30行打印读取到的type、code和value值,第34行-45行为一个switch循环,根据获取到的value进行按键状态的判断,第48行-第66行为一个switch循环,根据获取到的code值对按下的按键的功能进行判断。

保存退出之后,使用以下命令设置交叉编译器环境,并对demo68_input.c进行交叉编译,编译完成如下图所示:

export PATH=/usr/local/arm64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH

aarch64-none-linux-gnu-gcc -o demo68_input demo68_input.c

    

最后将交叉编译生成的 demo68_input文件拷贝到/home/nfs共享目录下即可。

18.2.2开发板测试

Buildroot系统启动之后,首先使用以下命令进行nfs共享目录的挂载(其中192.168.1.7为作者ubuntu的ip地址,需要根据自身ubuntu的ip来设置),如下图所示:

mount -t nfs -o nfsvers=3,nolock 192.168.1.7:/home/nfs /mnt

nfs共享目录挂载到了开发板的/mnt目录下,进入到/mnt目录下,如下图所示:

然后使用以下命令对接入设备信息进行查看,找到按键输入设备如下图所示:

cat /proc/bus/input/devices

从上述信息可以看到按键输入事件为event4,然后在/mnt目录下使用以下命令进行测试,然后分别按下开发板的BACK、VOL+、BOL-和HOME按键如下图所示:

./demo68_input /dev/input/event4

 可以看到按键的按下抬起状态,按键的功能值,都被打印了出来,至此,关于板载按键输入设备的测试就完成了。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值