作者:
wtchen (沒有存在感的人)
2015-07-23 18:02:52以下是在下針對device tree寫的文章,若有誤請不吝指正。
網誌好讀版:
http://gnitnawtw.blogspot.fr/2015/07/device-tree-overlayindustrial-io.html
終於把我第1個device tree overlay生出來了!要趕快把心得寫下來。
Device tree的功用
想像若是沒有device tree,為不同的處理器寫kernel modules
會變成一件看起來複雜實際上很簡單的事,舉個例子,
以raspberry pi model B+跟raspberry pi 2來說,這兩者只有
SoC、CPU、記憶體大小不一樣,但是其他該外部設備(I2C、SPI等)都差不多。
可是若是沒有device tree,寫kernel module的時候就必須把以下步驟各做一次
- 弄一個machine type id
- 在kernel裏面建立關於此id的相關文件,設定SoC的相關代碼
(包括外部設備如interrupt、timer、memory mapping等等)還有board-specific文件
- 設定其他的driver
但是現今的SoC都大同小異,了不起就是pin(gpio、I2C等)的位置不一樣,
為了這些小差異,要把上面那三件事重做一次,增加一倍的coding到kerenl,
使得kernel最後越來越肥搞到Linus本人都出來罵。
Device tree的作法就是把外設資訊(怎麼連接、哪個memory mapping等)
以bootloader傳送給kernel,讓kernel把外設需要的module根據Device tree的
訊息連接起來。
實際做起來還挺有趣的。我自己寫了兩個可以在raspberry pi model B+
連接industrial i/o (iio) driver用的device tree
MCP3008(adc)
如果編譯kernel的時候有勾選industrial i/o driver的時候就可以使用
可以在/lib/modules/{uname -r}/modules.alias找到這個module :
alias spi:mcp3008 mcp320x
根據kernel document 的說明
https://www.kernel.org/doc/Documentation/devicetree/bindings/iio/adc/mcp320x.txt
我寫了mcp320x.dts:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708";
/* disable spi-dev for spi0.0 */
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
spidev@0{
status = "disabled";
};
};
};
fragment@1 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
mcp3x0x@0 {
compatible = "mcp3008";
reg = <0>;
spi-max-frequency = <1000000>;
};
};
};
};
dts寫好後用dtc編譯:
dtc -@ -I dts -O dtb -o mcp320x.dtb mcp320x.dts
然後把mcp320x.dtb copy到/boot/overlays/
最後在/boot/config.txt加上:dtoverlay=mcp320x (跟我寫的mcp320x.dtb做連結)
重開機後,只要mcp3008有接對應該就沒問題了。
MPU6050(六軸陀螺儀)
一樣根據
https://www.kernel.org/doc/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
來編輯mpu6050.dts
// Definitions for MPU6050
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
clock-frequency = <400000>;
inv-mpu6050@68 {
compatible = "invensense,mpu6050";
reg = <0x68>;
interrupts = <2 23>;
//這行要看情況改不然IRQ有可能會衝到
};
};
};
};
編譯後放到/boot/overlays,/boot/config.txt上加入:dtoverlay=mpu6050
如果想要debug,可以在/boot/config.txt上加入:dtdebug=1
重開機後執行sudo vcdbg log msg 就可看device tree載入訊息:
參考資料:
Device Tree 背景介紹
http://www.wowotech.net/linux_kenrel/why-dt.html
Device Trees, Overlays and Parameters
https://www.raspberrypi.org/documentation/configuration/device-tree.md
https://patchwork.ozlabs.org/patch/464158/
作者:
wens (æ–‡æ€)
2015-07-24 09:42:00dt 有 free electrons 的教學投影片,可以放一下目前有用到 overlay 的好像就 rpi 跟 beagle 系列而已?一種方式可能是你跟bootloader講要什麼overlay, 他幫你合併到板子本身的 dt, 然後餵給 kernel