一:裝置樹的簡單概念
裝置樹:由一系列的節點,屬性組成,節點本身包含子節點(屬性:成對出現的名稱和值)
裝置樹可描述的資訊:(原先大多數被編碼在核心中)
它是電路板上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...