Home>Article>Operation and Maintenance> what is linux device node
Linux device node is a bridge between applications and device drivers; the device node is created in "/dev", which is the hub connecting the kernel and the user layer. It is equivalent to the inode of the hard disk and records The location and information of the hardware device. Device nodes allow users to communicate with the kernel through hardware, read and write devices, and perform other operations.
#The operating environment of this tutorial: linux5.9.8 system, Dell G3 computer.
What is a device node
The communication bridge between people is language. Similarly, applications and device drivers also need a bridge to communicate. This bridge is the device node.
For Linux systems, all IO resources are files, including files, directories, hard disks, devices, etc. Well, the keyboard is an input device in the computer system, and the operating system also abstracts it from files. If you want to obtain the data input by the user from the keyboard, you only need to read the device node provided by the keyboard.
In the Linux system, the keyboard is used as an input device, and its corresponding device node is located under "/dev/input". There are many files starting with event in this folder. These are the device nodes of all input devices. How to determine which device node is the keyboard? Connect the keyboard to the Raspberry Pi, open the terminal, execute "sudo cat /dev/input/event0", tap the keyboard, if there is no output, change to the next node until you find a node with output, then this node is the keyboard The corresponding device node.
The device node is created under /dev and is the hub connecting the kernel and the user layer. It means that the device is connected to which ID of the corresponding interface. It is equivalent to the inode of a hard disk and records the location and information of hardware devices
In Linux, all devices are stored in the /dev directory in the form of files, all through files. To access,The device node is the abstraction of the device by the Linux kernel, and a device node is a file. Applications access the device through a standardized set of calls that are independent of any specific driver. The driver is responsible for mapping these standard calls to actual hardware-specific operations.
The role of device nodes
Device nodes enable users to communicate with the kernel through hardware, read and write devices, and perform other operations
In Linux Devices exist like ordinary files, and accessing a device is like accessing a file.
The major device number represents a type of device, and the minor device number represents different individuals of the same type of device. Speaking of which Maybe you don’t know the existence form of device nodes
The existence form of device nodes
In addition, there is another concept in Linux, which is inode and block, which is the hard disk side. blocks and nodes. The inode in the hard disk is equivalent to a file or folder. It records the location of the file under this file. The location of the file is aligned with the block size. For example, some systems are 4K in size, and the inode The size is limited, so there is a saying that a single file cannot exceed 4G. In my personal understanding, the node in the Linux driver can be regarded as something similar to the inode of the hard disk, which can record the location of the hardware device and other information, and can be used when the user needs to access it. Access the device by referring to the information recorded in the device node
How to obtain data from the device node
The reason why the operating system abstracts IO into files is that the maximum The advantage is that this file can be accessed through a unified interface to communicate with different devices. These unified interfaces are a set of system calls provided by the operating system for file operations: open function, read function, write function, etc. For example, if you need to obtain data from a device, you only need to call the read function to read the device node corresponding to the device. Of course, before reading, you must first call the open function to open it. Now let’s take getting keyboard input as an example.
1. Open the device node
Before reading the data of the device node, you must first call the open function to open the device node. For specific usage of the open function, please refer to the link. A brief description is as follows:
Function declaration:
int open(const char *pathname, int flags);
Header file to be included:
#include
Parameters:
* First parameter (const char * pathname): Indicates the file path to be opened
* The second parameter (int flags): Indicates the way to open the file, for example, "O_RDONLY" - open for reading only; "O_WRONLY" - open for writing only ; "O_RDWR" - read, write open, etc.
Return value:
If the opening is successful, the file descriptor of the file is returned for use by functions such as read and write. Otherwise, -1 is returned.
So, to open the keyboard's device file (assuming it is "/dev/input/even10"), you need the following code:
int keys_fd; keys_fd = open("/dev/input/even10", O_RDONLY); if(keys_fd <= 0) { printf("open /dev/input/event10 device error!\n"); return -1; }
2, read the data of the device node
Reading device nodes requires the use of the read function. For specific usage methods, please refer to the link. A brief introduction is as follows:
Function declaration:
ssize_t read(int fd, void *buf, size_t count);
需要包含的头文件:
#include
参数:
* 第一个参数(int fd):要打开文件的文件描述符,来源一般是上述open函数的返回值。
* 第二个参数(void *buf):读取到的数据存放的起始位置指针
* 第三个参数(size_t count):要读取的数据字节数
返回值:
* 如果读取成功,则返回实际读取到的字节数
* 如果读取失败,则返回-1
* 如果返回值小于第三个参数count,则表示已经读取到文件结尾,返回值表示实际读取的字节数。
在读取键盘的例子中,我们循环读取键盘设备的文件节点,并将设备保存到一个char buf[24]的数组中去。具体代码如下:
char buf[24]; while(1) { if(read(keys_fd, buf, 24) == 24) { // 成功的从设备节点中获取到了24个字节 ... } }
根据read函数用法,当要读取24个字节,且read函数的返回值是24时,表示成功的从设备节点中获取到了24个字节。
3、分析从设备节点获取的数据
为什么这里要从键盘的设备驱动获取24个字节呢?这是因为正常情况下,从键盘设备节点获取的数据实际上是一个struct input_event结构。其定义为:
struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; };
显然,上述结构体的大小为24。
这里需要理解的是:设备节点是设备驱动程序提供的,且设备节点的数据是设备驱动写入的,而且写入时,是以上述结构的规则写入的,这是双方通过b8aef83627d8109d104c626ed7bbfbbd约定好的,那么应用程序去设备节点中读取数据之后,也需要按照上述结构去解析数据。那这个结构具体是什么意思呢?
* struct timeval time:其大小为16个字节,具体意义暂时不考虑。
* __u16 type:其大小为2个字节,表示input设备的类型,比如:EV_KEY表示上报的是键盘类型的数据,EV_REL表示相对路径,鼠标就属于这种类型,还是其他等等。
* __u16 code:其大小为2个字节,表示事件的代码。比如,如果type为EV_KEY,那么该代码code为设备键盘代码。code值实际上是应用程序和驱动程序约定好的一些固定的值,它可取的值位于include/uapi/linux/input-event-codes.h中。举例来讲,根据Linux源码下的include/uapi/linux/input-event-codes.h文件的第91行#define KEY_Q 16,如果键盘上按下或松开了Q键,那么键盘的驱动程序上报的code值应该是16;反之,如果应用程序获取到的值是19,那么,表示用户按下或松开了键盘上的Q键。
* __s32 value:其大小为4个字节,事件的值。如果事件的类型代码是EV_KEY,当按键按下时值为1,松开时值为0;
根据上述解释,我们可以添加以下代码来解析从设备节点中获取的数据。
if(t.type == EV_KEY) // 我们只关心input event类型为EV_KEY(按键)的消息 if(t.value == 0 || t.value == 1) { printf("key %d %s\n", t.code, // t.code表示按下或松开了哪个按键 (t.value) ? "Pressed" : "Released"); // t.value表示按下还是松开了相应的按键 }
4、关闭设备节点
在从设备节点获取数据完成后,务必调用close函数,来关闭设备节点。即
close(keys_fd);
相关推荐:《Linux视频教程》
The above is the detailed content of what is linux device node. For more information, please follow other related articles on the PHP Chinese website!