文章目錄
一、前言
前節中,已經將整個eclipse在線調試BBB程序做了詳細介紹,其實從上節開始,已經可以進行一定的應用程序編譯及調試,但是對於BBB這物聯網設備而言,我們更重要的是要使用它的硬件接口,如I2C、spi。此時自然會有兩個疑問:
- 如果我用I2C接口,但實際開機後該接口是普通IO怎麼辦?能否一開機,該接口便已經初始化成i2C接口。
- 當我在BBB上做項目開發,以BBB當作核心板時,BBB能否根據不同的擴展板作出特定的IO初始化操作,比如同樣的接口,一個擴展板用I2C,另一個用作普通IO口。BBB可以識別這兩個擴展板作不同的初始化操作。
接下來的幾節內容中將解決以上兩個問題。
二、 Device Tree介紹
對於本節前言中提到的兩個問題在BBB上已經有了合適的解決辦法:
- 通過linux本身device tree機制可以實現對硬件的基本配置
- 通過合適的方式加載device tree即可完成配置
- 在BBB上通過相關shell命令可以實現device tree加載
- 在BBB上已有相關腳本在開機時自動加載相應device tree.
- 在BBB上已經有相關腳本在開機時會讀取擴展板上的eeprom內信息,根據裏面的信息加載不同的device tree,從而實現開機針對特定擴展板進行不同配置。
通過這些信息我們可以看出,BBB實際項目的開發離不開device tree,相關特殊操作都是基於這個設備樹來操作的。
2.1 什麼是device tree
device tree直譯過來就是設備樹,什麼是設備樹呢,其實就是描述硬件信息的樹形結構,比如GPIO的配置、外設的配置等,這些信息要以一定的語法結構呈現,以方便編寫,該語法結構爲樹形結構。這是linux-3.x版本提供的新功能,當linux內核啓動時,device tree文件地址由bootloader傳送到內核,內核根據device tree中設備信息對芯片進行初始化,並加載相應驅動。
2.2 device tree文件
如同C語言一樣,首先要寫xx.c文件,以C語言的語法來編寫程序,再以C編譯器、鏈接器、彙編器等編譯,最終生成可以運行的C程序。device tree也是一樣,首先要編寫DTS文件,語法結構爲樹形結構,可以參考官網的說明,編寫的文件爲DTS文件,經過編譯器DTC編譯後可以生成DTB文件,內核可以識別該文件。其主要名稱縮寫:
- DTS: device tree source
- DTC: device tree compile
- DTB: device tree blob
- DTBO: device tree blob overlay
這裏多了一個DTBO文件,overlay是意思是覆蓋,就是說內核已經加載了DTB的基礎上,還需要對其他硬件進行配置,此時就要用DTBO文件對其進行覆蓋,開發BBB的cape時,DTBO是經常用到的文件,因此在實際學習中只需要掌握生成DTBO的DTS文件即可。
2.3 device tree語法結構
可以看下整個的例子,如下圖
2.3.1 結點名稱@單元地址
可以看出 每個結點的結構爲:
node-name@unit-address
結點名稱@單元地址
結構名稱是指當前需要設置的模塊的名稱,單元地址是指這個模塊在總線上的地址,通過這個地址可以設置它的寄存器,從而達到配置的目的。如果沒有地址,則不需要標示出來。
官網中結點名稱推薦用以下名稱:
- adc
- accelerometer
- atm
- audio-codec
- audio-controller
- backlight
- bluetooth
- bus
- cache-controller
- camera
- can
- charger
- clock
- clock-controller
- compact-flash
- can
- cpu
- cpus
- crypto
- disk
- display
- dma-controller
- dsp
- eeprom
- efuse
- endpoint
- ethernet
- ethernet-phy
- fdc
- flash
- gpio
- gpu
- gyrometer
- hdmi
- i2c
- ide
- interrupt-controller
- isa
- keyboard
- key
- keys
- lcd-controller
- led
- leds
- led-controller
- light-sensor
- magnetometer
- mailbox
- mdio
- memory
- memory-controller
- mmc
- mmc-slot
- mouse
- nand-controller
- nvram
- oscillator
- parallel
- pc-card
- pci
- pcie
- phy
- pinctrl
- pmic
- pmu
- port
- ports
- pwm
- regulator
- reset-controller
- rtc
- sata
- scsi
- serial
- sound
- spi
- sram-controller
- ssi-controller
- syscon
- temperature-sensor
- timer
- touchscreen
- usb
- usb-hub
- usb-phy
- video-codec
- vme
- watchdog
- wifi
2.3.2 結點屬性
屬性名稱+屬性值的方式
那麼一個結點可以有哪些屬性呢,這個在官方文檔中已經有清楚的定義,常用的有compatible, model, phandle, status, reg, device_type,name,interrupts
。
通過屬性值可以設置該接口的相關屬性,比如寄存器設置,設置中斷屬性等。
例如compatible,官方文檔解釋如下:
簡要的意思是說:
compatible是由一個或多個字符串構成的,是用來定義設備的編程模型的,客戶程序可以根據這裏面的字符串來選擇設備驅動。其形式建議是"manufacturer,model"
,即 廠家+模型的方式,例如:
compatible = "fsl,mpc8641", "ns16550";
3. BBB device tree實例
3.1 BBB dts文件分析
在BBB上最主要的是開發DTBO文件,系統開機時已經加載了基本的devicetree文件,只需要將dtbo文件加載,即可以完成相關端口初始化。
/*
* Copyright (C) 2013 CircuitCo
*
* Virtual cape for UART2 on connector pins P9.21 P9.22
*
* 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 = "DVK551-RS232-01";
version = "00A0";
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P9.21", /* uart2_txd */
"P9.22", /* uart2_rxd */
/* the hardware ip uses */
"uart2";
fragment@0 {
target = <&am33xx_pinmux>;
__overlay__ {
bb_uart2_pins: pinmux_bb_uart2_pins {
pinctrl-single,pins = <
0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 */
0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */
>;
};
};
};
fragment@1 {
target = <&uart3>; /* really uart2 */
__overlay__ {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&bb_uart2_pins>;
};
};
};
文件中:
/dts-v1/;
/plugin/;
這兩行是聲明,聲明瞭dts採用的版本號是v1,同時聲明瞭這個文件的內容是一個plugin。
compatible = "ti,beaglebone", "ti,beaglebone-black";
這個屬性是根節點下面的一行,爲了說明了它的適用平臺。意思是TI的廠家,採用beaglebone模型。
/* identification */
part-number = "DVK551-RS232-01";
version = "00A0";
part-number
是一般是說文件名稱,version
是指版本號是00A0,整個dts文件名就是part-number
+version
形式,因此這個例子的名稱就是DVK551-RS232-01-00A0.dts
。
再下面的部分說明了要使用的引腳和硬件設備
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P9.21", /* uart2_txd */
"P9.22", /* uart2_rxd */
/* the hardware ip uses */
"uart2";
fragment@0 {
target = <&am33xx_pinmux>;
__overlay__ {
bb_uart2_pins: pinmux_bb_uart2_pins {
pinctrl-single,pins = <
0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 */
0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */
>;
};
};
};
以上部分是根結點下的一個子結點主要是爲了定義引腳的地址及初始化值,對於我們修改而言,只需要知道引腳該怎樣配置即可,這就要用我們前面提到的查表來看。
上面結點信息中0x150
是指引腳地址,通過查表可以看到其地址,如下圖:
上在結點信息中0x21
是指配置引腳屬性轉換爲二進制爲0010 0001
,對就以下表可以看出主要初始化功能爲:選擇模式1,即串口功能,使能接收功能,使能端口下拉。具體查表方法可以查看前節相關內容。
針對以上信息的簡要介紹,可以手動對設備樹文件進行簡要修改,實際中相關端口的dts文件基本在BBB中都有了,我們只需要參考,並進行相關複製就可以了。