beagleboneblack – 如何使用设备树覆盖在Beaglebone Black上添
为什么要读这个?
如果您有一个Beaglebone Black(BBB),并且想要将自己的设备连接到它(不是capes),那么您可能已经听说过设备树.在我的情况下,我想将RTC设备连接到BBB上的I2C总线.网络上散布着大量信息,本文旨在概述我发现的内容,并指导您完成此操作. 因此,我将给出一个在BBB上激活I2C总线的完整示例,以及使用内核中包含的设备驱动程序连接DS1308 RTC芯片.听起来不错? 然后阅读,如果有什么不清楚,请留下评论.如果您有点匆忙,您也可以在Github上抓住设备树重叠代码并飞走. 第一件事 我在我的BBB上使用ArchLinux ARM,主要是因为Arch Linux很棒,我可能太笨了,不能使用debianoid发行版. 你可能会注意到内核版本已经超过了3.x的东西.在screenfetch中看不到的是内核支持使用Capemgr实用程序的设备树覆盖. 什么是设备树? 我会做的很快,你可以找到更深入的知识here,here,here和here. 在将设备树引入Linux之前,所有这些工作必须用特定的C头文件和自定义实现完成,然后所有这些都必须被合并到主线内核中.因此,作为一个可想象的穷尽任务,它来到了着名的Linus Torvalds rant.这里你还有更多的device tree background. 是的,不错,但它是如何工作的? 要描述设备树,我们使用.dts(设备树源)文件,它们是人类可读的,并由设备树编译器(dtc)编译成设备树blob(.dtb)二进制格式.当系统引导引导程序(例如u-boot)时,将该blob交给内核.内核解析它并创建由设备树给出的所有设备. 如果您不信我,请使用设备树编译器将您的BBB正在使用的设备树峰值. 如果您还没有安装,请获取相应的软件包.. pacman -Sy dtc-overlay dtc -f -I fs /proc/device-tree | less 由于该命令生成了大量的输出,所以推荐使用传呼机的管道.结果应该看起来像这样.. 您的设备树的所有部分也可以在内核源中进行调查,但是由于还有一个包含机制,信息会在几个文件之间分割 <kernel-source>/arch/arm/boot/dts/.. 一些相关文件是: > am335x-bone-common.dtsi
它们都描述与处理器相关的设备,Beaglebone平台上的常见设备或仅适用于Beaglebone Black的设备. 你提到了叠加层,那是什么? 好的问题,我看到你还在我身边.如前所述,内核启动时,设备树blob将被解析.所以当你的系统启动并运行时,整个魔法已经结束了.在像BBB这样的平台上,有一大堆扩展板(Capes),这将需要您每次去另一个斗篷使用时重新编译设备树. 因此,您可以使用覆盖机制,允许您在设备树中添加或修改设备AT RUNTIME!惊人.
我该如何使用这一切? 我会给你一个例子.由于BBB没有实时时钟(rtc),这对于生成测量等的时间戳是有用的,我们将要解决这个问题. 我们将使用ds1307实时时钟芯片(事实上,我有一个ds1308 rtc,但驱动程序是兼容的),并通过BBB上的I2C1总线进行通信.默认情况下,BBB上的总线被禁用,从设备树源可以看到. 该片段中的重要信息是: >定义了一个名为’i2c1’的节点 现在我们将创建一个覆盖图来配置i2c1总线的GPIO引脚,激活该总线,之后我们将添加rtc-i2c1总线,以便自动加载相应的驱动程序,并在/ dev中创建rtc-device . BBB上的P8和P9接头上的GPIO引脚具有多种功能,它们被复合在一起,因此我们必须调整引脚设置以将其用于I2C通信.从this table可以看到,对于I2C1总线,我们必须在多路复用器模式2中使用引脚17和18.要获取有关BBB外观上的GPIO处理的更多信息,请参阅here. /dts-v1/; /plugin/; /{ /* this is our device tree overlay root node */ compatible = "ti,beaglebone","ti,beaglebone-black"; part-number = "BBB-I2C1"; // you can choose any name here but it should be memorable version = "00A0"; fragment@0 { target = <&am33xx_pinmux>; // this is a link to an already defined node in the device tree,so that node is overlayed with our modification __overlay__ { i2c1_pins: pinmux_i2c1_pins { pinctrl-single,pins = < 0x158 0x72 /* spi0_d1.i2c1_sda */ 0x15C 0x72 /* spi0_cs0.i2c1_sdl */ >; }; }; }; }; /* root node end */ OMG刚刚发生什么? 乍一看,重叠语法看起来很奇怪,但它基本上由所谓的片段组成,目标是已经存在的设备节点并修改该节点(而且是子节点). 在这种情况下,我们定位处理器设备树(am33xx.dtsi)中定义的am33xx_pinmux设备节点.在该节点中,我们添加一个新的子节点,名为pinmux_i2c1_pins,之前不存在(看看am335x-bone-common.dtsi以验证)和标签i2c1_pins. 下一部分更复杂一些,如果您有兴趣,请阅读this.每个GPIO引脚都由一个具有几个位的单个寄存器配置,以控制其行为,所有寄存器由pinctrl单个驱动程序控制.要设置一个特定的引脚只是使用它的地址偏移从基地址(你会发现在上面的P9标题表),它的引脚配置作为第二个参数.. 我从Derek Molloy借了这个概述来解释引脚模式.由于0x72相当于01110010b,因此我们将两个引脚配置为使能上拉电阻的输入和复用模式2中的主动转换控制. 并且这些引脚的复用模式2意味着标题P9上的引脚17是时钟线SCL,标题P9上的引脚18是数据线SDA. 但是我们还是要启用I2C1? 这是绝对正确的,所以让我们扩展我们的覆盖如下. /dts-v1/; /plugin/; /{ /* this is our device tree overlay root node */ compatible = "ti,pins = < 0x158 0x72 /* spi0_d1.i2c1_sda */ 0x15C 0x72 /* spi0_cs0.i2c1_sdl */ >; }; }; }; fragment@1 { target = <&i2c1>; __overlay__ { pinctrl-0 = <&i2c1_pins>; clock-frequency = <100000>; status = "okay"; rtc: rtc@68 { /* the real time clock defined as child of the i2c1 bus */ compatible = "dallas,ds1307"; #address-cells = <1>; #size-cells = <0>; reg = <0x68>; }; }; }; }; /* root node end */ 在上面的代码中,我们添加了一个针对i2c1设备节点的新片段,并告诉它使用我们以前定义的引脚配置.我们设置一个100kHz的I2C时钟频率并激活该设备. 此外,rtc时钟作为一个小孩添加到i2c1节点.内核的重要信息是兼容语句,命名驱动程序(ds1307)和I2C总线上的器件地址(0x68). rtc的I2C地址可以从数据表中获取. 那我该如何把这个代码放到内核中? 起初设备树源必须被编译.使用带有以下调用的dtc编译器 dtc -O dtb -o <filename>-00A0.dtbo -b 0 -@ <filename>.dts
所得到的.dtbo文件应该被复制到/ lib / firmware中,我真的不知道那个“-00A0”命名约定来自哪里,但固件目录里还有其他文件. 从现在开始,您可以使用Capemgr动态加载叠加层.这样做进入/ sys / devices / platform / bone_capemgr /然后执行.. echo <filename> > slots 然后,Capemgr将在固件目录中查找您的.dtbo文件,如果可能的话加载它.通过查看插槽文件,您可以看到过程是否成功.应该看起来像这样.. 检查Beaglebone使用的设备树. dtc -f -I fs /proc/device-tree | less 你会发现覆盖层的所有条目 此外,您的文件系统中应该有一个新的I2C设备(/ dev / i2c-1)和一个新的rtc设备(/ dev / rtc1). 要看看你的i2c总线安装包i2c工具并使用.. i2cdetect -r 1 输出应该是这样的东西.. 您可以看到地址0x68被设备占用. 查询您的rtc使用.. hwclock -r -f /dev/rtc1 但这不是全部,还是呢? 不,还有一个选项,在引导时加载设备树重叠.真棒! 要这样做打开/boot/uEnv.txt并添加bone_capemgr.enable_partno =< filename>到optargs声明.这就是我BBB上的样子 optargs=coherent_pool=1M bone_capemgr.enable_partno=bbb-i2c1 令人困惑的是,文件名在optargs中使用,而不是在设备树覆盖中定义的部件号标签. 如果你喜欢,你可以在github将代码放在一个有用的Makefile上. 对不起,长发 解决方法
这是非常有用和有价值的信息.我写了一个i2c内核驱动程序,我可以动态加载,与地址0x77的定制芯片通话.我以前通过手动实例化设备成功地与芯片通信,如下所示:echo act2_chip 0x77> / SYS /总线/ I2C /装置/ I2C-1 / new_device.
在设备实例化之后,我可以看到它使用i2cdetect工具,我的可加载内核驱动程序可以与芯片进行通信. 现在我试图使用设备树方法实例化设备.所以跟随你,我改变了你的dtsi文件中的一些参数,如下所示: 片段@ 1 { __overlay__ { pinctrl-0 = <&i2c1_pins>; clock-frequency = <100000>; status = "okay"; act2_chip: act2_chip@77 { /* the real time clock defined as child of the i2c1 bus */ compatible = "xx,act2_chip"; #address-cells = <1>; #size-cells = <0>; reg = <0x77>; }; 我将芯片连接到引脚17和18,用于scl和sdk.这是echo中得到的dmesg输出>插槽: 但是当将驱动程序插入内核时,我看到被调用的探测功能.这意味着司机能够尽可能地看到设备. 当我尝试写入内核驱动程序时,我会收到以下消息:omap_i2c 4802a000.i2c:控制器超时 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- vb.net – .NET 4中是否允许泛型运算符重载?
- xml – DOM splitText和normalize组合应该给出身
- cocos2dx异步加载资源制作Loading界面
- React-native android 启动遇到的问题
- 本地SQLite DB的Android Content Provider:为什
- Oracle - 安装 Oracle Database 11g Release 2
- 【js特效】如下几种非flash的js图片特效已被收藏
- Oracle Study--Oracle RAC CacheFusion(MindMap
- Memory芯片的应用攻略
- Swift实现俄罗斯方块详细思路及源码