二十二、【devicetree】設備樹的介紹


一、簡介

  設備樹定義是保留着存在於系統中的設備信息,當機器引導時,OS通過使用驅動程序和其他組件獲得的信息建立此樹,並且當添加或刪除設備時更新此樹。

  • 設備樹保留着存在於系統中的設備信息。當機器引導時,OS通過使用驅動程序和其他組件獲得的信息建立此樹,並且當添加或刪除設備時更新此樹。
  • 設備樹是分級, 總線上的設備代表着總線適配器或驅動控制器的“子集”
  • 設備樹的每一個節點是一個設備節點(devnode),一個devnode包括設備驅動程序的設備對象加上有OS所保留的內部信息。
  • DTS:設備樹源文件,ASCII格式
  • DTC:設備樹編譯工具。
  • DTB:二進制設備樹。

 

 

二、設備樹的使用

  uboot負責加載到內存,內核解析使用。

1、編譯

//內核編譯dts
make ARCH=arm -j4 CROSS_COMPILE=arm-linux-gnueabihf- dtbs

//手工編譯
./scripts/dtc/dtc -I dts -O dtb -o xxx.dtb arch/arm/boot/dts/xxx.dts // 編譯 dts 為 dtb
./scripts/dtc/dtc -I dtb -O dts -o xxx.dts arch/arm/boot/dts/xxx.dtb // 反編譯 dtb 為 dts

2、設備樹常見屬性介紹

(1)節點屬性
cpu0: cpu@0 {
    compatible = "arm,cortex-a7";
    device_type = "cpu";
    reg = <0>;
} 
  • cpu0:為結點名稱起一個別名。
(2)compatible屬性
intc: interrupt-controller@a01000 {
    compatible = "arm,cortex-a7-gic";
    #interrupt-cells = <3>;
    interrupt-controller;
    reg = <0xa01000 0x1000>,
          <0xa02000 0x100>;
};
  • arm:芯片廠商。
  • cortex-a7-gic:模塊對應的驅動名
(3)model屬性
model = "embedfire i.MX6 ULL NPi Board"; 
  • 准確描述當前板子型號信息。
(4)status屬性

 (5)reg屬性
ocrams: sram@900000 {
      compatible = "fsl,lpm-sram";
      reg = <0x900000 0x4000>;
    };
  • 地址:外設寄存器組的起始地址。
  • 長度:外設寄存器組的字節長度。
(6)#address-cells和#size-cells屬性
soc {
    #address-cells = <1>;
    #size-cells = <0>;
    compatible = "simple-bus";
    interrupt-parent = <&gpc>;
    ranges;
    ocrams: sram@900000 {
            compatible = "fsl,lpm-sram";
            reg = <0x900000>;
    };
};
  • #address-cells:設置子節點reg地址的數量 。
  • #size-cells:設置子節點中reg地址的長度的數量。  

 3、系統中查看設備樹

ls /sys/firmware/devicetree/base 

 或者:

ls /proc/device-tree

4、驅動中獲取DTS屬性信息的接口

(1)節點表示:/include/linux/of.h
struct device_node {
    const char *name;  //節點名
    const char *type;  //設備類型
    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;
#if defined(CONFIG_OF_KOBJ)
    struct  kobject kobj;
#endif
    unsigned long _flags;
    void    *data;
#if defined(CONFIG_SPARC)
    const char *path_component_name;
    unsigned int unique_id;
    struct of_irq_controller *irq_trans;
#endif
};

查節點

  • 路徑/類型/名字/compatible

incldue/linux/of.h

(2)of_find_node_by_path()函數
struct device_node *of_find_node_by_path(struct device_node *from,const char *path);

參數:

  • from:開始查找的節點,NULL表示從根節點開始查找

  • path:查找的節點名

返回值:

  • 成功:device_node表示的節點
  • 失敗:NULL
(3)of_find_node_by_type()函數:根據“device_type“屬性來查找節點
struct device_node *of_find_node_by_type(struct device_node *from, const char *type);

不建議使用

(4)of_find_node_by_name()函數:根據"name"屬性來查找節點
struct device_node *of_find_node_by_name(struct device_node *from,const char *name);

不建議使用

(5)of_find_compatible_node()函數
struct device_node *of_find_compatible_node(struct device_node *from,const char *type, const char *compat);

參數:

  • from:開始查找的節點,NULL表示從根節點開始查找

  • type:指定 device_type 屬性值

  • compat:指定 compatible 屬性值

返回值:

  • 成功:device_node表示的節點
  • 失敗:NULL

(4)查節點的屬性值:incldue/linux/of.h

struct property {
    char    *name;      //屬性名
    int     length;     //屬性長度
    void    *value;     //屬性值
    struct property *next; //下一個屬性
#if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC)
    unsigned long _flags;
#endif
#if defined(CONFIG_OF_PROMTREE)
    unsigned int unique_id;
#endif
#if defined(CONFIG_OF_KOBJ)
    struct bin_attribute attr;
#endif
};
(5)of_find_property()函數
  • 節點+屬性名

查找節點中的屬性

struct property *of_find_property(const struct device_node *np,const char *name,int *lenp);

參數:

  • np:device_node表示的節點

  • name:查找的屬性名字

  • lenp:屬性值的字節數

返回值:

  • 成功:property表示的屬性
  • 失敗:NULL
(6)of_property_read_u32()函數:讀取一個32位無符號整數
static inline int of_property_read_u32(const struct device_node *np,const char *propname,
u32 *out_value);

參數:

  • np:device_node表示的節點

  • propname:查找的屬性名字

  • out_value:屬性值的整數值

返回值:

  • 成功:0
  • 失敗:負值
(7)of_property_read_u32_array()函數:讀取32位無符號整數數組
int of_property_read_u32_array(const struct device_node *np,const char *propname,u32 *out_values,size_t sz)
  • np:device_node表示的節點

  • name:查找的屬性名字

  • out_value:讀取到的數組值

  • sz :要讀取的數組元素數量

(8)of_property_read_string()函數:讀字符串
int of_property_read_string(struct device_node *np,const char *propname,const char **out_string)

參數:

  • np:device_node表示的節點

  • proname:查找的屬性名字

  • out_string:讀取到的字符串值

返回值:

  • 成功:0
  • 失敗:負值

  

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM