当前位置: 首页 > news >正文

嵌入式Linux驱动开发 —— 从DTS到代码的桥梁与简单OF系列API(2)

接前一篇文章:嵌入式Linux驱动开发 —— 从DTS到代码的桥梁与简单OF系列API(1)

核心数据结构:device_node、property和resource

在讲具体的API之前,我们需要先了解一下内核是用什么数据结构来表示设备树的。毕竟API只是操作这些数据结构的工具,如果不了解数据结构本身,用起API来也是一头雾水。

struct device_node:节点的内核表示

struct device_node是内核对设备树节点的描述。每个设备树节点在内核里都对应一个device_node结构体。这个结构体的定义在include/linux/of.h里,我们挑重点字段看:

struct device_node { const char *name; /* 节点名字,比如 "gpio" */ const char *type; /* 设备类型,取自 device_type 属性 */ phandle phandle; /* 节点的 phandle 值 */ const char *full_name; /* 节点的全路径名 */ struct fwnode_handle fwnode; struct property *properties; /* 属性链表头 */ struct property *deadprops; /* 已删除的属性 */ struct device_node *parent; /* 父节点 */ struct device_node *child; /* 子节点 */ struct device_node *sibling; /* 兄弟节点 */ struct kobject kobj; unsigned long _flags; void *data; /* ... 更多平台特定字段 ... */ };

这个结构体设计得很巧妙。它不仅记录了节点的名字和类型,还通过parentchildsibling三个指针把整棵树串了起来。这意味着你可以从任意一个节点出发,往上找父节点、往下找子节点、往旁边找兄弟节点 —— 就像在真的树上爬一样(其实更像查族谱)。

struct device_node中的properties字段指向一个属性链表,所有的property结构体都挂在这个链表上。我们接下来看property结构体。

struct property:属性的内核表示

struct property { char *name; /* 属性名字,比如 "reg" */ int length; /* 属性值的字节长度 */ void *value; /* 属性值,可以是任意数据 */ struct property *next; /* 指向下一个属性 */ unsigned long _flags; unsigned int unique_id; struct bin_attribute attr; };

这里最关键的是value字段。它是一个void *,可以指向任意类型的数据。这是因为设备树里的属性值可以是各种类型:可能是单个整数、可能是字符串、可能是整数数组、甚至可能是任意字节序列。

那么内核怎么知道value里存的是什么类型呢?答案是:不知道。内核只知道这是一坨字节,具体怎么解释,要看属性的名字和上下文。比如status属性通常被解释为字符串,reg属性被解释为整数数组,而compatible属性被解释为字符串数组。

所以当我们用API读取属性时,需要明确告诉内核我们想要什么类型的数据。这就是为什么有of_property_read_u32()of_property_read_string()这样不同的函数。

struct resource:资源的统一描述

Linux 内核用struct resource来统一描述各种资源 —— 不仅仅是内存映射IO,还包括中断、DMA 通道等。这个结构体定义在include/linux/ioport.h中:

struct resource { resource_size_t start; /* 资源起始地址/号 */ resource_size_t end; /* 资源结束地址/号 */ const char *name; /* 资源名称 */ unsigned long flags; /* 资源类型标志 */ struct resource *parent, *sibling, *child; };

flags字段说明这是什么类型的资源:

  • IORESOURCE_MEM:内存映射IO。
  • IORESOURCE_IRQ:中断资源。
  • IORESOURCE_IO:端口IO(x86特有)。
  • IORESOURCE_DMA:DMA通道。

设备树里的reg属性可以通过of_address_to_resource()函数转换成resource结构体,这样驱动就可以用统一的方式来处理不同类型的资源了。

更多内容请看下回。

http://www.jsqmd.com/news/879033/

相关文章:

  • 为什么你的DeepSeek告警总在凌晨3点炸?揭秘CPU/内存/Token耗尽三重耦合告警的因果建模法
  • 紧急通知:2024 Q3起甲方招标强制要求提交AI辅助生成声明——ChatGPT项目计划书合规签署指南(含法律效力白皮书)
  • 2026长沙系统门窗品牌深度测评:正统大牌南山世博特,集团级高端门窗实力标杆 - 涂伟
  • 选择Taotoken的Token Plan套餐,为长期项目锁定更优成本
  • 5分钟解锁Cursor Pro:免费使用AI编程助手的终极指南
  • 【AI视频生成工具学习曲线深度报告】:20年AI工程经验总结的5大认知断层与30天速通路径
  • DeepSeek免费额度即将全面收紧?基于127家企业的API调用日志分析,预测Q3配额下调时间点及迁移过渡期3套保额方案
  • ZXPInstaller终极指南:告别Adobe插件安装烦恼的跨平台解决方案
  • 告别繁琐下载:kill-doc浏览器脚本实现文档下载自动化终极方案
  • 为什么92%的团队部署DeepSeek失败?火山引擎vLLM+Triton加速方案(2024最新生产级验证)
  • 长期项目使用Taotoken Token Plan套餐的成本优化观察
  • 2026年4月深圳头部租车公司推荐,粤港澳包车/婚礼租车/商务租车/婚车租赁/企业租车/包车,租车公司口碑推荐 - 品牌推荐师
  • Cobalt Strike(CS)下载与使用指南
  • 全面精通QuPath数字病理分析:实战应用全解析
  • 终极指南:如何在Windows上使用iperf3进行专业网络性能测试
  • 为Hermes Agent配置Taotoken作为自定义模型提供方的步骤
  • 智读致用|《谷歌亚马逊如何做产品》9|胜在技术:做聪明的技术选择,比死磕代码更重要
  • 基于树模型混合分类器的物联网入侵检测系统设计与实战
  • 为什么你的DeepSeek流式接口总在TP99处陡增?揭秘TCP_NODELAY误配+LLM输出熵突变双重陷阱
  • 从零开始在个人项目中接入Taotoken并完成首次计费消费
  • ComfyUI-WanVideoWrapper:新手必看的AI视频生成终极指南
  • 【AI工具成本真相报告】:开源≠免费!TCO测算显示中大型项目3年隐性成本反超商业工具37%
  • DeepSeek身份认证Token刷新机制失效?——2024Q3高频报障TOP1问题溯源,附自动巡检Shell脚本与Prometheus告警规则
  • 为Nodejs后端服务配置Taotoken多模型聚合API调用
  • 3.1 注册表的备份与还原(Wise Registry Cleaner)——桌面支持必会的“后悔药”操作
  • 如何用GoldenCheetah将训练数据转化为科学训练指南
  • 5分钟学会Blender相机抖动效果:Camera Shakify让动画瞬间生动起来
  • Syncthing Android:构建去中心化文件同步网络的完整解决方案
  • YOLOv11农田烟草叶片病害目标检测数据集-470张-tobacco-plant-1
  • Zotero PDF Translate:打破语言壁垒的学术翻译神器