<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 設計應用 > 設備樹(shù)使用簡(jiǎn)介

設備樹(shù)使用簡(jiǎn)介

作者: 時(shí)間:2019-11-01 來(lái)源:電子產(chǎn)品世界 收藏

是不是所有的Linux內核都是完美的?畢竟諸多黑客效力于此,當然不是,至少在內核3.x版本之前不是,之前的代碼臃腫,代碼利用率較低,直到設備樹(shù)的引入,徹底改善這一情況;

本文引用地址:http://dyxdggzs.com/article/201911/406597.htm

一、FDT的概念

系統啟動(dòng)時(shí),Bootloader開(kāi)始加載,將內核文件,如zImage讀取到內存中,內核按照我們的代碼,逐一去配置每個(gè)寄存器,每個(gè)外設,似乎沒(méi)有什么問(wèn)題。但是試想一下,100種ARM芯片,就要寫(xiě)100個(gè)配置文件么?當然,如果你非要這么做,我也無(wú)話(huà)可說(shuō)。如果能抽象出一種數據結構,它可以直接抽象出內核需要配置的所有硬件以及硬件屬性,BootLoader預讀取到內存中,在內核啟動(dòng)以后,可以直接配置,對于用戶(hù)而言,配置MCU的外圍時(shí)我們直接面對的就只是這個(gè)DTS文件,極其方便快捷。FDT準確來(lái)講是一種數據結構,使得硬件可以用形如XML的描述語(yǔ)言來(lái)描述。

二、設備樹(shù)結構

1572592103955617.png

圖一   設備樹(shù)結構

設備樹(shù)一般包含以上內容:

?  根節點(diǎn)“/”下的model ,這個(gè)一般為字符串類(lèi)型,它描述了廠(chǎng)商以及板子名稱(chēng);

?  根節點(diǎn)“/”下的compitable,這個(gè)一般為字符串類(lèi)型,用以匹配model選定的開(kāi)發(fā)板對應的代碼;包括后續外圍驅動(dòng)的匹配均是有這個(gè)compitable來(lái)完成;

? 根節點(diǎn)“/”下的aliases,這個(gè)設備節點(diǎn)只能放在根節點(diǎn)目錄,主要用以存放外設的別名,簡(jiǎn)單講,"/soc/aips-bus@02000000/spba-bus@02000000/serial@02020000"其實(shí)是一個(gè)串口,但是開(kāi)發(fā)人員自己看起來(lái)并不直觀(guān),我可以在aliases中寫(xiě)作:serial ="/soc/aips-bus@02000000/spba-bus@02000000/serial@02020000";serial即可代替剛才的串口設備;

? 根節點(diǎn)“/”下的chosen:這個(gè)并非物理設備節點(diǎn),而是內核啟動(dòng)參數的節點(diǎn),類(lèi)似于uboot階段的bootargs參數;

當然,這個(gè)節點(diǎn)也可以是子節點(diǎn),不一定要在根節點(diǎn)下;

實(shí)例:chosen {

        stdout-path = &uart1;

    };

? snvs@020b0000:除以上節點(diǎn),剩下的我一般稱(chēng)之為物理設備節點(diǎn)(可能不準確),以snvs外設舉例,直接舉例;

實(shí)例:snvs@020b0000{

        conpitable = “fsl,imx6ul-snvs”;

        reg = <0x020b0000 0x4000>;

        interrupts = <0x0 0x4 0x4>;

};

(1)“@”后面緊跟就是該外設在MCU總線(xiàn)的地址,這個(gè)不難理解,可以理解為外設的基地址,外設模型 name@addresss;”

(2)“compitable”:如上陳述,非常關(guān)鍵的屬性,匹配外設驅動(dòng),屬性模型 compitable = “[manufacture,[model]]”;

(3)“reg”:該屬性為外設地址屬性,第一個(gè)參數為該節點(diǎn)總線(xiàn)地址,后者為地址長(cháng)度;

(4)“interrupt”:顧名思義,該外設的中斷,para1表示該中斷是不是SPI中斷(shared peripheral interrupt),注意名詞區分,參數值為1表示為SPI中斷,反之不是SPI中斷;para2是該中斷號;para3表示觸發(fā)方式,參數值為1,表示上升沿觸發(fā),為4表示高電平觸發(fā);如果需要低電平以及下降沿觸發(fā),硬件需要加非門(mén);

三、編譯設備樹(shù)與反編譯

設備樹(shù)編譯,我們都知道使用如下命令編譯:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-  dtbs  或者

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-  all

實(shí)際上,是dtc這個(gè)文件在負責把dts解釋成dtb文件,該文件在內核源碼根目錄 ./scripts/dtc

編譯命令:

./scripts/dtc/dtc –I dts –O dtb /home/gyh/tmp/imx6y2c-256m.dtb  ./arch/arm/boot/dts/imx6y2c-256m.dts

反編譯命令:

./scripts/dtc/dtc -I dtb -O dts -o /home/gyh/tmp/imx6y2c_asm.dts   ./arch/arm/boot/dts/imx6y2c-256m.dtb

對于Linux命令的使用,可以使用help cmdname 或者man cmdname,對于dtc,非內建命令,man dtc:

  -I <input format>

              Input formats are:

              dts - device tree source text

              dtb - device tree blob

              fs - /proc/device-tree style directory

  -O <output format>

              Output formats are:

              dts - device tree source text

              dtb - device tree blob

              asm - assembler source

系統提供的dts一般引用dtsi這個(gè)母設備樹(shù),所以大量外設都是直接引用dtsi中的,因此很難理解這些字符串是怎樣的匹配驅動(dòng)程序的,但是一旦將已經(jīng)生產(chǎn)的dtb文件反編譯,生產(chǎn)的dts文件將更直觀(guān);但是易讀性也更差。這并不矛盾;我選擇,” /”  ,”chosen” ,”aliases”三個(gè)節點(diǎn)來(lái)對比。

1572592152886254.png

圖二   BSP提供的dts文件

1572592212446420.png

圖三   反編譯的dts文件

對同一個(gè)chosen節點(diǎn):BSP中dts描述為stdout-path = &uart1;這樣很難想象它是怎樣把該外設定義為標準輸出的,但是如果看反編譯文件可以較好的理解,標準輸出被重定向到某個(gè)可以作為輸出的外設地址;

四、設備樹(shù)節點(diǎn)添加與驗證

       (1)直接在dts文件中查找,是否已經(jīng)存在你需要的外設節點(diǎn);如果有,且該外設支持多從機或者多節點(diǎn),直接在該節點(diǎn)下面,添加子節點(diǎn),以GPIO_LED為例。

1572592258543042.png

圖四   GPIO_LEDS節點(diǎn)

(2)假設,你需要添加一個(gè)黃色的LED,那么仿照已經(jīng)存在的節點(diǎn),復制一個(gè)節點(diǎn)在母節點(diǎn)下,命名為green-led,同時(shí)用GPIO3_4為該LED驅動(dòng)引腳;你希望在arm板上叫他,My_Cute(這個(gè)名字不好),那么最后修改如下:

1572592300358201.png

圖五  增加yellow-led節點(diǎn)

(3)節點(diǎn)添加完成,引用了GPIO3_4,所以你需要確認該MCU引腳已經(jīng)配置為GPIO功能,這里直接貼出配置代碼:MX6UL_PAD_LCD_RESET__GPIO3_IO04 0x40017059

1572592370218612.png

圖六  引腳配置為GPIO

該宏定義MX6UL_PAD_LCD_RESET__GPIO3_IO04在./arch/arm/boot/dts/imx6ull-pinfunc.h中;針對同一個(gè)引腳的全部復用,均定義了宏,可以直接調用;該dts并未直接包含imx6ull-pinfunc.h,在其他dtsi中已經(jīng)包含該頭文件;

(4)如果之前已經(jīng)完全編譯過(guò)內核,可以直接編譯dtb,注意不要make menuconfig或者defconfig,否則會(huì )覆蓋zImage的配置文件.config;

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-  dtbs

(5)編譯完成后,開(kāi)發(fā)板直接進(jìn)入uboot模式,tftp網(wǎng)絡(luò )燒寫(xiě)dtb,reset重啟生效;

run updtb

(備注:updtb為組合命令updtb=if tftp ${fdt_file}; then nand erase.part dtb; nand write ${loadaddr} dtb ${filesize}; fi;)

(6)如果dtb按照我們理解修改是正確的,那么我們將在開(kāi)發(fā)板的/sys/class/leds下面看到我們的My_Cute這個(gè)LED節點(diǎn);結果如下:

1572592395772004.png

圖七  開(kāi)發(fā)板設備截圖

其實(shí),可以看到/sys/class/leds下面的設備節點(diǎn)都是指向/devices/platfome/leds目錄的連接文件,也就是這里僅僅是這個(gè)設備的“快捷方式”,我們也可以進(jìn)行文件IO操作;

(7)文件IO操作:打開(kāi)My_Cute節點(diǎn),可以看到以下接口可以操作,但是我們在添加GPIO_LEDS并沒(méi)有添加這些屬性。Brightness, trigger—led亮度以及觸發(fā)方式比較常用,那么問(wèn)題來(lái)了,為什么會(huì )有這些接口。因為它們繼承了母節點(diǎn)的屬性,所以我們需要找到母節點(diǎn)設備的定義。

1572592434276435.png

圖八  yellow-led的操作接口

(8)講道理,所有的內核驅動(dòng)你都可以嘗試在 ./driver/下面去找,針對led類(lèi),我們直接進(jìn)入leds文件夾,發(fā)現leds的驅動(dòng)leds-gpio.c在,在這里就可以理解led的接口為什么是這樣;當然優(yōu)秀的驅動(dòng)應該還有一份清晰的文檔,你同樣可也嘗試去源碼根目錄的. /Documentation 中查找leds-gpio的使用文檔;這里也會(huì )解釋?zhuān)覟槭裁磿?huì )去開(kāi)發(fā)板的/sys/class/leds下面去查看我增加的My_Cute節點(diǎn);

1572592494338105.png

圖九  驅動(dòng)使用文檔

(9)增加一個(gè)驅動(dòng)或者一個(gè)設備節點(diǎn)到設備樹(shù)中,你可以先查看內核源碼的/ Documentation目錄,其中包含了幾乎所有驅動(dòng)的使用說(shuō)明以及設備樹(shù)屬性的解釋?zhuān)瑫r(shí)也包括大量?jì)?yōu)秀的內核調試技巧;再去寫(xiě)節點(diǎn),也可以先模仿,針對不懂的地方再來(lái)看文檔,印象更為深刻。

五、結語(yǔ)

設備樹(shù)相比于傳統的配置文件,無(wú)疑是降低了Linux外設開(kāi)發(fā)與使用的門(mén)檻,但是也隱藏了大量的細節,難以了解其底層的驅動(dòng)原理;對于LINUX內核的了解,我所認識的還不及冰山一角,單希望對你有一點(diǎn)幫助。



關(guān)鍵詞:

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>