[心得] 使用 device tree overlay控制iio driver

看板LinuxDev作者 (沒有存在感的人)時間9年前 (2015/07/23 18:03), 9年前編輯推噓5(506)
留言11則, 7人參與, 最新討論串1/1
以下是在下針對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/ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 90.27.173.93 ※ 文章網址: https://www.ptt.cc/bbs/LinuxDev/M.1437645786.A.774.html ※ 編輯: wtchen (90.27.173.93), 07/23/2015 18:04:54

07/23 18:46, , 1F
07/23 18:46, 1F

07/23 19:14, , 2F
dts和bootloader的關係呢?
07/23 19:14, 2F

07/24 00:30, , 3F
其實我還沒有完全搞懂,有心得會再分享
07/24 00:30, 3F

07/24 00:31, , 4F
感謝提問。
07/24 00:31, 4F

07/24 09:42, , 5F
dt 有 free electrons 的教學投影片,可以放一下
07/24 09:42, 5F

07/24 09:43, , 6F
目前有用到 overlay 的好像就 rpi 跟 beagle 系列而已?
07/24 09:43, 6F

07/24 09:44, , 7F
一種方式可能是你跟bootloader講要什麼overlay, 他幫你合併
07/24 09:44, 7F

07/24 09:44, , 8F
到板子本身的 dt, 然後餵給 kernel
07/24 09:44, 8F

07/24 14:54, , 9F
推!
07/24 14:54, 9F

07/24 20:10, , 10F
07/24 20:10, 10F
※ 編輯: wtchen (86.200.13.228), 08/03/2015 23:30:16

08/09 00:54, , 11F
08/09 00:54, 11F
文章代碼(AID): #1LiBlQTq (LinuxDev)
文章代碼(AID): #1LiBlQTq (LinuxDev)