天天看點

聊聊Beaglebone Black的cape和device tree overlay和dtc指令【轉】

本文是我早期寫的,語言略混亂。請直接看我最新整理的,适用于初學者的文章《使用BBB的device tree和cape(重新整理版)》

我們知道beagleboard官網上有一些官方的硬體外設,比如lcd顯示屏之類的,他們管這些外設叫做cape。其實這裡是我了解狹隘了,應該說隻要是修改了晶片引腳功能,或占用了空閑的引腳的東西,都可以叫做cape。比如之前我們提到的開啟某些引腳的AD轉換功能,其實也是給裝置添加了一個virtual cape。Beaglebone Black中用一個叫做capemgr的軟體管理所有的cape,不論它是實實在在的擴充闆,還是虛拟的cape。這個軟體的目錄是

/sys/devices/bone_capemgr.*/(這裡的*是一個每次系統啟動可能會不一樣的數字(與啟動順序有關))

如果你看過我的部落格,也許還會記得我們加載device tree overlay時打開了一個檔案,正是這個目錄下的slots檔案。slots檔案就是capemgr這個軟體的對外接口。slot這個單詞是“插槽”的意思,看,很形象吧!我要插上一個cape,就向這個“插槽”裡“插入”(echo)相應的裝置。echo這個指令的含義是“向标準裝置輸出”嘛。另外,.dtbo檔案隻有放到/lib/firmware目錄下才能被使用。

還記得我們第一次打開slots檔案看到了什麼嗎?

# cat /sys/devices/bone_capemgr.*/slots

0: 54:PF---

1: 55:PF---

2: 56:PF---

3: 57:PF---

4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G

5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI

這裡前4項為什麼是空的呢?它們是給那些有EEPROM的實體cape預留的位置。通過實體cape上的開關,可以達到我們用 echo something > $SLOTS 語句一樣的效果。不難看出,這樣的實體cape最多隻能插4個。

4和5這兩項則是系統已經加載的兩個virtual cape,因為eMMC和HDMI确實需要占用一些引腳,是以根據前面的定義,它們也是cape。

其實device tree overlay的作用之一是将裝置和驅動進行綁定(前提是驅動或驅動子產品已經存在于核心中),隻不過相比從前那種重新編譯核心的方式來說,這種方式實在太友善了。

12.18更新

關于cat $SLOTS

cat後顯示的内容中,左側的L字母代表是否加載。有時4、5這兩項依然存在,但沒有L字母,則也沒有加載這兩個cape。詳見我的日志《為BBB制作專屬自己的cape(二)》中的“系統存在Bug,運作時解除安裝cape會導緻kernel panic”一節。

關于dtc指令

參考我的日志《使用Beaglebone Black的PRU》前面寫到的“修改系統dtb檔案”這一部分操作可知:dtc指令雖然叫做“編譯”,但其作用主要隻是轉變一下資料存儲的格式,由人類可閱讀的dts轉成機器識别的dtb或dtbo或者反過來轉換。

實際上由dtb轉換成dts檔案後,跟初始dts檔案還是有不同的,從這個不同也能看出dts檔案中什麼内容是不重要的。以BBB自帶的BB-ADC-00A0.dtbo為例,我們看一下它轉換回dts檔案是什麼樣的。

root@beaglebone:~/tmp# dtc -I dtb -O dts BB-ADC-00A0.dtbo

/dts-v1/;

/ {

compatible = "ti,beaglebone", "ti,beaglebone-black";

part-number = "BB-ADC";

exclusive-use = "P9.39", "P9.40", "P9.37", "P9.38", "P9.33", "P9.36", "P9.35", "tscadc";

fragment@0 {

target = <0xdeadbeef>;

__overlay__ {

#address-cells = <0x1>;

#size-cells = <0x1>;

tscadc {

compatible = "ti,ti-tscadc";

reg = <0x44e0d000 0x1000>;

interrupt-parent = <0xdeadbeef>;

interrupts = <0x10>;

ti,hwmods = "adc_tsc";

status = "okay";

adc {

ti,adc-channels = <0x8>;

};

};

helper {

compatible = "bone-iio-helper";

vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";

vsense-scale = <0x1000 0x1000 0x1000 0x1000 0x1000 0x1000 0x1000 0x1000>;

linux,phandle = <0x1>;

phandle = <0x1>;

};

};

__symbols__ {

test_helper = "/fragment@0/__overlay__/helper";

__fixups__ {

ocp = "/fragment@0:target:0";

intc = "/fragment@0/__overlay__/tscadc:interrupt-parent:0";

};

BB-ADC-00A0.dts原文是這樣的

/*

* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License version 2 as

* published by the Free Software Foundation.

*/

/plugin/;

compatible = "ti,beaglebone", "ti,beaglebone-black";

/* identification */

part-number = "BB-ADC";

/* state the resources this cape uses */

exclusive-use =

/* the pin header uses */

"P9.39", /* AIN0 */

"P9.40", /* AIN1 */

"P9.37", /* AIN2 */

"P9.38", /* AIN3 */

"P9.33", /* AIN4 */

"P9.36", /* AIN5 */

"P9.35", /* AIN6 */

/* the hardware IP uses */

"tscadc";

fragment@0 {

target = <&ocp>;

__overlay__ {

/* avoid stupid warning */

#address-cells = <1>;

#size-cells = <1>;

tscadc {

compatible = "ti,ti-tscadc";

reg = <0x44e0d000 0x1000>;

interrupt-parent = <&intc>;

interrupts = <16>;

ti,hwmods = "adc_tsc";

status = "okay";

adc {

ti,adc-channels = <0 1 2 3 4 5 6 7>;

};

};

test_helper: helper {

compatible = "bone-iio-helper";

vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";

vsense-scale = <100 100 100 100 100 100 100 100>;

};

};

二者差別請自行比對。

當我想把dts檔案轉換成dtbo檔案時,出現了錯誤。

root@beaglebone:~/tmp# dtc -I dts -O dtb BB-ADC-00A0.dts

ERROR (phandle_references): Reference to non-existent node or label "ocp"

ERROR (phandle_references): Reference to non-existent node or label "intc"

ERROR: Input tree has errors, aborting (use -f to force output)

(加上 -f 也是沒有用的)但如果加上 -@ ,就可以順利輸出了。這就是device tree overlay和原生device tree的不同吧——device tree(比如/boot目錄裡那些dtb檔案反編譯出來的dts檔案)都是包含從根節點到每個子節點的全部資訊的。而device tree overlay(比如/lib/firmware目錄中的那些)隻需要包含要修改的内容即可。至于字尾名dtbo和dtb,似乎單純是為了區分二者,内容格式其實都是一樣的,都可以用dtc指令反編譯成dts檔案。

---------------------

作者:魏來之路

版權聲明:本文為部落客原創文章,轉載請附上博文連結!