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

楼主: 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/
作者: james732 (好人超)   2015-07-23 18:46:00
作者: openeyes222 (睁大眼看)   2015-07-23 19:14:00
dts和bootloader的关系呢?
楼主: wtchen (没有存在感的人)   2015-07-24 00:30:00
其实我还没有完全搞懂,有心得会再分享感谢提问。
作者: wens (文思)   2015-07-24 09:42:00
dt 有 free electrons 的教学投影片,可以放一下目前有用到 overlay 的好像就 rpi 跟 beagle 系列而已?一种方式可能是你跟bootloader讲要什么overlay, 他帮你合并到板子本身的 dt, 然后喂给 kernel
作者: onlywig (环岛旅行ing)   2015-07-24 14:54:00
推!
作者: zack2004 (~夜晚的星空~)   2015-07-24 20:10:00
作者: chadcoco1222 (ha)   2015-08-09 00:54:00

Links booklink

Contact Us: admin [ a t ] ucptt.com