linux裝置樹(裝置驅動)

2021-09-19 03:21:16 字數 4042 閱讀 5526

一:裝置樹的簡單概念

裝置樹:由一系列的節點,屬性組成,節點本身包含子節點(屬性:成對出現的名稱和值)

裝置樹可描述的資訊:(原先大多數被編碼在核心中)

它是電路板上cpu,匯流排,裝置組成的樹,bootloader會將這棵樹傳遞給核心,並根據它展開linux核心中的platform_device等裝置。裝置用到的記憶體,irq等資源,也被傳遞給核心,核心會將這些資源繫結給展開的相應的裝置。

.dts:asc2文字格式的裝置樹描述,,乙個.dts檔案對應乙個arm裝置。

「/」root節點,子節點,子節點下面又包含各種子節點,各節點包含各種屬性,

dtc是將.dts編譯為.dtb (.dtb二進位制格式的裝置樹描述檔案)。

2:bootloader支援裝置樹

uboot裝置v1.1.3以上版本,在config檔案中加入 #define config_of_libfdt(在uboot中可以從flash中將.dtb讀入記憶體中去)。

然後可以通過bootz kernel_addr_initrd_address dtb_address的命令來啟動核心,kernel_addr_initrd_address 核心映像位址dtb_address為initrd位址。

2:節點的相容屬性

int of_machine_is_compatible(const char *compat)//用該函式判斷根節點的相容性。

每個節點都有乙個相容屬性,用於驅動和裝置的繫結,列表中的字串表徵了節點代表的確切裝置,規則是驅動裝置id表中的compatible域的值(字串),和裝置樹中裝置節點中的compatible屬性值完全一致,則節點的內容是給驅動的。

使用裝置樹後,驅動需要與.dts中描述的裝置節點進行匹配,從而使驅動的probe函式執行,對於platform_device而言,需要新增乙個of匹配表。通過of_match_table新增匹配的.dts中的相關節點屬性

int *of_device_is_compatible(struct device_node *from,const char *type); //判斷裝置節點的相容屬性是否包含type制定的字串。

3:裝置節點以及label的命名

組織形式a10_hps_arm_a9_0: cpu@0x0  裝置節點型別 @裝置在記憶體空間的基位址。

4:位址編碼

#address-cells = <1>;描述子節點reg屬性值的位址表中首位址cell數量

#size-cells = <1>;描述子節點reg屬性值的位址表中位址長度cell數量

reg =

address和length是可變長度,父節點的address-cells 和size-cells分別決定的子節點reg屬性的address和length欄位的長度。(表示初始位址和初始位址的長度)。子節點中reg的值就是乙個首位址緊接著乙個位址長度為乙個單元。

描述乙個裝置的記憶體位址的時候,一般使用1個cell(32bits)描述位址,緊接著1個cell(32bits)描述位址長度。

對映中的子位址,父位址分別採用各自位址空間的address 。

5:中斷連線

interrupt-controller 乙個空屬性用來宣告這個node接收中斷訊號;

#interrupt-cells 這是中斷控制器節點的屬性,用來標識這個控制器需要幾個單位做中斷描述符;

interrupt-parent 標識此裝置節點屬於哪乙個中斷控制器,如果沒有設定這個屬性,會自動依附父節點的;

interrupts 乙個中斷識別符號列表,表示每乙個中斷輸出訊號。

a10_hps_arm_gic_0: intc@0xffffd000 ; //end intc@0xffffd000 (a10_hps_arm_gic_0)

interrupts = <0 18 4>;:裝置節點,中斷號,觸發方式,(有多少個cell,由它依附的中斷控制節點的 interrupt-cell屬性決定)。

通過platform_get_irq_byname()獲取相應的中斷號。

6:gpio,時鐘,pinmux連線

led_pio: gpio@0x100000010 ; //end gpio@0x100000010 (led_pio)

gpio-controller:說明該節點描述的是乙個gpio控制器

#gpio-cells:描述gpio使用節點的屬性乙個cell的內容

第乙個cell為gpio號,第二個為gpio極性,為0 高電平有效,為1 低電平有限。

屬性名=<&引用gpio節點別名gpio標號工作模式》;

通過of_get_gpio來獲取gpio。

時鐘:clocks = <&clk_0 &clk_0 &dp_0_video_pll 3 &clk_0>;

clock-names = "h2f_axi_clock", "h2f_lw_axi_clock", "f2sdram0_clock", "f2sdram2_clock";

pinmux:裝置節點使用的pinmux的引腳群是通過phandle來制定

7 :由裝置樹引發的bsp驅動變更

以前會從在大量的platform_device,現在platform_device的resource**不在需要,而現在這些resource實際**於.dts裝置中的reg,interrupts屬性。呼叫of_platform_bus_probe(null,***_of_bus_ids,null),即可展開platform_device。

使用裝置樹,驅動需要在.dts中描述的裝置節點進行匹配,新的驅動裝置的匹配變成了裝置節點的相容屬性和裝置驅動中的of匹配表的匹配。

在arch/arm/mach_***註冊platform_device,i2c_board_info,spi_board_info等的時候繫結platform_data,而後驅動通過api獲取平台資料

8 :常用的api函式(位於核心的driver/of目錄下)

1:尋找節點

struct device_node *of_find_compatible_node(struct device_node *from,

const char *type, const char *compat);  //遍歷裝置樹的裝置節點,檢視節點型別(通過compatible屬性查詢制定節點)

讀取屬性:

struct property *of_find_property(const struct device_node *np,

const char *name, int *lenp);//讀取制定屬性的值

int of_property_count_elems_of_size(const struct device_node *np,

const char *propname, int elem_size);//得到制定屬性值的數量

int of_property_read_u32_index(const struct device_node *np,

const char *propname, u32 index, u32 *out_value);//讀取屬性值中制定標號的32 為資料值

int of_property_read_string(struct device_node *np,

const char *propname, const char **out_string);//提取屬性值的字串。

__be32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags);//提取io口位址對映

void __iomem *of_iomap(struct device_node *np, int index);//提取io口位址並且轉化為細膩位址

void __iomem *of_io_request_and_map(struct device_node *np, int index, const char *name);//提取io口位址並且對映成虛擬位址

struct platform_device *of_find_device_by_node(struct device_node *from,

const char *type, const char *compat); //獲取對應節點的platform_device 。

linux驅動之裝置樹

裝置樹語法及內部構成 裝置樹實戰 裝置樹其實是乙個檔案,這個檔案包含很多的節點,這些節點是專用來描述裝置的資訊,包括cpu的資訊,gpio的資訊等。資訊裡面包括很多的屬性。屬性中包括各種值 value,這些 value 是傳遞給核心使用的。核心可以解析出這些檔案資訊,然後給程式設計師使用。dtb c...

驅動 linux裝置驅動 字元裝置驅動開發

preface 前面對linux裝置驅動的相應知識點進行了總結,現在進入實踐階段!linux 裝置驅動入門篇 linux 裝置驅動掃盲篇 fedora下的字元裝置驅動開發 開發乙個基本的字元裝置驅動 在linux核心驅動中,字元裝置是最基本的裝置驅動。字元裝置包括了裝置最基本的操作,如開啟裝置 關閉...

Linux裝置驅動之《字元裝置驅動》

linux裝置中最大的特點就是裝置操作猶如檔案操作一般,在應用層看來,硬體裝置只是乙個裝置檔案。應用程式可以像操作檔案一樣對硬體裝置進行操作,如open close read write 等。下面是乙個字元裝置驅動程式的簡單實現test.c 模組分析 1.初始化裝置驅動的結構體 struct fil...