0

0

什么是linux设备节点

青灯夜游

青灯夜游

发布时间:2022-04-18 20:10:58

|

7664人浏览过

|

来源于php中文网

原创

linux设备节点是应用程序和设备驱动程序沟通的一个桥梁;设备节点被创建在“/dev”,是连接内核与用户层的枢纽,相当于硬盘的inode一样的东西,记录了硬件设备的位置和信息。设备节点使用户可以与内核进行硬件的沟通,读写设备以及其他的操作。

什么是linux设备节点

本教程操作环境:linux5.9.8系统、Dell G3电脑。 

什么是设备节点

人和人之间沟通桥梁是语言。同样,应用程序和设备驱动程序沟通也需要一个桥梁。这个桥梁就是设备节点。

对于Linux系统,所有的IO资源都是文件,包括文件、目录、硬盘、设备等。那么,键盘作为计算机系统中的一款输入设备,操作系统同样也把它抽象了文件,要想获取用户从键盘上输入的数据时,只需要读取键盘提供的设备节点即可。

在Linux系统中,键盘作为输入设备,其对应的设备节点位于”/dev/input“下。在这个文件夹下有很多以event打头的文件,这些就是所有input设备的设备节点。如何确定哪个是键盘的设备节点呢?将键盘连接到树莓派上,打开终端,执行“sudo cat /dev/input/event0”,敲击键盘,如果没有输出,就换下一个节点,直到找到有输出的节点,那这个节点就是键盘对应的设备节点。

设备节点被创建在/dev下,是连接内核与用户层的枢纽,就是设备是接到对应哪种接口的哪个ID 上。 相当于硬盘的inode一样的东西,记录了硬件设备的位置和信息

在Linux中,所有设备都以文件的形式存放在/dev目录下,都是通过文件的方式进行访问,设备节点是Linux内核对设备的抽象,一个设备节点就是一个文件。应用程序通过一组标准化的调用执行访问设备,这些调用独立于任何特定的驱动程序。而驱动程序负责将这些标准调用映射到实际硬件的特有操作。

设备节点的作用

设备节点使得用户可以与内核进行硬件的沟通,读写设备以及其他的操作

在linux里面设备就像是普通文件一样的存在,访问一个设备就好像是访问一个文件一样

主设备号代表着一类设备,次设备号代表着同一类设备的不同个体,说到这里也许并不知道设备节点的存在形式

设备节点的存在形式

另外在linux里面还有一个概念,就是inode与block,也就是硬盘一面的块与节点,硬盘里面的inode就相当于一个文件或者文件夹,它记录下此文件下面的文件位置所在,文件的位置是以block大小对齐的,例如有些系统就是4K的大小,而inode的大小是有限的,所以就有了单个文件不能超过4G的说法。而在linux的驱动程序里面的节点在我个人的理解也可以看做是一个类似于硬盘的inode一样的东西,里面可以记录硬件设备的位置以及别的一些信息,在用户需要进行访问的时候就参照到设备节点所记录的信息进行设备的访问

如何从设备节点中获取数据

操作系统之所以把IO都抽象成了文件,最大的好处就是可以通过统一的接口来访问这个文件,从而和不同的设备沟通。这些统一的接口就是操作系统针对文件操作对外提供的一组系统调用:open函数、read函数、write函数等。比如,如果需要从一个设备中获取数据,只需要调用read函数去读取该设备对应的设备节点就可以了,当然在read之前,要先调用open函数打开。现在以获取键盘输入为例来介绍。

1、打开设备节点

在读取设备节点的数据之前,要先调用open函数打开设备节点。open函数的具体用法可以参考链接。简单描述如下:

函数声明:

int open(const char *pathname, int flags);

需要包含的头文件:

  #include 

参数:

* 第一个参数(const char *pathname):表示需要打开的文件路径

* 第二个参数(int flags):表示打开文件的方式,比如,”O_RDONLY” ——只读打开;”O_WRONLY”——只写打开;”O_RDWR”——读、写打开,等。

返回值:

 如果打开成功,则返回该文件的文件描述符,以供read,write等函数使用。否则,返回-1。

那么,要打开键盘的设备文件(假设是”/dev/input/even10“),则需要以下代码:

  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 、读取设备节点的数据

js-实现可展开隐藏导航菜单按钮特效
js-实现可展开隐藏导航菜单按钮特效

简单实用可展开隐藏导航菜单按钮js特效代码下载。这款菜单的特点是点击按钮时可以展开菜单,展开的时候带有弹性的动画特效,效果相当酷。菜单项是一些小图标,当然你也可以使用图标结合文字的方式,由于隐藏/展开的方式相对节省空间,因此这款菜单可以应用在移动设备上。

下载

读取设备节点需要使用read函数,具体使用方法可以参考链接。简单介绍如下:

函数声明:

  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。

  这里需要理解的是:设备节点是设备驱动程序提供的,且设备节点的数据是设备驱动写入的,而且写入时,是以上述结构的规则写入的,这是双方通过约定好的,那么应用程序去设备节点中读取数据之后,也需要按照上述结构去解析数据。那这个结构具体是什么意思呢?

* 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视频教程

相关专题

更多
typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

108

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

336

2023.10.11

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2023.11.20

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

527

2023.09.20

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

190

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

358

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

542

2024.08.29

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.6万人学习

Git 教程
Git 教程

共21课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号