裝置樹詳解

2021-08-04 08:24:17 字數 2982 閱讀 5814

在linux3.x版本後,arch/arm/plat-***和arch/arm/mach-***中,描述板級細節的**(比如platform_device、i2c_board_info等)被大量取消,取而代之的是裝置樹,其目錄位於arch/arm/boot/dts

1個dts檔案+n個dtsi檔案,它們編譯而成的dtb檔案就是真正的裝置樹

imx6dl-hummingboard.dts

|_imx6dl.dtsi

| |_imx6qdl.dtsi

|_imx6qdl-microsom.dtsi

|_imx6qdl-microsom-ar8035.dtsi

下面分別是是imx6dl-hummingboard.dts以及imx6dl.dtsi檔案,我們以它們為例來分析,不難發現dts檔案內容很少,只有一些板級的特徵,大部分公共的硬體描述都在dtsi檔案中

/dts-v1

/;#include

"imx6dl.dtsi"

#include

"imx6qdl-microsom.dtsi"

#include

"imx6qdl-microsom-ar8035.dtsi"

/ ; regulators ;

}&i2c1 ;

};

/ 

soc ;

aips-bus@02000000 ;

/*省略無關***/

i2c1: i2c@021a0000 ;

};/*省略無關***/

};

};

標號引用常常還作為節點的重寫方式,比如下面**是imx6qdl.dtsi中定義的i2c節點,而前面imx6dl-hummingboard.dts中的&i2c1,就是對i2c1標號處節點的一次重寫,在其內部新增了乙個rtc裝置

如果乙個節點是屬性節點(即僅僅是作為屬性被其他節點呼叫),那麼它定義在**其實無所謂,重要的是呼叫的位置,比如lcd螢幕的時序,其實我們完全可以把它定義在其他犄角旮旯,然後在lcd節點下用&來呼叫它,這也是可以的。這有點類似於函式:在哪定義不重要,重要的是在哪呼叫

首先,核心必須要知道dtb檔案的位址,這由u-boot來告訴核心,詳見u-boot引導核心流程分析 第6節。只要核心知曉了dtb檔案的位址,那麼驅動就可以通過一些api任意獲取裝置樹的內部資訊

/*定義的of_match_table*/

static const struct of_device_id pcf8523_of_match = ,

};/*driver 結構體中的of_match_table*/

static struct i2c_driver pcf8523_driver = ,

.probe = pcf8523_probe,

.id_table = pcf8523_id,

};

當修改或編寫驅動時,常常需要修改gpio、時鐘、中斷等等引數,以前都是在mach-***中的device設定的,現在則要在節點裡設定,然後驅動用特殊的api來獲取

/*imx6dl.dtsi中gpio1控制器的定義節點*/

gpio1: gpio@0209c000 ;

/*imx6qdl-sabreauto.dtsi中某個裝置節點*/

max7310_reset: max7310-reset ;9

gpio = of_get_named_gpio(node, "reset-gpios", index);

gpio = of_get_gpio(node, index);
假設某裝置節點需要乙個gpio中斷

/*先確定中斷所在的組*/

interrupt-parent = <&gpio6>;

/*表示中斷,gpio6中的第8個io,2為觸發型別,下降沿觸發*/

interrupts = <8

2>;而在驅動中使用中斷號 =irq_of_parse_and_map(node, index)函式返回值來得到中斷號

所謂的自定義屬性,有點類似於老核心中的platform_data,我們在裝置節點中可以隨意新增自定義屬性,比如下面這個節點裡面的屬性都是我們自己定義的

reg_3p3v: 3p3v ;
of_property_read_u32(node, "regulator-min-microvolt", µvolt);
int of_property_read_u8(const

struct device_node *np, const

char *propname, u8 *out_value)

int of_property_read_u16(const

struct device_node *np, const

char *propname, u16 *out_value)

bool of_property_read_bool(const

struct device_node *np, const

char *propname)

of_property_read_string(node, "regulator-name", &string)
/*帶有陣列的某個節點*/

l2: cache

-controller@1e00a000 ;

/*驅動中使用api來讀取陣列, &data為輸出型引數*/

of_property_read_u32_array(node, "arm,pl310-cache", &

data, array_size(data));

裝置樹詳解

在linux3.x版本後,arch arm plat 和arch arm mach 中,描述板級細節的 比如platform device i2c board info等 被大量取消,取而代之的是裝置樹,其目錄位於arch arm boot dts 1個dts檔案 n個dtsi檔案,它們編譯而成的d...

裝置樹詳解

在linux3.x版本後,arch arm plat 和arch arm mach 中,描述板級細節的 比如platform device i2c board info等 被大量取消,取而代之的是裝置樹,其目錄位於arch arm boot dts 1個dts檔案 n個dtsi檔案,它們編譯而成的d...

裝置樹詳解

在linux3.x版本後,arch arm plat 和arch arm mach 中,描述板級細節的 比如platform device i2c board info等 被大量取消,取而代之的是裝置樹,其目錄位於arch arm boot dts 1個dts檔案 n個dtsi檔案,它們編譯而成的d...