嵌入式linux学习记录十四、术语

  1. 大管家: struct keyinput_dev

    {

    dev_t devid; /* 设备号 */

    struct cdev cdev; /* cdev */

    struct class *class; /* 类 */

    struct device *device; /* 设备 */

    struct device_node *nd; /* 设备节点 */

    struct timer_list timer; /* 定义一个定时器*/

    struct irq_keydesc *irqkeydesc; /* 按键描述数组 */

    unsigned char curkeynum; /* 当前的按键号 */

    int key_nums; /* 账本:记录设备树里实际配置的按键数量 */

    struct input_dev *inputdev; /* input结构体 */

    };

    1. dev_t dev_id(门牌号 ):主次设备号。就是一个**,** 本质上就是一个 u32 类型的数字。高 12 位是主设备号,低 20 位是次设备号。它仅仅是个数字,用来在内核登记备案。
    2. struct cdev cdev(灵魂/行为):内核里代表"字符设备"的核心结构体。它里面最重要的成员是 file_operations(函数指针集)。应用层调用 read/write 时,内核就是通过它找到你的 C 语言驱动函数的。
    3. struct class *class(家族/分类):高层管理概念。比如创建一个叫 "my_led_class" 的类,在系统的 /sys/class/ 目录下就会多一个文件夹。它是为了批量管理属于同一类的设备。
    4. struct device *device(窗户/文件):它是类(class)的孩子。它的诞生会直接触发内核在 /dev/ 目录下生成用户可见的设备文件 (比如 /dev/led)。应用层就是通过这个窗户和驱动说话的。
    5. struct device_node *nd(硬件图纸) :设备树专属结构体。它不参与上面的任何软件分配,它唯一的任务就是精准指向设备树(.dts)里的那个节点,供你解析 GPIO 编号、中断号等硬件资源。
  2. 小管家: struct irq_keydesc

    {

    int gpio; /* gpio */

    int irqnum; /* 中断号 */

    unsigned char value; /* 按键对应的键值 */

    char name10; /* 名字 */

    struct keyinput_dev *back_dev; /* 【关键】反向指针,指向它的大管家 */

    // irqreturn_t (*handler)(int, void *); /* 中断服务函数 */

    };

    1. gpio:"我负责盯着哪根硬件引脚?(比如 GPIO1_IO18)"

    2. irqnum:"如果有人拍这根引脚,我该通过哪个特定的电话线(中断号)向大管家汇报?"

    3. value :"如果确认这个人真的按下了,我该给 Input 大集团上报什么数字键值?(比如上报 KEY_0 还是 KEY_ENTER?)"

    4. name :"我的工牌名字叫什么?(比如 "KEY0",申请中断时给内核看的)"

    5. handler:"当我的电话响了(中断触发),我该用哪个具体的动作(中断服务函数指针)去接电话?",

struct inode ------ 停在车库里的"物理实体车"

  1. 比喻 :它是车库里那辆实实在在、有车架号、有固定排量的真车(比如一辆具体的五菱宏光)

  2. 特点 :不管有没有人来租,这辆车都铁打不动地停在车库里。在整个系统里,一辆物理车(一个文件)有且仅有一个 inode 结构体

  3. struct file (filp) ------ 客户签下的"租车合同"

    1. 比喻 :当一个客户(应用层进程)跑来调用 open() 说"我要租车"时,前台营业员不会 把整辆车直接塞进客户的口袋,而是会当场打印一份"租车合同",这就是 filp

    2. 特点

      • 如果有 3 个客户同时 open 了同一个设备文件,车库里依然只有一辆车(1个 inode ),但前台会打印出 3 份独立的合同(3个 filp)。

      • 合同(filp)里记录的是只有这次租车才关心的动态信息 :比如你开到哪了(f_pos 读写偏移量)、你是只读还是读写(f_flags 权限)、以及合同特有的备注栏(private_data

  4. struct inodestruct device区别和联系:

    在 Linux 内核中,struct inodestruct device 都是极其核心的底层结构体,但它们属于完全不同的两个管理维度

    简单来说:inode 属于"文件系统维度"(软件抽象),而 device 属于"设备驱动模型维度"(硬件抽象)。 为了让你彻底搞懂它们的关系,我们先看两者的核心区别,再看它们在字符设备驱动中是如何交汇连接的。

    1. 核心区别:它们各自管什么?

      1. struct device ------ 驱动模型的"硬件护照"

        1. 所属领域:设备驱动模型(Linux Device Model)。

        2. 它是什么 :它是内核用来抽象、拓扑物理硬件 的基类。无论是底层的 GPIO 控制器、I2C 总线,还是你通过平台总线注册的按键(pdev->dev),在内核眼里都是一个 struct device

        3. 核心职责 :建立内核的硬件树状拓扑结构(展示在 /sys/devices/ 体系中)。它记录了硬件的总线类型(bus)、电源管理状态(power)、父设备(parent)、以及驱动私有数据(driver_data)。

        4. 生命周期 :由设备总线(Platform/I2C/SPI 等)或驱动框架管理。当你在 probe 阶段或通过 device_create() 注册硬件时,它才在内存中被创建。

      2. struct inode ------ 文件系统的"档案实体"

        1. 所属领域:VFS(虚拟文件系统)。

        2. 它是什么 :它是磁盘或内存文件系统里,某个文件/节点的物理唯一标识 。在 Linux "一切皆文件"的哲学下,每个文件(无论是普通文本、目录,还是 /dev/key 这样的设备文件)在内核中都有且仅有一个 struct inode

        3. 核心职责 :记录文件的元数据。比如:文件大小、访问权限、所有者、修改时间、以及该文件对应的主次设备号(dev_t i_rdev)和字符设备指针(struct cdev *i_cdev)。

        4. 生命周期 :由文件系统管理。当你在 /dev/ 下看到一个节点,哪怕没有任何驱动绑定它,它的 inode 也已经存在于文件系统中了。

    2. 核心联系:它们在何处交汇?

      虽然它们一个管"文件",一个管"硬件",但在字符设备驱动(或者是你正在写的 Input 子系统驱动)中,它们会经历一场完美的接力与交汇。

      我们通过你在应用层执行 open("/dev/input/event1") 时的底层流动,来看它们是如何发生联系的:

      1. 桥梁一:设备号(dev_t)这是它们产生联系的纽带。

        1. 硬件端(struct device :你在 probe 阶段调用 device_create() 或者 input_register_device() 时,内核会为你分配一个主次设备号,并把这个设备号打上 struct device 的标签。

        2. 软件端(struct inode :内核的 udevmdev 守护进程感知到新硬件加入后,会在 /dev/ 下创建一个对应的设备文件。这个文件的 inode->i_rdev 里,就死死地写入了和硬件端一模一样的设备号

      2. 桥梁二:通用 open 的寻路过程。当应用层通过打开文件找到硬件大管家时,两条线彻底拧成一股绳:

        1. 第一步(通过 inode 抓到 cdev) : 应用层调用 open("/dev/input/event1")。内核顺着路径找到该文件的 struct inode 。内核看了一眼 inode->i_cdev,噢!它指向了你之前在 probe 里注册的字符设备(cdev)。

        2. 第二步(通过 cdev 跨界到 device : 在标准驱动中,你的大管家结构体通常把 cdevstruct device * 封装在一起(或者在 Input 子系统里,evdev 结构体同时关联了 cdevstruct device)。

        3. 第三步(落脚到 device 抽屉) : 通用 open 函数通过 container_ofinode->i_cdev 捞出大管家,再从大管家里拿到 struct device ,最终调用 dev_get_drvdata() 或者 input_get_drvdata() 提取出你寄存的内存指针,塞进 filp->private_data

  5. struct device_node和struct device关系:

    .dts 文件(你写的设备树源码)

    ↓ 编译

    .dtb(二进制设备树)

    ↓ 内核启动时解析

    struct device_node(内存中的树状结构,描述硬件"长什么样")

    ↓ 驱动 match & probe 成功后

    struct device(驱动模型中的设备对象,代表"这个硬件正在被管理")

相关推荐
载数而行5202 小时前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
古城小栈3 小时前
Unix 与 Linux 异同小叙
linux·服务器·unix
国产化创客3 小时前
ESP32 CameraWebServer 原生摄像头项目全解析
物联网·开源·嵌入式·实时音视频·智能硬件
凡人叶枫4 小时前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
2601_961875245 小时前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant
java_cj5 小时前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
lsyeei5 小时前
linux 系统目录详解
linux·运维·服务器
森G5 小时前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt