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

📅 2026/6/24 12:51:40
嵌入式linux学习记录十四、术语
大管家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结构体 */};dev_t dev_id门牌号主次设备号。就是一个本质上就是一个u32类型的数字。高 12 位是主设备号低 20 位是次设备号。它仅仅是个数字用来在内核登记备案。struct cdev cdev灵魂/行为内核里代表“字符设备”的核心结构体。它里面最重要的成员是file_operations函数指针集。应用层调用read/write时内核就是通过它找到你的 C 语言驱动函数的。对下绑定身份dev设备号字符设备必须要有一个唯一的身份证号。通过cdev_add函数内核把设备号dev与这个cdev结构体进行哈希绑定。物理意义当应用层去打开/dev/ap3216c文件时内核通过文件自带的设备号就能在工商大网哈希表里瞬间定位到这个cdev结构体。对上绑定业务opsstruct file_operations光找到设备还不够应用层接下来还要调用read/write/open。cdev-ops指针就直接指向了你自己在驱动里实现的“业务函数大盘”。物理意义内核顺着设备号找到cdev后会立刻翻开它的ops菜单看看里面有没有写着.open ap3216c_open。如果有就把控制权交过去。struct class *class家族/分类高层管理概念。比如创建一个叫my_led_class的类在系统的/sys/class/目录下就会多一个文件夹。它是为了批量管理属于同一类的设备。struct device *device窗户/文件它是类class的孩子。它的诞生会直接触发内核在/dev/目录下生成用户可见的设备文件比如/dev/led。应用层就是通过这个窗户和驱动说话的。struct device_node *nd硬件图纸设备树专属结构体。它不参与上面的任何软件分配它唯一的任务就是精准指向设备树.dts里的那个节点供你解析 GPIO 编号、中断号等硬件资源。小管家struct irq_keydesc{int gpio; /* gpio */int irqnum; /* 中断号 */unsigned char value; /* 按键对应的键值 */char name[10]; /* 名字 */struct keyinput_dev *back_dev; /* 【关键】反向指针指向它的大管家 */// irqreturn_t (*handler)(int, void *); /* 中断服务函数 */};gpio“我负责盯着哪根硬件引脚比如 GPIO1_IO18”irqnum“如果有人拍这根引脚我该通过哪个特定的电话线中断号向大管家汇报”value“如果确认这个人真的按下了我该给 Input 大集团上报什么数字键值比如上报KEY_0还是KEY_ENTER”name“我的工牌名字叫什么比如KEY0申请中断时给内核看的”handler“当我的电话响了中断触发我该用哪个具体的动作中断服务函数指针去接电话”struct inode—— 停在车库里的“物理实体车”比喻它是车库里那辆实实在在、有车架号、有固定排量的真车比如一辆具体的五菱宏光。特点不管有没有人来租这辆车都铁打不动地停在车库里。在整个系统里一辆物理车一个文件有且仅有一个inode结构体。在 Linux “一切皆文件” 的大盘下磁盘上的每一个文件、/dev/下的每一个设备节点在内核内存里都有且仅有一份专属的struct inode结构体来记录它的元数据比如文件大小、创建时间、文件类型以及我们最关心的设备号。struct file (filp)—— 客户签下的“租车合同”比喻当一个客户应用层进程跑来调用open()说“我要租车”时前台营业员不会把整辆车直接塞进客户的口袋而是会当场打印一份“租车合同”这就是filp。特点如果有 3 个客户同时open了同一个设备文件车库里依然只有一辆车1个inode但前台会打印出 3 份独立的合同3个filp。合同filp里记录的是只有这次租车才关心的动态信息比如你开到哪了f_pos读写偏移量、你是只读还是读写f_flags权限、以及合同特有的备注栏private_data。struct inode和struct device区别和联系在 Linux 内核中struct inode和struct device都是极其核心的底层结构体但它们属于完全不同的两个管理维度。简单来说inode属于“文件系统维度”软件抽象而device属于“设备驱动模型维度”硬件抽象。为了让你彻底搞懂它们的关系我们先看两者的核心区别再看它们在字符设备驱动中是如何交汇连接的。核心区别它们各自管什么struct device—— 驱动模型的“硬件护照”所属领域设备驱动模型Linux Device Model。它是什么它是内核用来抽象、拓扑物理硬件的基类。无论是底层的 GPIO 控制器、I2C 总线还是你通过平台总线注册的按键pdev-dev在内核眼里都是一个struct device。核心职责建立内核的硬件树状拓扑结构展示在/sys/devices/体系中。它记录了硬件的总线类型bus、电源管理状态power、父设备parent、以及驱动私有数据driver_data。生命周期由设备总线Platform/I2C/SPI 等或驱动框架管理。当你在probe阶段或通过device_create()注册硬件时它才在内存中被创建。struct inode—— 文件系统的“档案实体”所属领域VFS虚拟文件系统。它是什么它是磁盘或内存文件系统里某个文件/节点的物理唯一标识。在 Linux “一切皆文件”的哲学下每个文件无论是普通文本、目录还是/dev/key这样的设备文件在内核中都有且仅有一个struct inode。核心职责记录文件的元数据。比如文件大小、访问权限、所有者、修改时间、以及该文件对应的主次设备号dev_t i_rdev和字符设备指针struct cdev *i_cdev。生命周期由文件系统管理。当你在/dev/下看到一个节点哪怕没有任何驱动绑定它它的inode也已经存在于文件系统中了。核心联系它们在何处交汇虽然它们一个管“文件”一个管“硬件”但在字符设备驱动或者是你正在写的 Input 子系统驱动中它们会经历一场完美的接力与交汇。我们通过你在应用层执行open(/dev/input/event1)时的底层流动来看它们是如何发生联系的桥梁一设备号dev_t这是它们产生联系的纽带。硬件端struct device你在probe阶段调用device_create()或者input_register_device()时内核会为你分配一个主次设备号并把这个设备号打上struct device的标签。软件端struct inode内核的udev或mdev守护进程感知到新硬件加入后会在/dev/下创建一个对应的设备文件。这个文件的inode-i_rdev里就死死地写入了和硬件端一模一样的设备号。桥梁二通用open的寻路过程。当应用层通过打开文件找到硬件大管家时两条线彻底拧成一股绳第一步通过inode抓到 cdev 应用层调用open(/dev/input/event1)。内核顺着路径找到该文件的struct inode。内核看了一眼inode-i_cdev噢它指向了你之前在probe里注册的字符设备cdev。第二步通过 cdev 跨界到device 在标准驱动中你的大管家结构体通常把cdev和struct device *封装在一起或者在 Input 子系统里evdev结构体同时关联了cdev和struct device。第三步落脚到device抽屉 通用open函数通过container_of从inode-i_cdev捞出大管家再从大管家里拿到struct device最终调用dev_get_drvdata()或者input_get_drvdata()提取出你寄存的内存指针塞进filp-private_data。struct device_node和struct device关系.dts 文件你写的设备树源码↓ 编译.dtb二进制设备树↓ 内核启动时解析struct device_node内存中的树状结构描述硬件长什么样↓ 驱动 match probe 成功后struct device驱动模型中的设备对象代表这个硬件正在被管理inode-i_cdev 查找到的struct cdev的内存地址;在 Linux 中万物皆文件。为了让用户空间了解内核的情况内核已经有了两个大名鼎鼎的虚拟文件系统Procfs挂载在/proc主要用于展示与系统进程、内存、CPU、中断等相关的核心运行状态。它的管制非常严格不准乱放驱动的私有调试信息。Sysfs挂载在/sys主要用于展示设备的拓扑模型与标准的硬件属性比如你的触摸屏灵敏度、LED 的亮灭。它有着严格的设备树和分类哲学每一个文件的命名和存放位置都要符合内核规范。Debugfs挂载在/sys/kernel/debug/是 Linux 内核提供的一种专门用于开发调试的虚拟文件系统Virtual File System。简单来说它是内核空间与应用层用户空间之间的一条无限制、高自由度的“秘密通道”。内核开发者可以通过它把驱动内部的任意变量、状态或大块的原始数据以“文件”的形式暴露给用户空间方便在终端进行查看或修改。Debugfs 的工作机制高度依赖内核提供的标准 API。在你的edt-ft5x06触摸屏驱动里就是一套教科书式的用法建大门创建目录 驱动调用debugfs_create_dir(edt-ft5x06, NULL)内核在/sys/kernel/debug/下划出一块底盘。摆摊位创建文件并绑定变量/操作绑定简单变量调用debugfs_create_u16(num_x, ...)。内核会自动打通当你cat num_x时内核直接把结构体里的tsdata-num_x变量值转成字符串吐给你。绑定复杂行为调用debugfs_create_file(mode, ..., debugfs_mode_fops)。将文件节点与自定义的文件操作结构体包含读写回调函数死死绑定在一起。撤摊撤场驱动卸载 当驱动被移除remove时调用debugfs_remove_recursive(tsdata-debug_dir)一键把该目录下所有的虚拟文件和文件夹安全地从内存中抹去。