ARM Linux 設備樹基本知識

關於Linux 設備樹

##0. DTS、DTC和DTB
  ① DTS,位於arch/arm/boot/dts/
  ② DTC,將.dts編譯爲.dtb的工具,源碼位於scripts/dtc/
  ③ DTB (Device Tree Big large object),.dts的被DTC編譯後得二進制文件。

##1. 兼容屬性

/*					  具體     -->      抽象	*/
compatible = "manufacturer, model", "manufacturer2,model2"... ;
  • 用於板與DT_MACHINE_START 或者 設備與驅動 的匹配。

##2. 設備節點命名

/*設備類型@內存基地址或總線地址
   |        |                 */
<name>[@<unit_addr>] { 
	...
};
  • "< >"表示必須有; "[ ]"表示可選;

##3. label命名

<設備類型><index> :
  • 其他節點通過&label來訪問該節點,進行引用或者修改屬性的值

  • "< >"表示必須有;

##4. 地址編碼

reg = <addr_1 len_1 addr_2 len_2 ...>;
/*		 |      |_______________
		 |                     |
父節點#address-cells=<n> 和  #size-cells=<n>  決定其單元數 */

子 —> 父地址轉換表:ranges = <child_addr parent_addr map_len
							child_addr1 parent_addr1 map_len1
							... >;

##5. 中斷連接

  ① 中斷控制器:

interrupt-controller;   /* 表明身份 */
#interrupt-cells = <n>; /* 指示連接此中斷控制器之設備的中斷屬性cells個數 */  

  ② 開啓中斷的設備:

interrupt-parent = <&int_ctrl_label>; 	/* 指示所依附的中斷控制器 */
interrupt = < x ... >, <y ... >;	/* 中斷控制器#interrupt-cells決定cell個數,逗號隔開多箇中斷號 */
interrupt-name = "x_name","y_name", ... ;	 /* 給特定中斷號起名 */
  • index獲取中斷號:int platform_get_irq(struct platform_device *dev, unsigned int num);
  • 中斷名獲得中斷號:int platform_get_irq_byname(struct platform_device *dev, const char *name);

##6. GPIO、時鐘、pinmux的連接
###6.1 GPIO
  ① GPIO控制器:

gpio-controller;   /* 表明身份 */
#gpio-cells = <n>; /* 連接此GPIO控制器之設備的xxx-gpios屬性cells個數 */  

  ② 使用GPIO的設備:

xxx-gpios = <&ctrl_label n ...>; /* 所依附的gpio控制器之#gpio-cells決定cells個數 */
  • 使用xxx-gpios獲得gpio口:static inline int of_get_named_gpio(struct device_node *np, const char *propname, int index)
  • 設備只有一個gpio屬性時,不關心GPIO名字獲得gpio口:static inline int of_get_gpio(struct device_node *np, int index)

###6.2 時鐘
  ① 外部時鐘

clock-frequency = <n>;		/* 表明外部時鐘之頻率 */
clock-output-names = "xxx";	/* 外部時鐘導出名字到設備驅動 */
#clock-cells = <0>;			/* 規定引用此節點之設備的clocks屬性的cells個數 */

  ② 時鐘控制器

clocks: clock-controller@n {
	...
	clock-names = "xxx", "yyy"; /* 定義屬性clocks中時鐘之名 */
	clocks = <&xxx>, <&yyy>;    /* 引用外部時鐘節點定義屬性clocks */
	#clock-cells = <n>;         /* 規定引用此節點之設備的clocks屬性的cells個數 */
	...
};

  ③ 使用時鐘的設備

/*		長度爲時鐘控制器#clock-cells
				  +--^--+            */
clocks = <&clocks n1 ...>, <&clocks n2 ...>, ...; /* 引用時鐘控制器節點來定義屬性clocks */
clock-names = "iii", "jjj", ...;	/* 定義屬性clocks中時鐘之名 */
  • clock-name定義的名字獲得時鐘:struct clk *clk_get(struct device *dev, const char *con_id)

###6.3 pinmux
  ① pinmux引腳羣

xxx: yyy {
	vendor_name,pins = "pin_name1", "pin_name2", ...;
	vendor_name,pin-function = <n>;   /* 引腳功能設置 */
	vendor_name,pin-pud = <n>;        /* 引腳支路電阻上下拉或不接設置 */
	vendor_name,pin-drv = <n>;        /* 引腳電流驅動能力等級設置 */
};

  ② 設備使用引腳羣

pinctrl-names = "default";
pinctrl-0 = <&xxx>;		/* 引用引腳羣xxx */

##參考文獻

  [1] 宋寶華. Linux設備驅動開發詳解[M].北京:機械工業出版社,2015

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章