如何解决为不同的 beaglebone 披风编译机器人控制库 有用的提示:我实际运行的是哪个版本?电机披风无法启动未回答的问题有用的提示:观看串口终端!
我应该如何修改和/或编译 Robot Control Library 以与使用略有不同引脚分配的不同 beaglebone cape 一起使用?
我想要重新使用机器人控制库的主要原因是能够通过 PRU 读取第四个编码器。除此之外,我只需要访问编码器和 pwm 模块。
解决方法
TL;DR
修改 PRU 固件以从不同的引脚读取编码器信号很容易。弄清楚如何为我需要的功能组合组装一个工作设备树要困难得多。
我欢迎任何关于我应该如何做到这一点的反馈,或者我可以如何改进我目前拥有的。
机器人控制库+电机罩
Robotics Cape 和 BeagleBone Blue 为伺服控制四个电机提供了交钥匙解决方案,
如果您对以 8V 驱动它们感到满意(例如 2S LIPO 电池)。 Motor Cape 可以处理
更高的驱动电压(和更大的电流),但不包括编码器。将编码器插入 P8 和 P9
Motor Cape 上的标头非常简单,但 BeagleBone 本身只有 3 个编码器计数器 (eQEP)。
机器人控制库通过使用 PRU0 读取第四个编码器解决了这个问题。然而,一些
Motor Cape 与 Robot Control Library 对 Robotics Cape 的期望之间存在引脚冲突。
那么,使用机器人控制库读取编码器和驱动电机有多么困难 电机角上的不同引脚排列?如果您已经能够胜任 BeagleBone,那么可能根本不难 设备树覆盖,我不是...
一切从一个计划开始——引脚选择
别针 | PRU 位 | 机器人斗篷 | 电机披风 |
---|---|---|---|
P8_15 | 15 | 编码 4B | -- |
P8_16 | 14 | 编码 4A | M2 目录 |
P9_25 | 7 | IMU | -- |
机器人控制库期望第四个编码器出现在 P8_15 和 P8_16 上,但是 Motor Cape 将 P8_16 接线作为方向信号。只有 12 个引脚而不是配置 作为 PRU0 的输入,我最终选择了 P9_25,因为我不需要 IMU 功能。
我找到的关于哪些引脚可用于哪些目的的最佳参考是这些 pdf:
- https://ofitselfso.com/BeagleNotes/BeagleboneBlackP8HeaderPinMuxModes.pdf
- https://ofitselfso.com/BeagleNotes/BeagleboneBlackP9HeaderPinMuxModes.pdf
最简单的部分 -- 修改 PRU 代码
机器人控制库将 pru_firmware/src/pur0-encoder.asm
中的编码器信号输入位定义为
; Encoder counting definitions
; these pin definitions are specific to SD-101D Robotics Cape
.asg r0,OLD ; keep last known values of chA and B in memory
.asg r1,EXOR ; place to store the XOR of old with new AB vals
.asg 14,A
.asg 15,B
这可以修改为在第 7 位(寄存器 31,用于所有输入)上查找 A 通道
; Encoder counting definitions
; these pin definitions are specific to SD-101D Robotics Cape
.asg r0,EXOR ; place to store the XOR of old with new AB vals
.asg 07,B
注意 PRU 固件必须通过运行 make
和 sudo make install
单独编译
在 pru_firmware
目录中。它不作为构建其余部分的一部分自动编译
来自顶级 Makefile 的库。
有用的提示:我实际运行的是哪个版本?
有关于修改 librobotcontrol
的报告版本的说明
library/version_updating_howto.txt
。我按照这些说明创建了自己的
“私人”版本号,以便我可以确认我实际上正在运行我修改过的
库的版本。此版本由 rc_test_drivers
报告。
然而……如上所述,PRU 固件没有被顶级 Makefile 编译,
所以有一段时间我在 PRU 中运行带有“旧”固件的“新”版本 librobotcontrol
。
几乎可以工作的部分——设备树
我在文档和代码中找到了 librobotcontrol
设备树覆盖的参考
不再需要,因为 Robotics Cape 使用了自己的设备树。
现在不推荐使用覆盖层,而披风有自己的完整设备树。
我还观察到,运行推荐的 configure_robotics_dt.sh
替换了 /boot/uEnv.txt
以下加载单个设备树二进制文件 (.dtb) 的简化版本
uname_r=4.19.94-ti-r42
dtb=am335x-boneblack-roboticscape.dtb
cmdline=coherent_pool=1M
我发现的有关设备树、pinmux 等一般信息的最喜欢的参考是 http://www.ofitselfso.com/BeagleNotes/AboutTheDeviceTree.pdf 然而,我现在意识到有些 细节有点过时,所以要小心。
因为我几乎不知道从哪里开始,所以我开始修改机器人披风设备树 刚好足以消除与摩托斗篷的冲突。我分叉和克隆 https://github.com/beagleboard/BeagleBoard-DeviceTrees 并创建了两个新文件
-
am335x-boneblack-custom.dts
-
am335x-boneblack-roboticscape.dts
的副本 - 更改了
model
以使新设备树可识别 - 将
#include
改为指向am335x-custom.dtsi
而不是am335x-roboticscape.dtsi
-
-
am335x-custom.dtsi
-
am335x-roboticscape.dtsi
的副本 - 删除了一大堆我认为不再需要的东西
- 将 P9_25(而不是 P8_16)路由到 PRU0
-
之前
/* PRU encoder input */
0x03c 0x36 /* P8_15,PRU0_r31_15,MODE6 */
0x038 0x36 /* P8_16,PRU0_r31_14,MODE6 */
之后
/* PRU encoder input */
0x03c 0x36 /* P8_15,MODE6 */
0x1ac 0x36 /* P9_25,PRU0_r31_7,MODE6 */
编译安装修改后的设备树(make
、sudo make install
BeagleBoard-DeviceTrees
repo),我修改了 /boot/uEnv.txt
以调用我的新自定义设备树
uname_r=4.19.94-ti-r42
dtb=am335x-boneblack-custom.dtb
cmdline=coherent_pool=1M
我能够在没有安装披风的情况下启动 BeagleBone,将编码器直接插入所需的引脚
P8_和 P9(包括 P9_25 上的 enc4a)并使用 sudo rc_test_encoders
读取所有四个编码器。
我以为我赢了然后去睡觉了...
电机披风无法启动
一夜好眠后,我将 Motor Cape 连接到 BeagleBone 上,希望不会发生任何变化 我只是通过 P8 和 P9 头直接传递编码器信号。我以为下一步是 对一些 pwm 方向引脚进行类似的调整。
但是,BeagleBone 拒绝在安装了 MotorCape 的情况下启动我的自定义设备树。我回到
“标准”am335x-boneblack-roboticscape.dtb
设备树,并观察到它不会启动
马达角安装。我也开始怀疑 Robotics Cape 的“工厂”安装可能有
毕竟一直在使用叠加层
我从一开始就纠结于是否应该从 Robotics Cape 设备树开始并删除 为了消除资源冲突,我不需要的东西,而不是从“裸”的 BeagleBone 设备树开始 并添加我确实需要的东西。无论准确与否,在我看来,那种映射到试图指定 完整的设备树与提供覆盖层以应用于基本设备树的顶部。后者好像 概念上更正确的路径,所以一旦 Motor Cape 无法使用机器人技术派生的设备树启动, 我决定硬着头皮尝试找出设备树覆盖。
未回答的问题
- [ ] 为什么安装了电机罩的 BB 不能从
am335x-boneblack-roboticscape.dtb
启动?实际错误是什么? - [ ]
librobotcontrol
的“正常”安装是安装上面简化的uEnv.txt
还是使用覆盖层?有用吗?
我还没有可以安装在安装好的斗篷下的 USB-to-TTL 串行电缆,所以我对它知之甚少 为什么或如何无法启动。
最终起作用的部分——设备树覆盖
我最终发现设备树覆盖的集合在
https://github.com/beagleboard/bb.org-overlays 和 v4.19.x-ti-overlays
分支位于
https://github.com/beagleboard/BeagleBoard-DeviceTrees。我怀疑这可能是一个
正在进行迁移,但有更多与 bb.org-overlays
相关的文档
存储库,所以这就是我选择使用的。
我希望早些找到的一些文档链接:
- https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays
- https://github.com/cdsteinkuehler/beaglebone-universal-io
- https://vadl.github.io/beagleboneblack/2016/07/29/setting-up-bbb-gpio
我创建了 bb.org-overlays
存储库的分叉、克隆和分支,并在以下位置创建了一个新的叠加层
src/arm/CustomCape-00A0.dts
通过将 BBORG_MOTOR-00A2.dts
和 RoboticsCape-00A0.dts
/*
* Device Tree Overlay for custom cape trying to reuse Robot Control Library's
* reading of 4x optical encoders.
*/
/*
pinmux control byte map courtesy of http://beaglebone.cameon.net/
Bit 5: 1 - Input,0 - Output
Bit 4: 1 - Pull up,0 - Pull down
Bit 3: 1 - Pull disabled,0 - Pull enabled
Bit 2 \
Bit 1 |- Mode
Bit 0 /
*/
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone-black";
/* identification */
part-number = "CustomCape";
/* version */
version = "00A0";
exclusive-use =
"P8.11",/*QEP_2B*/
"P8.12",/*QEP_2A*/
"P8.16",/*PRU_ENCODER_A*/
"P8.33",/*QEP_1B*/
"P8.35",/*QEP_1A*/
"P9.27",/*QEP_0B*/
"P9.41",/*MOT_STBY*/
"P9.42"; /*QEP_0A*/
/*
* Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
*/
fragment@0 {
target-path="/";
__overlay__ {
chosen {
overlays {
CustomCape-00A0 = __TIMESTAMP__;
};
};
};
};
fragment@1 {
target = <&am33xx_pinmux>;
__overlay__ {
/****************************************
* pinmux helper
****************************************/
mux_helper_pins: pins {
pinctrl-single,pins = <
/* EQEP */
0x1A0 0x31 /* P9_42,EQEP0A,MODE1 */
0x1A4 0x31 /* P9_27,EQEP0B,MODE1 */
0x0D4 0x32 /* P8_33,EQEP1B,MODE2 */
0x0D0 0x32 /* P8_35,EQEP1A,MODE2 */
0x030 0x34 /* P8_12,EQEP2A_in,MODE4 */
0x034 0x34 /* P8_11,EQEP2B_in,MODE4 */
/* PRU encoder input */
0x03c 0x36 /* P8_15,MODE6 */
>;
};
};
};
/****************************************
Pinmux Helper
activates the pinmux helper list of pin modes
****************************************/
fragment@2 {
target = <&ocp>;
__overlay__ {
test_helper: helper {
compatible = "bone-pinmux-helper";
pinctrl-names = "default";
pinctrl-0 = <&mux_helper_pins>;
status = "okay";
};
};
};
/*
* Free up the pins used by the cape from the pinmux helpers.
*/
fragment@3 {
target = <&ocp>;
__overlay__ {
P8_11_pinmux { status = "disabled"; }; /* enc3b */
P8_12_pinmux { status = "disabled"; }; /* enc3a */
P8_15_pinmux { status = "disabled"; }; /* enc4b */
P8_33_pinmux { status = "disabled"; }; /* enc0 */
P8_35_pinmux { status = "disabled"; }; /* enc0 */
P9_25_pinmux { status = "disabled"; }; /* enc4a */
P9_27_pinmux { status = "disabled"; }; /* enc1b */
P9_92_pinmux { status = "disabled"; }; /* enc1a */
};
};
/****************************************
Encoders
****************************************/
fragment@9 {
target = <&eqep0>;
__overlay__ {
count_mode = <0>; /* 0 - Quadrature mode,normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock,chb input = direction */
swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no,1 - yes) */
invert_qa = <1>; /* Should we invert the channel A input? */
invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */
invert_qi = <0>; /* Should we invert the index input? */
invert_qs = <0>; /* Should we invert the strobe input? */
status = "okay";
};
};
fragment@10 {
target = <&eqep1>;
__overlay__ {
count_mode = <0>; /* 0 - Quadrature mode,1 - yes) */
invert_qa = <1>; /* Should we invert the channel A input? */
invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */
invert_qi = <0>; /* Should we invert the index input? */
invert_qs = <0>; /* Should we invert the strobe input? */
status = "okay";
};
};
fragment@11 {
target = <&eqep2>;
__overlay__ {
count_mode = <0>; /* 0 - Quadrature mode,1 - yes) */
invert_qa = <1>; /* Should we invert the channel A input? */
invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */
invert_qi = <0>; /* Should we invert the index input? */
invert_qs = <0>; /* Should we invert the strobe input? */
status = "okay";
};
};
/****************************************
PRU
****************************************/
fragment@31 {
target = <&pruss>;
__overlay__ {
status = "okay";
};
};
};
我将自定义叠加层添加到 /boot/uEnv.txt
并禁用了视频和音频叠加层
uname_r=4.19.94-ti-r42
#uuid=
#dtb=
###U-Boot Overlays###
###Documentation: http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays
###Master Enable
enable_uboot_overlays=1
###
###Additional custom capes
uboot_overlay_addr4=/lib/firmware/CustomCape-00A0.dtbo
###
###Custom Cape
#dtb_overlay=/lib/firmware/<file8>.dtbo
###
###Disable auto loading of virtual capes (emmc/video/wireless/adc)
#disable_uboot_overlay_emmc=1
disable_uboot_overlay_video=1
disable_uboot_overlay_audio=1
#disable_uboot_overlay_wireless=1
#disable_uboot_overlay_adc=1
###
###PRUSS OPTIONS
###pru_rproc (4.19.x-ti kernel)
uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-19-TI-00A0.dtbo
###
###Cape Universal Enable
enable_uboot_cape_universal=1
###
###U-Boot Overlays###
cmdline=coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet
我不主张最佳性甚至正确性,但无论是否配备 Motor Cape,此配置都适用
安装,我可以使用 rc_test_encoders
读取所有四个编码器。安装好Motor Cape后,uBoot
正确拾取并应用 BBORG_MOTOR-00A2
叠加层。老实说,我认为我需要更多
PRU 的配置以从机器人控制库工作中获取基于 PRU 的编码器计数器,但这似乎
做到这一点。
我欢迎任何关于我应该如何做到这一点的反馈,或者我可以如何改进我目前拥有的。
有用的提示:观看串口终端!
我什至在没有串行终端的情况下尝试调试设备树启动问题,这让我很尴尬 打开 beaglebone,以便我可以观察启动顺序。在一些 5 分钟环氧树脂的帮助下,我 最终能够制作一个 90 度接头,将 JTAG 端口从安装的斗篷下引出。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。