只要你想用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)看看它们长什么样:
  1. /*
  2. * Copyright (C) 2013 CircuitCo
  3. *
  4. * Virtual cape for UART1 on connector pins P9.24 P9.26
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. /dts-v1/;
  11. /plugin/;
  12. / {
  13. compatible = "ti,beaglebone", "ti,beaglebone-black";
  14. /* identification */
  15. part-number = "BB-UART1";
  16. version = "00A0";
  17. /* state the resources this cape uses */
  18. exclusive-use =
  19. /* the pin header uses */
  20. "P9.24",        /* uart1_txd */
  21. "P9.26",        /* uart1_rxd */
  22. /* the hardware ip uses */
  23. "uart1";
  24. fragment@0 {
  25. target = <&am33xx_pinmux>;
  26. __overlay__ {
  27. bb_uart1_pins: pinmux_bb_uart1_pins {
  28. pinctrl-single,pins = <
  29. 0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
  30. 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
  31. >;
  32. };
  33. };
  34. };
  35. fragment@1 {
  36. target = <&uart2>; /* really uart1 */
  37. __overlay__ {
  38. status = "okay";
  39. pinctrl-names = "default";
  40. pinctrl-0 = <&bb_uart1_pins>;
  41. };
  42. };
  43. };

可以看到,dts文件是一个树形结构,是由若干节点和属性组成的。compatible = "ti,beaglebone", "ti,beaglebone-black"; 这行代码上面相邻行的斜杠"/"代表根节点,下面的fragment@0和fragment@1是其两个子节点。其中根节点下面的属性声明了本dts文件适用的平台,它的名字、版本号,使用了哪些引脚和硬件资源等。fragment@0节点中配置了两个BBB引脚的功能,把它们设置成了uart1的tx和rx功能。fragment@1节点中使能了uart1这个硬件设备(启用了相应的驱动)。

不要被dts文件复杂的外表吓到!dts文件确实有一定的编写规则,但是这不是我们要操心的。因为BBB已经提供了足够多现成的dts文件,我们要做的就是:1、看懂它们,2、学会复制和粘贴。
 

二、修改dts文件

 
我们的最终目的是写出符合自己需求的dts文件,那么单单复制粘还是不够的,我们有时候需要修改里面那些属性的值。那么这些属性都是什么含义呢?其实它们都是有据可循的:www.kernel.org/doc/Documentation/devicetree/bindings/ 。提示一点,文档有点乱,请多用Ctrl+F。

前面说到dts里主要有两部分内容:修改BBB引脚功能和启动驱动程序。上面的网址里只告诉了驱动程序的属性,那么引脚功能该如何配置呢?
以前面给出的代码为例,这几行代码是用来配置引脚功能的:

  1. pinctrl-single,pins = <
  2. 0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
  3. 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
  4. >;

其中第一列的0x184和0x180分别是P9.24和P9.26的地址,第二列的0X20代表要配置成什么功能。它们都是怎么确定的呢?这里就要用到pdf文档《BBB引脚功能速查表》了(请百度找此表,在EEWORLD论坛的一篇帖子中)。我们首先找到P9.24所在的行(在第2页的中间),然后在第三列中可以看到它的偏移地址(OFFSET)是184。至于功能配置,我们按照pdf第2页下面的GPIO Settings提示来写。我们需要把这个引脚配置成“快速模式”、“使能输入”、“使能下拉”、“功能0(uart1_txd)”。每一位按照相应的功能来写,即00100000,即0x20。

 
如何查看BBB当前的引脚功能呢?
  1. cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pins

因为这个目录很常用,我把它存成了环境变量$PINS。以后我使用 cat $PINS 就可以了。
一般这句后面还会加上grep命令来显示特定的引脚功能,同样在《BBB引脚功能速查表》中第三列找到P9.24的地址是0x984,所以可以这样查找:

  1. root@beaglebone:~# cat $PINS | grep 984
  2. pin 97 (44e10984) 00000037 pinctrl-single

可以看到,这个引脚的当前功能是0x37,即00110111,从最后三位看出是功能7,查表知是GPIO功能。

另外一个要注意的是每个dts里根节点下都有这两个属性:

  1. part-number = "BB-UART1";
  2. version = "00A0";

第一个是名字,第二个是版本号。你自己写的dts文件要新起一个名字,版本号则必须按照00A0,00A1……这样的顺序依次排下去。你的dts文件名必须是“名字+版本号.dts”的格式,如这里的BB-UART1-00A0.dts。

 

三、编译dts文件

 

写好dts文件以后,要把它转化成系统可识别的格式。上面说到有dtb和dtbo两种格式,我们这里要转化成的是dtbo格式。因为BBB的Angstrom系统在上电启动的时候就加载了一个dtb文件,给每个引脚配置了默认的功能,加载了需要加载的驱动程序。因为这个dtb文件已经加载,我们在系统运行着的情况下是不能修改它的。我们能做的,是在系统这个dtb的基础上,“叠加(Overlay)”一些新的功能,因此要用dtbo(dtb overlay)格式。

实际上,dts和dtbo文件可以随时编译和反编译,即dts可以生成dtbo,dtbo也可以复原成dts(但是复原的dts里没有注释等无用的东西了)。编译和反编译使用的命令都是相同的:dtc(device tree compile)。
dts编译成dtbo:

  1. dtc -I dts -O dtb -@ BB-UART1-00A0.dts > BB-UART1-00A0.dtbo

dtbo反编译成dts:

  1. dtc -I dtb -O dts BB-UART1-00A0.dtbo > BB-UART1-00A0.dts

(注:有的网站上编译用的是这样的命令:dtc -O dtb -o BB-UART1-00A0.dtbo -b 0 -@ 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属性)即可:

  1. echo BB-UART1 > /sys/devices/bone_capemgr.8/slots

slot这个单词是“插槽”的意思,看,很形象吧!我要插上一个cape,就向这个“插槽”里“插入”(echo)相应的设备。echo这个命令的含义是“向标准设备输出”嘛。因为这个目录很常用,所以我把它存成环境变量$SLOTS,这样以后只需写 echo BB-UART1 > $SLOTS 即可了。

(注:如果那个dtbo有多个版本,比如有00A0,00A1,00A2这3个版本,如果你只写 echo BB-UART1 > $SLOTS 的话,它会自动加载最新的版本。而且,必须保证从00A0开始每个版本都存在才可以成功加载,就是说,如果/lib/firmware/目录中只有00A2这一个版本的话,加载会失败。但是,你可以通过 echo BB-UART1:00A2 > $SLOTS 像这样添加版本号来加载某个特定版本。)

 

五、查看和卸载已加载的cape

使用命令:
  1. cat $SLOTS

可以查看当前已经加载的所有cape。比如在我的BBB上执行命令后得到输出:

  1. root@beaglebone:~# cat $SLOTS
  2. 0: 54:P---L Beaglebone LCD4 Cape,00A1,BeagleboardToys,BB-BONE-LCD4-01
  3. 1: 55:PF---
  4. 2: 56:PF---
  5. 3: 57:PF---
  6. 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
  7. 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-ADC
  8. 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART1

前面说了slots是“插槽”的意思,可以看到我这里已经“插入”了4个cape,包括1个实体的LCD cape和3个虚拟cape。

BBB可以插入4个实体cape,它们只能插在0、1、2、3这四个slot里,这也是1、2、3号slot是空白的原因。后面的slot里都是虚拟cape,只要引脚不冲突,可以不限数量地添加。一旦你的dtbo文件使用的引脚与已加载的cape有冲突,就会提示:

  1. -sh: echo: write error: File exists

另外注意上面显示的几个已加载cape里的这部分内容“ff:P-O-L”,这里最后的“L”代表这个cape已经被load,即已经启用。也许你将来会遇到虽然显示在$SLOTS里,但是没有这个“L”的cape,那样的话它基本等于不存在。

至于卸载cape,假设我要卸载我的第8个cape,按照官方的说法,应当这样操作:

  1. echo -8 > $SLOTS

但因为系统bug的原因,这样操作会导致系统重启……所以目前只能通过重启系统来卸载cape。等出系统更新也许就解决这个bug 了。

【转】使用BBB的device tree和cape(重新整理版)的更多相关文章

  1. 聊聊Beaglebone Black的cape和device tree overlay和dtc命令【转】

    本文转载自:https://blog.csdn.net/wyt2013/article/details/16846171 本文是我早期写的,语言略混乱.请直接看我最新整理的,适用于初学者的文章< ...

  2. 【转】用Device tree overlay掌控Beaglebone Black的硬件资源

    原文网址:https://techfantastic.wordpress.com/2013/11/15/beaglebone-black-device-tree-overlay/ 经过一晚上的Goog ...

  3. Device Tree碎碎念

    首先推荐elinux.org上一篇关于Device Tree的文章: http://elinux.org/Device_Tree_Usage 这是一篇关于Device Tree的入门文章.对英文犯怵的 ...

  4. Device Tree(二):基本概念

    转自:http://www.wowotech.net/linux_kenrel/dt_basic_concept.html 一.前言 一些背景知识(例如:为何要引入Device Tree,这个机制是用 ...

  5. Linux and the Device Tree

    来之\kernel\Documentation\devicetree\usage-model.txt Linux and the Device Tree ----------------------- ...

  6. linux下的device tree

    在我个人的理解,device tree就是描述硬件设备的,目前有什么配置,把这些配置信息告诉linux内核,让内核去识别,增强了内核的通用性,不用因为平台不同而每次都要编译新内核了. 配置device ...

  7. Device Tree(三):代码分析【转】

    转自:http://www.wowotech.net/linux_kenrel/dt-code-analysis.html Device Tree(三):代码分析 作者:linuxer 发布于:201 ...

  8. ARM Linux 3.x的设备树(Device Tree)

    http://blog.csdn.net/21cnbao/article/details/8457546 宋宝华 Barry Song <21cnbao@gmail.com> 1.     ...

  9. Device Tree Usage( DTS文件语法)

    http://elinux.org/Device_Tree_Usage Device Tree Usage     Top Device Tree page This page walks throu ...

随机推荐

  1. java jvm学习笔记二(类装载器的体系结构)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao                 在了解java虚拟机的类装载器之前,有一个概念我们是必须先知道的,就是java的沙箱,什 ...

  2. 《深入Java虚拟机学习笔记》- 第1章 Java体系结构

    一.体系结构组成 当编写并运行一个Java程序时,就同时体验了这四种技术.用Java语言编写源代码,编译成Java Class文件,然后再在Java虚拟机上运行class文件.当编写程序时,通过调用类 ...

  3. HDU 4003-Find Metal Mineral(树状背包)

    题意: n个节点的树给出每个边的权值,有k个机器人,求由机器人走完所有节点的最小花费(所有机器人开始在根节点) 分析: 仔细看了几遍例题后,发现这个题的状态很巧妙,先从整体考虑,一个机器人走完所有边回 ...

  4. C# Debug与release之间的一些小差异

    如果代码声明了一个变量,后面却没有用到, 生成方式debug模式下,这个变量的值存在,调试过程中是可以看到的, 生成方式release模式下,编译时经过了优化,这个值在调试过程就看不到了

  5. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  6. Node与Express开发 坑1

    添加 app.set('views', __dirname + '/views') 修改 app.use(express.static(__dirname + '/public')); express ...

  7. 在win64位,python64位2.7版本中安装pyHook

    今天看了一篇博文说的是利用pyhook监听键盘鼠标事件(感兴趣的可以看博客园中相关文章),文章中使用的pyHook模块的官方下载地址是:http://sourceforge.net/projects/ ...

  8. Docker系列(八)Kubernetes介绍

    Kubernetes组件功能图   各组件说明: 节点 节点在Kubernetes由虚拟机或者实体机表示,常称为Minion,即从属主机.当一个节点加入到Kubernetes系统中时,它将会创建一个数 ...

  9. POJ 3648-Wedding(2-SAT)

    题面很邪恶啊... 一对新人请n-1对夫妻吃饭,人们坐在一张桌子的两侧,每一对互为夫妻关系的人必须坐在桌子的两侧.而且有些人两两之间会存在“通奸”关系,通奸关系不仅在男女之间,同性之间也有.新娘对面不 ...

  10. hdoj 1229 还是A+B

    还是A+B Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...