聊聊Beaglebone Black的cape和device tree overlay和dtc命令

本文是我早期写的,语言略混乱。请直接看我最新整理的,适用于初学者的文章《使用BBB的device tree和cape(重新整理版)》

我们知道beagleboard官网上有一些官方的硬件外设,比如lcd显示屏之类的,他们管这些外设叫做cape。其实这里是我理解狭隘了,应该说只要是修改了芯片引脚功能,或占用了空闲的引脚的东西,都可以叫做cape。比如之前我们提到的开启某些引脚的AD转换功能,其实也是给设备添加了一个virtual cape。Beaglebone Black中用一个叫做capemgr的软件管理所有的cape,不论它是实实在在的扩展板,还是虚拟的cape。这个软件的目录是

/sys/devices/bone_capemgr.*/(这里的*是一个每次系统启动可能会不一样的数字(与启动顺序有关))

如果你看过我的博客,也许还会记得我们加载device tree overlay时打开了一个文件,正是这个目录下的slots文件。slots文件就是capemgr这个软件的对外接口。slot这个单词是“插槽”的意思,看,很形象吧!我要插上一个cape,就向这个“插槽”里“插入”(echo)相应的设备。echo这个命令的含义是“向标准设备输出”嘛。另外,.dtbo文件只有放到/lib/firmware目录下才能被使用。

还记得我们第一次打开slots文件看到了什么吗?

# cat /sys/devices/bone_capemgr.*/slots
0: 54:PF--- 
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
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI

这里前4项为什么是空的呢?它们是给那些有EEPROM的实体cape预留的位置。通过实体cape上的开关,可以达到我们用 echo something > $SLOTS 语句一样的效果。不难看出,这样的实体cape最多只能插4个。

4和5这两项则是系统已经加载的两个virtual cape,因为eMMC和HDMI确实需要占用一些引脚,所以根据前面的定义,它们也是cape。

其实device tree overlay的作用之一是将设备和驱动进行绑定(前提是驱动或驱动模块已经存在于内核中),只不过相比从前那种重新编译内核的方式来说,这种方式实在太方便了。


12.18更新


关于cat $SLOTS


cat后显示的内容中,左侧的L字母代表是否加载。有时4、5这两项依然存在,但没有L字母,则也没有加载这两个cape。详见我的日志《为BBB制作专属自己的cape(二)》中的“ 系统存在Bug,运行时卸载cape会导致kernel panic ”一节。

关于dtc命令

参考我的日志《使用Beaglebone Black的PRU》前面写到的“修改系统dtb文件”这一部分操作可知:dtc命令虽然叫做“编译”,但其作用主要只是转变一下数据存储的格式,由人类可阅读的dts转成机器识别的dtb或dtbo或者反过来转换。
实际上由dtb转换成dts文件后,跟初始dts文件还是有不同的,从这个不同也能看出dts文件中什么内容是不重要的。以BBB自带的BB-ADC-00A0.dtbo为例,我们看一下它转换回dts文件是什么样的。
root@beaglebone:~/tmp# dtc -I dtb -O dts BB-ADC-00A0.dtbo
/dts-v1/;

/ {
        compatible = "ti,beaglebone", "ti,beaglebone-black";
        part-number = "BB-ADC";
        exclusive-use = "P9.39", "P9.40", "P9.37", "P9.38", "P9.33", "P9.36", "P9.35", "tscadc";

        fragment@0 {
                target = <0xdeadbeef>;

                __overlay__ {
                        #address-cells = <0x1>;
                        #size-cells = <0x1>;

                        tscadc {
                                compatible = "ti,ti-tscadc";
                                reg = <0x44e0d000 0x1000>;
                                interrupt-parent = <0xdeadbeef>;
                                interrupts = <0x10>;
                                ti,hwmods = "adc_tsc";
                                status = "okay";

                                adc {
                                        ti,adc-channels = <0x8>;
                                };
                        };

                        helper {
                                compatible = "bone-iio-helper";
                                vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
                                vsense-scale = <0x1000 0x1000 0x1000 0x1000 0x1000 0x1000 0x1000 0x1000>;
                                status = "okay";
                                linux,phandle = <0x1>;
                                phandle = <0x1>;
                        };
                };
        };

        __symbols__ {
                test_helper = "/fragment@0/__overlay__/helper";
        };

        __fixups__ {
                ocp = "/fragment@0:target:0";
                intc = "/fragment@0/__overlay__/tscadc:interrupt-parent:0";
        };
};
BB-ADC-00A0.dts原文是这样的
/*
 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 *
 * 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-ADC";

	/* state the resources this cape uses */
	exclusive-use =
		/* the pin header uses */
		"P9.39",	/* AIN0 */
		"P9.40",	/* AIN1 */
		"P9.37",	/* AIN2 */
		"P9.38",	/* AIN3 */
		"P9.33",	/* AIN4 */
		"P9.36",	/* AIN5 */
		"P9.35",	/* AIN6 */
		/* the hardware IP uses */
		"tscadc";

	fragment@0 {
		target = <&ocp>;
		__overlay__ {
			/* avoid stupid warning */
			#address-cells = <1>;
			#size-cells = <1>;

			tscadc {
				compatible = "ti,ti-tscadc";
				reg = <0x44e0d000 0x1000>;

				interrupt-parent = <&intc>;
				interrupts = <16>;
				ti,hwmods = "adc_tsc";
				status = "okay";

				adc {
					ti,adc-channels = <0 1 2 3 4 5 6 7>;
				};
			};

			test_helper: helper {
				compatible = "bone-iio-helper";
				vsense-name  = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
				vsense-scale = <100     100     100     100     100     100     100     100>;
				status = "okay";
			};
		};
	};
};
二者区别请自行比对。
当我想把dts文件转换成dtbo文件时,出现了错误。
root@beaglebone:~/tmp# dtc -I dts -O dtb BB-ADC-00A0.dts
ERROR (phandle_references): Reference to non-existent node or label "ocp"

ERROR (phandle_references): Reference to non-existent node or label "intc"

ERROR: Input tree has errors, aborting (use -f to force output)
(加上 -f 也是没有用的)但如果加上 -@ ,就可以顺利输出了。这就是device tree overlay和原生device tree的不同吧——device tree(比如/boot目录里那些dtb文件反编译出来的dts文件)都是包含从根节点到每个子节点的全部信息的。而device tree overlay(比如/lib/firmware目录中的那些)只需要包含要修改的内容即可。至于后缀名dtbo和dtb,似乎单纯是为了区分二者,内容格式其实都是一样的,都可以用dtc命令反编译成dts文件。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值