你知道Linux获取设备树源文件(DTS)里的资源?

在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 platform_driver 的probe() 里面知道设备的中断号, 内存地址等资源。 这些资源的描述信息存放在 resource 数据结构中, 相同的资源存放在一个树形树形数据结构中, 通过父节点, 兄弟节点, 子节点相连。 比如中断资源, io端口资源, io内存资源, dma资源有不同资源树。 linux使用 struct resource 来描述一个resouce struct resource { resource_size_t start; //资源范围的开始 resource_size_t end; //资源范围的结束 const char *name; //资源拥有者名 unsigned long flags; //资源属性标识 struct resource *parent, *sibling, *child; //资源树的父节点, 兄弟节点, 字节点指针 }; resource_size_t 由系统决定 为uint32_t 或uint64_t 。 在platform机制里, 使用platform_get_resource()来获取指定的资源类型。 比如获取想获取中断号, irq = platform_get_irq(pdev, 0); int platform_get_irq(struct platform_device *dev, unsigned int num) { struct resource *r = platform_get_resource(dev, ioresource_irq, num); return r ? r->start : -enxio; } export_symbol_gpl(platform_get_irq); platform_get_irq() 会返回一个start, 即可用的中断号。 之后便可使用request_irq() 来注册中断服务函数。 再比如想要获取io内存资源: struct resource *res_mem = platform_get_resource(pdev, ioresource_mem, 0); 即可得到一个io内存资源节点指针, 包括了地址的开始,结束地址等, 该io内存的长度可用 resource_size() 来获取, 但这段资源只是一个描述, 想真正使用这段io内存, 还要经过先申请, 再映射的过程。例如可使用devm_request_mem_region()申请出使用这段io内存, 再使用ioremap() 将其映射出来, 供用户空间使用。 devm_request_mem_region(&pdev->dev, res_mem->start, resource_size(res_mem), res_mem->name)) addr_start = ioremap(res_mem->start, resource_size(res_mem)); ioremap() 的返回值即为该资源的虚拟地址。 io内存的资源是在设备树源(device tree source)文件(以.dts结尾)里给出的,.dts文件就是用来描述目标板硬件信息的, 在uboot启动后, 使用uboot提供的特定api将其获取出来, 如fdt_getprop(), fdt_path_offset(), 这些api包含在uboot 的头文件 里面。 uboot将.dts文件里的描述解析出来, 再对相应寄存器赋值, 在linux启动后, 使用 platform_get_resource() 即可获取到这些给定的资源, 在驱动里使用。 例如一个在.dts文件中关于gpio资源的描述: gpio: gpio-controller@1070000000800 { #gpio-cells = ; compatible = cavium,octeon-3860-gpio; reg = ; gpio-controller; … 根据其描述, 可知道gpio控制器的io内存起始地址为:0x107900000800, 长度为0x100. 即从 0x107900000800 到 0x1079000008ff. 在目标板里使用 cat /proc/iomem 可以看到: 1070000000800-10700000008ff : /soc@0/gpio-controller@1070000000800 关于i2c 的描述: twsi0: i2c@1180000001000 { #address-cells = ; #size-cells = ; compatible = cavium,octeon-3860-twsi; reg = ; interrupts = ; clock-rate = ; io内存起始地址为: 0x118000001000, 长度为0x200. 从 0x118000001000 到 0x1180000011ff. 在目标板里使用 cat /proc/iomem 可以看到: 1180000001000-11800000011ff : /soc@0/i2c@1180000001000
在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 platform_driver 的probe() 里面知道设备的中断号, 内存地址等资源。 这些资源的描述信息存放在 resource 数据结构中, 相同的资源存放在一个树形树形数据结构中, 通过父节点, 兄弟节点, 子节点相连。 比如中断资源, io端口资源, io内存资源, dma资源有不同资源树。 linux使用 struct resource 来描述一个resouce struct resource { resource_size_t start; //资源范围的开始 resource_size_t end; //资源范围的结束 const char *name; //资源拥有者名 unsigned long flags; //资源属性标识 struct resource *parent, *sibling, *child; //资源树的父节点, 兄弟节点, 字节点指针 }; resource_size_t 由系统决定 为uint32_t 或uint64_t 。 在platform机制里, 使用platform_get_resource()来获取指定的资源类型。 比如获取想获取中断号, irq = platform_get_irq(pdev, 0); int platform_get_irq(struct platform_device *dev, unsigned int num) { struct resource *r = platform_get_resource(dev, ioresource_irq, num); return r ? r->start : -enxio; } export_symbol_gpl(platform_get_irq); platform_get_irq() 会返回一个start, 即可用的中断号。 之后便可使用request_irq() 来注册中断服务函数。 再比如想要获取io内存资源: struct resource *res_mem = platform_get_resource(pdev, ioresource_mem, 0); 即可得到一个io内存资源节点指针, 包括了地址的开始,结束地址等, 该io内存的长度可用 resource_size() 来获取, 但这段资源只是一个描述, 想真正使用这段io内存, 还要经过先申请, 再映射的过程。例如可使用devm_request_mem_region()申请出使用这段io内存, 再使用ioremap() 将其映射出来, 供用户空间使用。 devm_request_mem_region(&pdev->dev, res_mem->start, resource_size(res_mem), res_mem->name)) addr_start = ioremap(res_mem->start, resource_size(res_mem)); ioremap() 的返回值即为该资源的虚拟地址。 io内存的资源是在设备树源(device tree source)文件(以.dts结尾)里给出的,.dts文件就是用来描述目标板硬件信息的, 在uboot启动后, 使用uboot提供的特定api将其获取出来, 如fdt_getprop(), fdt_path_offset(), 这些api包含在uboot 的头文件 里面。 uboot将.dts文件里的描述解析出来, 再对相应寄存器赋值, 在linux启动后, 使用 platform_get_resource() 即可获取到这些给定的资源, 在驱动里使用。 例如一个在.dts文件中关于gpio资源的描述: gpio: gpio-controller@1070000000800 { #gpio-cells = ; compatible = cavium,octeon-3860-gpio; reg = ; gpio-controller; … 根据其描述, 可知道gpio控制器的io内存起始地址为:0x107900000800, 长度为0x100. 即从 0x107900000800 到 0x1079000008ff. 在目标板里使用 cat /proc/iomem 可以看到: 1070000000800-10700000008ff : /soc@0/gpio-controller@1070000000800 关于i2c 的描述: twsi0: i2c@1180000001000 { #address-cells = ; #size-cells = ; compatible = cavium,octeon-3860-twsi; reg = ; interrupts = ; clock-rate = ; io内存起始地址为: 0x118000001000, 长度为0x200. 从 0x118000001000 到 0x1180000011ff. 在目标板里使用 cat /proc/iomem 可以看到: 1180000001000-11800000011ff : /soc@0/i2c@1180000001000

中控智慧科技指纹门禁一体机F2plus介绍
蓝牙耳机什么牌子好,便宜好用的蓝牙耳机推荐
波音表示预计9月完成737MAX软件修复将会尽力让737MAX飞机早日复飞
LG推出两款搭载22英寸触摸屏的InstaView冰箱,可实现WiFi连接
三篇基于迁移学习的论元关系提取
你知道Linux获取设备树源文件(DTS)里的资源?
基于微机电系统MEMS技术的Bourns BPS140系列压力传感器介绍
微软宣布Win10创意者更新:4月11日正式推送,PC用户先行,笔记本平台和手机稍后
浅析适用于车载应用位置检测的新变革
互联网+是怎样诞生的
苹果MacBook有望引入MagSafe功能
谷东科技用AR助力把好燃气“安全阀”
高冷外表下是一颗全能的 “芯”
哪一些物联网应用可以做到减少环境影响
M24LR64-R:13.56 MHz双接口EEPROM开发方案
高压直流电源的工作原理是怎样的
鼎桥无线专网解决方案在电力领域成熟应用
OPPOR17Pro评测 值不值得买
RX65N和RX651系列主要特性分析(原理图)
元宇宙怎么赚钱_元宇宙盈利模式