瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。
【公众号】迅为电子
【粉丝群】824412014(加群获取驱动文档+例程)
【视频观看】嵌入式学习之Linux驱动(第十三篇 输入子系统_全新升级)_基于RK3568
【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板
第145 章 输入子系统上报数据格式分析
在之前的章节中,我们已经了解到可以通过应用程序获取上报的信息。此外,还可以使用命令“hexdump /dev/input/event4”来查看上报的信息。实际上,使用hexdump命令查看到的数据也是input_event数据包,如下图所示。通过使用hexdump命令,我们可以快速查看上报的信息,而无需编写应用程序,从而提高效率。
接下来我们再来看一下input_event数据包中的成员,如下图所示:
在input_event数据包中,有四个成员变量:time,type,code,value。这些成员变量的值在使用hexdump命令获取到的数据中是以字节的形式存储的每个字节都以十六进制的形式表示。为了将hexdump输出的数据与input_event数据包中的成员值对应起来,你需要了解数据包的字节顺序(即字节序)和每个成员的字节大小。
一般情况下,input_event数据包的字节顺序是小端字节序(Little Endian)。这意味着较低的字节位于较高的内存地址处。对于每个成员变量,可以根据其字节大小来确定在hexdump输出中对应的字节范围。
在/usr/include/x86_64-linux-gnu/bits/types.h 文件中有如下定义:
由上图可得出以下结论
time.tv_sec和time.tv_usec的类型是long int,占8个字节
__u16 type的类型是unsigned short int,占2个字节
__u16 code的类型是unsigned short int,占2个字节
__s32 value的类型是unsigned int,占4个字节
下面是一个示例来说明如何与hexdump输出的数据对应。
假设hexdump输出的数据(以16进制表示)如下:
root@topeet:~$ hexdump /dev/input/event2
0000000 0f09 65d3 0000 0000 36fb 0001 0000 0000
0000010 0003 0039 0000 0000 0f09 65d3 0000 0000
0000020 36fb 0001 0000 0000 0003 0035 00f5 0000
0000030 0f09 65d3 0000 0000 36fb 0001 0000 0000
0000040 0003 0036 02b2 0000 0f09 65d3 0000 0000
0000050 36fb 0001 0000 0000 0003 0030 0021 0000
一个input_event数据包所占字节的大小为8+8+2+2+4 =24个字节。如下图所示为一个input_event数据包。
对应的成员值如下:
tv_sec: 0f09 65d3 0000 0000
tv_usec: 36fb 0001 0000 0000
type: 0003
code:0039
value: 0000 0000
好,现在我们对上报数据格式已经分析完毕。那么不知道大家有没有一个疑问,为什么要使用_u16等,而不是直接使用unsigned short int呢?
这是因为不同的机器类型,比如不同的硬件架构或者操作系统,可能在数据类型的大小个字节顺序上存在差异。
使用__u16是一种特殊的数据类型,它是Linux内核中定义的无符号16位整数类型,这个数据类型在不同平台上都保证占用2个字节,并且具有确定的字节顺序(大端或小端),这样就可以在不同机器上保持一致。相比之下,unsigned short int并没有提供对字节大小或字节顺序的特定保证,因此在不同的机器类型上,它的大小和字节顺序可能会有所变化,这可能导致在跨平台环境中出现数据不一致的问题。