【转】使用BBB的device tree和cape(重新整理版)
只要你想用BBB做哪怕一丁点涉及到硬件的东西,你就不可避免地要用到cape和device tree的知识。所以尽管它们看起来很陌生而且有点复杂,但还是得学。其实用起来不难的。下面我只讲使用时必须会的内容,不深究其工作原理。文中基本没有废话,请仔细阅读每个字,勿遗漏细节。
我们已经知道beagleboard官网上有一些官方的硬件外设,比如lcd显示屏之类的,他们管这些外设叫做cape。其实应该说只要是修改了芯片引脚功能,或占用了空闲的引脚的东西,都可以叫做cape。比如之前我们提到的开启某些引脚的I2C功能,其实也是给设备添加了一个虚拟的(virtual)cape。当我们想要使用一个cape的时候,需要做两件事:配置BBB引脚的功能,启动相应的驱动程序。而device tree基本就是用来干这两件事的。
下面我们就来依次认识device tree文件,修改dts文件,编译dts文件,加载device tree,验证是否加载成功。
一、认识device tree文件
那么device tree具体是长什么样的呢?首先要知道它们有三种格式:一个方便人类阅读的源文件*.dts(device tree source),另两个是经过编译送给系统使用的文件*.dtb(device tree blob)和*.dtbo(device tree blob overlay)。
在BBB的/lib/firmware/目录下,你可以看到很多*.dts文件。我们随便打开一个(BB-UART1-00A0.dts)看看它们长什么样:
在BBB的/lib/firmware/目录下,你可以看到很多*.dts文件。我们随便打开一个(BB-UART1-00A0.dts)看看它们长什么样:
- /*
- * Copyright (C) 2013 CircuitCo
- *
- * Virtual cape for UART1 on connector pins P9.24 P9.26
- *
- * 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-UART1";
- version = "00A0";
- /* state the resources this cape uses */
- exclusive-use =
- /* the pin header uses */
- "P9.24", /* uart1_txd */
- "P9.26", /* uart1_rxd */
- /* the hardware ip uses */
- "uart1";
- fragment@0 {
- target = <&am33xx_pinmux>;
- __overlay__ {
- bb_uart1_pins: pinmux_bb_uart1_pins {
- pinctrl-single,pins = <
- 0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
- 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
- >;
- };
- };
- };
- fragment@1 {
- target = <&uart2>; /* really uart1 */
- __overlay__ {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&bb_uart1_pins>;
- };
- };
- };
不要被dts文件复杂的外表吓到!dts文件确实有一定的编写规则,但是这不是我们要操心的。因为BBB已经提供了足够多现成的dts文件,我们要做的就是:1、看懂它们,2、学会复制和粘贴。
二、修改dts文件
我们的最终目的是写出符合自己需求的dts文件,那么单单复制粘还是不够的,我们有时候需要修改里面那些属性的值。那么这些属性都是什么含义呢?其实它们都是有据可循的:www.kernel.org/doc/Documentation/devicetree/bindings/ 。提示一点,文档有点乱,请多用Ctrl+F。
前面说到dts里主要有两部分内容:修改BBB引脚功能和启动驱动程序。上面的网址里只告诉了驱动程序的属性,那么引脚功能该如何配置呢?
以前面给出的代码为例,这几行代码是用来配置引脚功能的:
前面说到dts里主要有两部分内容:修改BBB引脚功能和启动驱动程序。上面的网址里只告诉了驱动程序的属性,那么引脚功能该如何配置呢?
以前面给出的代码为例,这几行代码是用来配置引脚功能的:
- pinctrl-single,pins = <
- 0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
- 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
- >;
如何查看BBB当前的引脚功能呢?
- cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pins
一般这句后面还会加上grep命令来显示特定的引脚功能,同样在《BBB引脚功能速查表》中第三列找到P9.24的地址是0x984,所以可以这样查找:
- root@beaglebone:~# cat $PINS | grep 984
- pin 97 (44e10984) 00000037 pinctrl-single
另外一个要注意的是每个dts里根节点下都有这两个属性:
- part-number = "BB-UART1";
- version = "00A0";
三、编译dts文件
实际上,dts和dtbo文件可以随时编译和反编译,即dts可以生成dtbo,dtbo也可以复原成dts(但是复原的dts里没有注释等无用的东西了)。编译和反编译使用的命令都是相同的:dtc(device tree compile)。
dts编译成dtbo:
- dtc -I dts -O dtb -@ BB-UART1-00A0.dts > BB-UART1-00A0.dtbo
- dtc -I dtb -O dts BB-UART1-00A0.dtbo > BB-UART1-00A0.dts
四、加载dtbo文件
加载之前,一定记住要把编译好的dtbo文件放到/lib/firmare/目录中,否则程序是找不到你的dtbo文件的。
Beaglebone Black中用一个叫做cape manager的软件管理所有的cape,不论它是实实在在的扩展板,还是虚拟的cape。这个软件的目录是
/sys/devices/bone_capemgr.8/(这里的数字也有可能是9,与启动顺序有关,你可以直接用*代替它)。这个目录内有一个叫做slots的文件,这就是capemgr这个软件的对外接口。我们要加载某个cape的话,只需要向这个文件中写入dts文件里定义的名字(part-number属性)即可:
Beaglebone Black中用一个叫做cape manager的软件管理所有的cape,不论它是实实在在的扩展板,还是虚拟的cape。这个软件的目录是
/sys/devices/bone_capemgr.8/(这里的数字也有可能是9,与启动顺序有关,你可以直接用*代替它)。这个目录内有一个叫做slots的文件,这就是capemgr这个软件的对外接口。我们要加载某个cape的话,只需要向这个文件中写入dts文件里定义的名字(part-number属性)即可:
- echo BB-UART1 > /sys/devices/bone_capemgr.8/slots
(注:如果那个dtbo有多个版本,比如有00A0,00A1,00A2这3个版本,如果你只写 echo BB-UART1 > $SLOTS 的话,它会自动加载最新的版本。而且,必须保证从00A0开始每个版本都存在才可以成功加载,就是说,如果/lib/firmware/目录中只有00A2这一个版本的话,加载会失败。但是,你可以通过 echo BB-UART1:00A2 > $SLOTS 像这样添加版本号来加载某个特定版本。)
使用命令:
- cat $SLOTS
- root@beaglebone:~# cat $SLOTS
- 0: 54:P---L Beaglebone LCD4 Cape,00A1,BeagleboardToys,BB-BONE-LCD4-01
- 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
- 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-ADC
- 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART1
BBB可以插入4个实体cape,它们只能插在0、1、2、3这四个slot里,这也是1、2、3号slot是空白的原因。后面的slot里都是虚拟cape,只要引脚不冲突,可以不限数量地添加。一旦你的dtbo文件使用的引脚与已加载的cape有冲突,就会提示:
- -sh: echo: write error: File exists
至于卸载cape,假设我要卸载我的第8个cape,按照官方的说法,应当这样操作:
- echo -8 > $SLOTS