设备树

[1] 什么是设备树?
    用于描述设备和总线层次关系的脚本。
   
[2] 设备树如何组成?
/ {                           // 根, 描述CPU总线和主板, 名字一定为'/'
 name = <value ...>        // 属性, name为名字,<value ...>为属性值
 name = "string", ...   // 属性, name为名字, "string", ...为属性值

 node {                     // 节点, 描述设备或总线, 名字可以使用全名
  name = <value ...> // 属性
  name = "string", ...   // 属性
  ...
  node {
   ...
    };
  };
 ...
};

   
    1. 名字
       描述设备类型或属性名,语法如下:
       基本名@扩展名
       (1) 基本名
           由'a'-'z'、'0'-'9'、','、'.'、'+'、'_'、'#'、'?'和'-'字符组成
           最大字符数为31
           是设备类型
           
       (2) 扩展名
           如果某类设备存在多个设备,可以增加扩展名,以避免名字重复,
           扩展名只能用于设备结点名, 一般为设备在总线上的地址
           内核在匹配驱动时,不会使用扩展名
       
    2. 属性值
       <value ...>        一个或多个32bit整数
       "string", ...      一个或多个字符串      
   
[3] 如何实现设备树?(详细语法)
    1. 根和内存
/ {
 model = "主板名";
 compatible = "SOC名";            // 必选,用于匹配BSP中的支持的SOC列表,以判断内核是否支持该主板

 // platform总线
 #address-cells = <A>;           // 必选, 地址位数,单位(cell)为32bit, A = 地址位数 / 32
 #size-cells = <S>;              // 必选, 大小位数,单位(cell)为32bit, S = 大小位数 / 32

 // 内存
 memory {
  device_type = "memory";       // device_type值一定为"memory"
  reg = <address size ... ...>  // 必选, 描述地址范围
 };
};

       <address size>
       (1) 地址和大小成对出现, 描述内存范围, 地址的位数决定于A,大小位数决定于S
       (2) 地址或大小的位数超过32位时,需要用多个32bit数表示,采用大端模式
           例: A = 2  S = 2 时
               reg = <0x00000000 0x400000000 0x00000000 0x400000000>
               表示内存范围为0x400000000 - 0x800000000

    2. chosen
/ {
 ...
 chosen {
  bootargs = "内核启动参数";    // 必选
  linux,stdout-path= "console"  // 可选
 };
 ...
};

    3. 设备
标号: 设备类型@地址 {           // 设备名字, 基本名通常为设备类型, 扩展名通常为设备在总线上的地址
 name = "设备(总线)类型";       // 可选,name属性值必须和基本名一致
 device_type = "芯片名";       // 可选,设备采用芯片名
 compatible = "兼容芯片1", "兼容产品2";     // 必选, 用于匹配驱动

 // io内存(寄存器)地址
 #address-cells = <A>;           // 可选, 同"根和内存"相同名称属性
 #size-cells = <S>;               // 可选, 同"根和内存"相同名称属性
 reg = <地址(端口号) 大小 ... ...>; // 可选, 同"根和内存"相同名称属性

 // 中断(详细参考Documentation/devicetree/bindings/interrupt-controller/interrupts.txt内核文档)
 // 只有一个中断父设备(必选)
 interrupt-parent = <&父设备标号>;
 interrupts = <irqno trigger>, <... ...>;

 // 有多个中断父设备(必选)
 interrupts-extended = <&父设备标号 irqno trigger>, <... ... ...>;

};

       (1) 设备和驱动匹配
           1. 匹配设备树上的设备
              驱动               设备树          条件
              compatible         compatible      必须
              type               device_type     驱动存在type属性
              name               name            驱动存在name
             
           2. 匹配代码添加的设备
              驱动               设备             条件
              name               name             必须
             
       (2) 设备(非中断控制器)中断
           interrupt-parent
           interrupts
           和
           interrupts-extended
           只允许出现一次
           
           1. irqno
              父设备(中断控制器)中的中断编号
             
           2. trigger
              促发条件,目前只用到32bit中的[0:3]bit
              1 = low-to-high edge triggered
              2 = high-to-low edge triggered
              4 = active high level-sensitive
              8 = active low level-sensitive            
           
    4. 中断控制器
标号: 设备类型@地址 {
 ...
 interrupt-controller; // 必选
 interrupt-parent = <&父设备标号>; // 必选

 #interrupt-cells = <1>; // 必选
 interrupts = <irqno>, <...>; // 必选
 或
 #interrupt-cells = <2>; // 必选
 interrupts = <irqno trigger>, <... ...>; // 必选
 ...
};

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demon-HY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值