只要你想用BBB做哪怕一丁點涉及到硬件的東西,你就不可避免地要用到cape和device tree的知識。所以盡管它們看起來很陌生而且有點復雜,但還是得學。其實用起來不難的。下面我只講使用時必須會的內容,不深究其工作原理。文中基本沒有廢話,請仔細閱讀每個字,勿遺漏細節。
我們已經知道beagleboard官網上有一些官方的硬件外設,比如lcd顯示屏之類的,他們管這些外設叫做cape。其實應該說只要是修改了芯片引腳功能,或占用了空閑的引腳的東西,都可以叫做cape。比如之前我們提到的開啟某些引腳的I2C功能,其實也是給設備添加了一個虛擬的(virtual)cape。當我們想要使用一個cape的時候,需要做兩件事:配置BBB引腳的功能,啟動相應的驅動程序。而device tree基本就是用來干這兩件事的。
下面我們就來依次認識device tree文件,修改dts文件,編譯dts文件,加載device tree,驗證是否加載成功。
一、認識device tree文件
那么device tree具體是長什么樣的呢?首先要知道它們有三種格式:一個方便人類閱讀的源文件*.dts(device tree source),另兩個是經過編譯送給系統使用的文件*.dtb(device tree blob)和*.dtbo(device tree blob overlay)。
在BBB的/lib/firmware/目錄下,你可以看到很多*.dts文件。我們隨便打開一個(BB-UART1-00A0.dts)看看它們長什么樣:
在BBB的/lib/firmware/目錄下,你可以看到很多*.dts文件。我們隨便打開一個(BB-UART1-00A0.dts)看看它們長什么樣:
- /*
- * Copyright (C) 2013 CircuitCo
- *
- * Virtual cape for UART1 on connector pins P9.24 P9.26
- *
- * 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.
- */
- /dts-v1/;
- /plugin/;
- / {
- compatible = "ti,beaglebone", "ti,beaglebone-black";
- /* identification */
- part-number = "BB-UART1";
- version = "00A0";
- /* state the resources this cape uses */
- exclusive-use =
- /* the pin header uses */
- "P9.24", /* uart1_txd */
- "P9.26", /* uart1_rxd */
- /* the hardware ip uses */
- "uart1";
- fragment@0 {
- target = <&am33xx_pinmux>;
- __overlay__ {
- bb_uart1_pins: pinmux_bb_uart1_pins {
- pinctrl-single,pins = <
- 0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
- 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
- >;
- };
- };
- };
- fragment@1 {
- target = <&uart2>; /* really uart1 */
- __overlay__ {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&bb_uart1_pins>;
- };
- };
- };
不要被dts文件復雜的外表嚇到!dts文件確實有一定的編寫規則,但是這不是我們要操心的。因為BBB已經提供了足夠多現成的dts文件,我們要做的就是: 1、看懂它們,2、學會復制和粘貼。
二、修改dts文件
我們的最終目的是寫出符合自己需求的dts文件,那么單單復制粘還是不夠的,我們有時候需要修改里面那些屬性的值。那么這些屬性都是什么含義呢?其實它們都是有據可循的:www.kernel.org/doc/Documentation/devicetree/bindings/ 。提示一點,文檔有點亂,請多用Ctrl+F。
前面說到dts里主要有兩部分內容:修改BBB引腳功能和啟動驅動程序。上面的網址里只告訴了驅動程序的屬性,那么 引腳功能該如何配置呢?
以前面給出的代碼為例,這幾行代碼是用來配置引腳功能的:
前面說到dts里主要有兩部分內容:修改BBB引腳功能和啟動驅動程序。上面的網址里只告訴了驅動程序的屬性,那么 引腳功能該如何配置呢?
以前面給出的代碼為例,這幾行代碼是用來配置引腳功能的:
- pinctrl-single,pins = <
- 0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
- 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
- >;
如何查看BBB當前的引腳功能呢?
- cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pins
一般這句后面還會加上grep命令來顯示特定的引腳功能,同樣在《BBB引腳功能速查表》中第三列找到P9.24的地址是0x984,所以可以這樣查找:
- root@beaglebone:~# cat $PINS | grep 984
- pin 97 (44e10984) 00000037 pinctrl-single
另外一個要注意的是每個dts里根節點下都有這兩個屬性:
- part-number = "BB-UART1";
- version = "00A0";
三、編譯dts文件
實際上,dts和dtbo文件可以隨時編譯和反編譯,即dts可以生成dtbo,dtbo也可以復原成dts(但是復原的dts里沒有注釋等無用的東西了)。編譯和反編譯使用的命令都是相同的:dtc(device tree compile)。
dts編譯成dtbo:
- dtc -I dts -O dtb -@ BB-UART1-00A0.dts > BB-UART1-00A0.dtbo
- dtc -I dtb -O dts BB-UART1-00A0.dtbo > BB-UART1-00A0.dts
四、加載dtbo文件
加載之前,一定記住要把編譯好的dtbo文件放到/lib/firmare/目錄中,否則程序是找不到你的dtbo文件的。
Beaglebone Black中用一個叫做cape manager的軟件管理所有的cape,不論它是實實在在的擴展板,還是虛擬的cape。這個軟件的目錄是
/sys/devices/bone_capemgr.8/(這里的數字也有可能是9,與啟動順序有關,你可以直接用*代替它)。這個目錄內有一個叫做slots的文件,這就是capemgr這個軟件的對外接口。我們要加載某個cape的話,只需要向這個文件中寫入dts文件里定義的名字(part-number屬性)即可:
Beaglebone Black中用一個叫做cape manager的軟件管理所有的cape,不論它是實實在在的擴展板,還是虛擬的cape。這個軟件的目錄是
/sys/devices/bone_capemgr.8/(這里的數字也有可能是9,與啟動順序有關,你可以直接用*代替它)。這個目錄內有一個叫做slots的文件,這就是capemgr這個軟件的對外接口。我們要加載某個cape的話,只需要向這個文件中寫入dts文件里定義的名字(part-number屬性)即可:
- echo BB-UART1 > /sys/devices/bone_capemgr.8/slots
(注:如果那個dtbo有多個版本,比如有00A0,00A1,00A2這3個版本,如果你只寫 echo BB-UART1 > $SLOTS 的話,它會自動加載最新的版本。而且,必須保證從00A0開始每個版本都存在才可以成功加載,就是說,如果/lib/firmware/目錄中只有00A2這一個版本的話,加載會失敗。但是,你可以通過 echo BB-UART1:00A2 > $SLOTS 像這樣添加版本號來加載某個特定版本。)
使用命令:
- cat $SLOTS
- root@beaglebone:~# cat $SLOTS
- 0: 54:P---L Beaglebone LCD4 Cape,00A1,BeagleboardToys,BB-BONE-LCD4-01
- 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
- 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-ADC
- 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART1
BBB可以插入4個實體cape,它們只能插在0、1、2、3這四個slot里,這也是1、2、3號slot是空白的原因。后面的slot里都是虛擬cape,只要引腳不沖突,可以不限數量地添加。一旦你的dtbo文件使用的引腳與已加載的cape有沖突,就會提示:
- -sh: echo: write error: File exists
至於卸載cape,假設我要卸載我的第8個cape,按照官方的說法,應當這樣操作:
- echo -8 > $SLOTS
