• Linux 获取设备树源文件(DTS)里的资源【转】


    本文转载自:http://blog.csdn.net/keleming1/article/details/51036000

    http://www.cnblogs.com/dyllove98/archive/2013/07/03/3170178.html
    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 的头文件<libfdt.h> 里面。
     
    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
  • 相关阅读:
    PHP各种读取文件的函数效率对比
    一篇不错的session与cookie机制的文章
    Yahoo!团队实践分享:网站性能优化的34条黄金守则
    PHP魔术函数集锦
    MySQL索引类型一览 让MySQL高效运行起来
    Mysql的索引和查询优化
    MySQL简单查询性能分析
    kafka进阶一
    Event Loop
    如何提高 Webpack 的构建速度、优化前端性能?NPM 的模块构建优先选用ES6还是ES5?如何吃透复杂的插件体系,源码如何阅读?
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7551496.html
Copyright © 2020-2023  润新知