《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 可編程邏輯 > 其他 > Linux教學(xué)——Linux設(shè)備樹基礎(chǔ)知識(shí)

Linux教學(xué)——Linux設(shè)備樹基礎(chǔ)知識(shí)

2022-08-24
作者:土豆居士 一口Linux
來源:電子技術(shù)應(yīng)用專欄作家 一口Linux
關(guān)鍵詞: Linux 設(shè)備樹

  在platform_device部分有簡單說明描述設(shè)備有兩種方法:一種是使用platform_device結(jié)構(gòu)體來指定;另一種是使用設(shè)備樹來描述。

  本篇筆記我們就來簡單地學(xué)習(xí)一下設(shè)備樹的一些知識(shí)。

  什么是設(shè)備樹

  微信圖片_20220824160553.png

  設(shè)備樹簡單理解就是描述設(shè)備信息(資源)的一棵樹。設(shè)備樹(Device Tree)用代碼體現(xiàn)如下:

  微信圖片_20220824160653.png

  這些代碼被保存在.dts/dtsi后綴文件中,也即設(shè)備樹源文件 DTS(DeviceTree Source)。

  這些源文件同我們的C代碼一樣,并不能直接使用的,而是得經(jīng)過一個(gè)編譯過程生成機(jī)器可運(yùn)行的二進(jìn)制文件,如:

  微信圖片_20220824160919.png

  dts文件使用dtc工具編譯生成dtb文件,這個(gè)dtb文件就是內(nèi)核可以使用的文件。例如我們的板子跑起來之后,我們系統(tǒng)使用的設(shè)備樹文件就存在目錄/boot下:

  微信圖片_20220824160931.png

  Linux為什么會(huì)引入設(shè)備樹?

  在上一個(gè)實(shí)驗(yàn):【Linux筆記】LED驅(qū)動(dòng)實(shí)驗(yàn)(總線設(shè)備驅(qū)動(dòng)模型)中我們使用了platform_device結(jié)構(gòu)體來描述led設(shè)備(硬件資源)。既然已經(jīng)有了描述設(shè)備的方法了,為什么還要引入設(shè)備樹呢?

  因?yàn)長inux內(nèi)核中有很多BSP(板級(jí)支持包),不同的BSP會(huì)包含著不同的描述設(shè)備的代碼(.c或.h文件)。

  隨著芯片的發(fā)展,Linux內(nèi)核中就包含著越來越多這些描述設(shè)備的代碼,導(dǎo)致Linux內(nèi)核代碼會(huì)很臃腫。

  這導(dǎo)致Linux之父Linus 大發(fā)雷霆:"this whole ARM thing is a f*cking pain in the ass"。

  因此引入了設(shè)備樹文件,從而可精簡一些臃腫的C代碼。除此之外,.dts編譯生成.dtb文件的過程要比.c編譯生成驅(qū)動(dòng)模塊、加載驅(qū)動(dòng)模塊的過程要簡單很多,也更方便我們進(jìn)行開發(fā)。

  設(shè)備樹的語法

  設(shè)備樹源文件也是需要根據(jù)一定規(guī)則來編寫的,同C語言一樣,也要遵循一些語法規(guī)則。下面簡單看一下設(shè)備樹的源碼結(jié)構(gòu)及語法。

  先看一個(gè)設(shè)備樹示例:

  微信圖片_20220824160948.png

  1、節(jié)點(diǎn)格式

  label: node-name@unit-address

  其中:

  label:標(biāo)號(hào)

  node-name:節(jié)點(diǎn)名字

  unit-address:單元地址

  label 是標(biāo)號(hào),可以省略。label 的作用是為了方便地引用 node。比如:

  微信圖片_20220824161014.png

  可以使用下面 2 種方法來修改 uart@fe001000 這個(gè) node:

  微信圖片_20220824161033.png

  2、屬性格式

  簡單地說, properties 就是“name=value”, value 有多種取值方式。示例:

  一個(gè)32位的數(shù)據(jù),用尖括號(hào)包圍起來,如

  interrupts = <17 0xc>;

  一個(gè)64位數(shù)據(jù)(使用2個(gè)32位數(shù)據(jù)表示),用尖括號(hào)包圍起來,如:

  clock-frequency = <0x00000001 0x00000000>;

  有結(jié)束符的字符串,用雙引號(hào)包圍起來,如:

  compatible = "simple-bus";

  字節(jié)序列,用中括號(hào)包圍起來,如:

  local-mac-address = [00 00 12 34 56 78]; // 每個(gè)byte使用2個(gè)16進(jìn)制數(shù)來表示

  local-mac-address = [000012345678];      // 每個(gè)byte使用2個(gè)16進(jìn)制數(shù)來表示

  可以是各種值的組合,用逗號(hào)隔開,如:

  compatible = "ns16550", "ns8250";

  example = <0xf00f0000 19>, "a strange property format";

  3、一些標(biāo)準(zhǔn)屬性

  (1) compatible 屬性

  “compatible”表示“兼容”,對(duì)于某個(gè)LED,內(nèi)核中可能有A、B、C三個(gè)驅(qū)動(dòng)都支持它,那可以這樣寫:

  led {

  compatible = “A”, “B”, “C”;

  };

  內(nèi)核啟動(dòng)時(shí),就會(huì)為這個(gè)LED按這樣的優(yōu)先順序?yàn)樗业津?qū)動(dòng)程序:A、B、C。

  (2)model 屬性

  model屬性與compatible屬性有些類似,但是有差別。compatible屬性是一個(gè)字符串列表,表示可以你的硬件兼容A、B、C等驅(qū)動(dòng);model用來準(zhǔn)確地定義這個(gè)硬件是什么。

  比如根節(jié)點(diǎn)中可以這樣寫:

  / {

  compatible = "samsung,smdk2440", "samsung,mini2440";

  model = "jz2440_v3";

  };

  它表示這個(gè)單板,可以兼容內(nèi)核中的“smdk2440”,也兼容“mini2440”。

  從compatible屬性中可以知道它兼容哪些板,但是它到底是什么板?用model屬性來明確。

  (3)status 屬性

  status 屬性看名字就知道是和設(shè)備狀態(tài)有關(guān)的, status 屬性值也是字符串,字符串是設(shè)備的狀態(tài)信息,可選的狀態(tài)如下所示:

  微信圖片_20220824161158.png

  (4)#address-cells 和#size-cells 屬性

  格式:

  address-cells:address要用多少個(gè)32位數(shù)來表示;

  size-cells:size要用多少個(gè)32位數(shù)來表示。

  比如一段內(nèi)存,怎么描述它的起始地址和大小?

  下例中,address-cells為1,所以reg中用1個(gè)數(shù)來表示地址,即用0x80000000來表示地址;size-cells為1,所以reg中用1個(gè)數(shù)來表示大小,即用0x20000000表示大小:

  / {

  # address-cells = <1>;

  # size-cells = <1>;

  memory {

  reg = <0x80000000 0x20000000>;

  };

  };

  (5)reg 屬性

  reg屬性的值,是一系列的“address size”,用多少個(gè)32位的數(shù)來表示address和size,由其父節(jié)點(diǎn)的# address-cells、#size-cells決定。示例:

  /dts-v1/;

  / {

  # address-cells = <1>;

  # size-cells = <1>;

  memory {

  reg = <0x80000000 0x20000000>;

  };

  };

  (7)name 屬性

  過時(shí)了,建議不用。它的值是字符串,用來表示節(jié)點(diǎn)的名字。在跟platform_driver匹配時(shí),優(yōu)先級(jí)最低。compatible屬性在匹配過程中,優(yōu)先級(jí)最高。

  (8)device_type 屬性

  過時(shí)了,建議不用。它的值是字符串,用來表示節(jié)點(diǎn)的類型。在跟platform_driver匹配時(shí),優(yōu)先級(jí)為中。compatible屬性在匹配過程中,優(yōu)先級(jí)最高。

  3、常用的節(jié)點(diǎn)

  (1)根節(jié)點(diǎn)

  用 / 標(biāo)識(shí)根節(jié)點(diǎn),如:

  /dts-v1/;

  / {

  model = "SMDK24440";

  compatible = "samsung,smdk2440";

  # address-cells = <1>;

  # size-cells = <1>;

  };

  (2)CPU節(jié)點(diǎn)

  一般不需要我們?cè)O(shè)置,在 dtsi 文件中都定義好了,如:

  cpus {

  # address-cells = <1>;

  # size-cells = <0>;

  cpu0: cpu@0 {

  .......

  }

  };

  (3)memory 節(jié)點(diǎn)

  芯片廠家不可能事先確定你的板子使用多大的內(nèi)存,所以 memory 節(jié)點(diǎn)需要板廠設(shè)置,比如:

  memory {

  reg = <0x80000000 0x20000000>;

  };

  (4)chosen 節(jié)點(diǎn)

  我們可以通過設(shè)備樹文件給內(nèi)核傳入一些參數(shù),這要在chosen節(jié)點(diǎn)中設(shè)置bootargs屬性:

  chosen {

  bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";

  };

  操作設(shè)備樹的函數(shù)

  Linux 內(nèi)核給我們提供了一系列的函數(shù)來獲取設(shè)備樹中的節(jié)點(diǎn)或者屬性信息,這一系列的函數(shù)都有一個(gè)統(tǒng)一的前綴“of_”(“open firmware”即開放固件。),所以在很多資料里面也被叫做 OF 函數(shù)。

  1、節(jié)點(diǎn)相關(guān)操作函數(shù)

  Linux 內(nèi)核使用 device_node 結(jié)構(gòu)體來描述一個(gè)節(jié)點(diǎn),此結(jié)構(gòu)體定義在文件 include/linux/of.h 中,定義如下:

  微信圖片_20220824161351.png

  與查找節(jié)點(diǎn)有關(guān)的 OF 函數(shù)有 5 個(gè):

  (1) of_find_node_by_name 函數(shù)

  of_find_node_by_name 函數(shù)通過節(jié)點(diǎn)名字查找指定的節(jié)點(diǎn),函數(shù)原型如下:

  struct device_node *of_find_node_by_name(struct device_node *from,

  const char *name);

  (2) of_find_node_by_type 函數(shù)

  of_find_node_by_type 函數(shù)通過 device_type 屬性查找指定的節(jié)點(diǎn),函數(shù)原型如下:

  struct device_node *of_find_node_by_type(struct device_node *from, const char *type);

  (3) of_find_compatible_node 函數(shù)

  of_find_compatible_node 函數(shù)根據(jù) device_type 和 compatible 這兩個(gè)屬性查找指定的節(jié)點(diǎn),函數(shù)原型如下:

  struct device_node *of_find_compatible_node(struct device_node *from,const char *type,

  const char *compatible);

  (4)of_find_matching_node_and_match 函數(shù)

  of_find_matching_node_and_match 函數(shù)通過 of_device_id 匹配表來查找指定的節(jié)點(diǎn),函數(shù)原型如下:

  struct device_node *of_find_matching_node_and_match(struct device_node *from,const struct of_device_id *matches,const struct of_device_id **match);

  (5)of_find_node_by_path 函數(shù)

  of_find_node_by_path 函數(shù)通過路徑來查找指定的節(jié)點(diǎn),函數(shù)原型如下:

  inline struct device_node *of_find_node_by_path(const char *path);

  2、提取屬性值的 OF 函數(shù)

  Linux 內(nèi)核中使用結(jié)構(gòu)體 property 表示屬性,此結(jié)構(gòu)體同樣定義在文件 include/linux/of.h 中,內(nèi)容如下:

  微信圖片_20220824161416.png

  Linux 內(nèi)核也提供了提取屬性值的 OF 函數(shù) :

  (1) of_find_property 函數(shù)

  of_find_property 函數(shù)用于查找指定的屬性,函數(shù)原型如下:

  property *of_find_property(const struct device_node *np,const char *name,int *lenp);

  (2)of_property_count_elems_of_size 函數(shù)

  of_property_count_elems_of_size 函數(shù)用于獲取屬性中元素的數(shù)量,比如 reg 屬性值是一個(gè)數(shù)組,那么使用此函數(shù)可以獲取到這個(gè)數(shù)組的大小,此函數(shù)原型如下:

  int of_property_count_elems_of_size(const struct device_node *np,const char *propname,int elem_size);

  (3)讀取 u8、 u16、 u32 和 u64 類型的數(shù)組數(shù)據(jù)

  微信圖片_20220824161433.png

  (4)讀取 u8、 u16、 u32 和 u64 類型屬性值

  微信圖片_20220824161451.png

  (5)of_property_read_string 函數(shù)

  of_property_read_string 函數(shù)用于讀取屬性中字符串值,函數(shù)原型如下:

  int of_property_read_string(struct device_node *np,const char *propname,const char **out_string)

  

 更多信息可以來這里獲取==>>電子技術(shù)應(yīng)用-AET<<

微信圖片_20210517164139.jpg

微信圖片_20220701092006.jpg

電子技術(shù)應(yīng)用專欄作家  一口Linux

原文鏈接:https://mp.weixin.qq.com/s/BI23d71SJkYPHnzQbFyvpQ

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請(qǐng)及時(shí)通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
久久午夜电影网| 国产免费成人在线视频| 午夜亚洲视频| 亚洲最新在线视频| 亚洲区第一页| 亚洲国产三级| 亚洲欧洲日韩女同| 亚洲激情av| 亚洲国产日韩美| 亚洲国产婷婷| 亚洲精品乱码久久久久久黑人| 欧美中文在线观看国产| 欧美亚洲一区二区在线| 亚洲欧美日韩视频二区| 亚洲影院免费| 欧美一区二区三区婷婷月色| 亚洲免费视频一区二区| 亚洲一区黄色| 亚洲欧美另类综合偷拍| 亚洲免费中文| 欧美在线播放| 欧美一区激情视频在线观看| 欧美一区综合| 亚洲国产精品成人综合色在线婷婷 | 一区二区在线观看av| 伊人精品成人久久综合软件| 狠狠v欧美v日韩v亚洲ⅴ| 一色屋精品视频在线看| 亚洲福利国产精品| 亚洲精品视频免费| 亚洲香蕉网站| 久久国产福利国产秒拍| 亚洲第一黄色网| 99re热这里只有精品免费视频| 亚洲视频视频在线| 欧美一区=区| 久久先锋资源| 欧美日韩蜜桃| 国产欧美日韩激情| 亚洲二区三区四区| 99精品视频免费观看视频| 亚洲一区二区在线免费观看视频| 欧美一级成年大片在线观看| 久久国产精品第一页| 日韩视频在线免费观看| 亚洲欧美日韩国产成人| 久久久999精品免费| 欧美韩国一区| 国产乱码精品一区二区三| 在线日韩成人| 日韩午夜电影在线观看| 亚洲一区二区三区精品在线观看| 欧美一区二区视频97| 亚洲美女av电影| 午夜精品福利一区二区三区av| 久久成人一区| 欧美人与禽猛交乱配视频| 国产精品热久久久久夜色精品三区| 国产一区二区三区电影在线观看| 亚洲国产高清在线| 亚洲一区精品电影| 亚洲日本欧美天堂| 午夜欧美视频| 欧美黄在线观看| 国产视频精品网| 亚洲精品中文字| 欧美一区二区三区在线| 一本一本久久a久久精品综合麻豆| 久久国产精品一区二区三区| 欧美福利精品| 国产亚洲欧美一级| 99视频精品全部免费在线| 久久精品欧美| 亚洲欧美日韩在线高清直播| 免费日韩av片| 国产婷婷色一区二区三区| 亚洲七七久久综合桃花剧情介绍| 欧美亚洲综合网| 亚洲婷婷综合久久一本伊一区| 久久综合福利| 国产精品私人影院| 亚洲欧洲综合另类在线| 久久精品国产综合精品| 亚洲欧美中日韩| 欧美伦理91| 在线观看成人av| 午夜久久久久久| 亚洲免费在线观看视频| 欧美精品二区| 伊人蜜桃色噜噜激情综合| 亚洲一区www| 亚洲视频视频在线| 欧美黄色成人网| 黄色综合网站| 先锋影音久久| 欧美一级视频免费在线观看| 欧美日韩精品一区二区三区四区 | 欧美日韩精品一区二区天天拍小说 | 亚洲最新视频在线| 亚洲乱码国产乱码精品精可以看| 久久精品亚洲一区| 国产精品一区免费观看| 在线亚洲激情| 亚洲视频综合| 欧美精品一区视频| 在线精品亚洲| 亚洲国产美女精品久久久久∴| 久久精品最新地址| 国产日韩精品在线观看| 亚洲在线视频网站| 亚洲一区亚洲| 欧美午夜精品一区| 日韩一区二区福利| 制服丝袜亚洲播放| 欧美激情欧美狂野欧美精品| 亚洲电影中文字幕| 亚洲欧洲在线看| 免费不卡亚洲欧美| 亚洲福利视频一区二区| 亚洲国产精品第一区二区| 久久久人人人| 狠狠色综合网| 久久黄色小说| 亚洲第一免费播放区| 亚洲精品国产无天堂网2021| 国产区亚洲区欧美区| 亚洲在线观看免费视频| 亚洲欧美日韩视频二区| 欧美视频日韩| 亚洲视频精品在线| 亚洲欧美日韩国产一区二区三区| 欧美视频福利| 这里只有精品丝袜| 销魂美女一区二区三区视频在线| 国产精品欧美一区二区三区奶水 | 在线视频你懂得一区二区三区| 宅男噜噜噜66一区二区 | 亚洲美女av网站| 亚洲视频在线观看| 国产精品毛片| 欧美在线高清| 久久综合色88| 亚洲国产一区二区视频| 99在线热播精品免费| 欧美日韩精品一区二区天天拍小说| 一区二区三区欧美日韩| 午夜亚洲一区| 韩国欧美国产1区| 亚洲美女啪啪| 国产精品www色诱视频| 亚洲欧美日韩成人| 久久综合久色欧美综合狠狠| 亚洲人成网站在线播| 亚洲先锋成人| 国产免费观看久久| 亚洲欧洲一区二区三区在线观看| 欧美日韩国产首页在线观看| 亚洲婷婷免费| 久久在线视频| 日韩亚洲精品电影| 欧美在线播放一区| 在线观看日韩www视频免费| 日韩一区二区高清| 国产精品色在线| 亚洲福利视频网站| 欧美性开放视频| 久久激情一区| 欧美日韩免费观看一区二区三区 | 99成人精品| 国产欧美日本| 亚洲精品国产精品国产自| 欧美性一二三区| 欧美在线不卡| 欧美日一区二区在线观看| 欧美亚洲在线视频| 欧美日韩第一页| 欧美亚洲三区| 欧美日韩99| 欧美综合国产精品久久丁香| 欧美日韩 国产精品| 欧美综合国产| 国产精品理论片在线观看| 亚洲电影免费观看高清完整版在线观看| 欧美激情综合五月色丁香小说| 亚洲欧美综合网| 欧美理论在线| 亚洲第一福利视频| 国产精品亚洲综合一区在线观看| 亚洲国产日日夜夜| 国产欧美综合一区二区三区| 99精品视频免费观看视频| 国产一区二区在线观看免费| 中文久久乱码一区二区| 悠悠资源网亚洲青| 欧美亚洲一区二区在线观看| 亚洲观看高清完整版在线观看| 先锋影音久久| 日韩一区二区福利| 欧美黄网免费在线观看| 久久国产日韩|