嵌入式Linux导出设备树,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 = <2>; compatible = "cavium,octeon-3860-gpio";reg = <0x10700 0x00000800 0x0 0x100>;gpio-controller; …根据其描述, 可知道gpio控制器的IO内存起始地址为:0x107900000800, 长度为0x100.即从0x107900000800到0x1079000008ff.在目标板里使用cat /proc/iomem可以看到:1070000000800-10700000008ff: /soc@0/gpio-controller@1070000000800关于i2c的描述:twsi0: i2c@1180000001000 { #address-cells = <1>; #size-cells = <0>; compatible = "cavium,octeon-3860-twsi";reg = <0x11800 0x00001000 0x0 0x200>;interrupts = <0 45>; clock-rate = <100000>; 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 = <2>; compatible = "cavium,octeon-3860-gpio";reg = <0x10700 0x00000800 0x0 0x100>;gpio-controller; …根据其描述, 可知道gpio控制器的IO内存起始地址为:0x107900000800, 长度为0x100.即从0x107900000800到0x1079000008ff.在目标板里使用cat /proc/iomem可以看到:1070000000800-10700000008ff: /soc@0/gpio-controller@1070000000800关于i2c的描述:twsi0: i2c@1180000001000 { #address-cells = <1>; #size-cells = <0>; compatible = "cavium,octeon-3860-twsi";reg = <0x11800 0x00001000 0x0 0x200>;interrupts = <0 45>; clock-rate = <100000>; IO内存起始地址为:0x118000001000,长度为0x200.从0x118000001000到0x1180000011ff.在目标板里使用cat /proc/iomem可以看到:1180000001000-11800000011ff: /soc@0/i2c@1180000001000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值