This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/PRU-SWPKG:PRU PWM 问题

Guru**** 2540720 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/595111/linux-pru-swpkg-pru-pwm-issue

器件型号:PRU-SWPKG

工具/软件:Linux

我正在尝试使用 BeagleBone Black 上的 PRU 通过 P8_11发送宽度为100个时钟周期的脉冲。 在 main.c 文件中、我为引脚 P8_10添加了一个上升沿的回调。

如果我禁用外部环路并仅发送一次脉冲、我不会在回调函数中注册任何内容。 如果启用了外环、程序将冻结。

我的方法是否有任何问题? 是否有任何工作示例也尝试这样做?

谢谢。

/* PRU PWM 代码

每1000个时钟周期发送宽度为100个时钟周期的脉冲。
//
//程序启动
.origin 0

//高
电平和低电平之间的延迟 mov R1、10
//发送
mov R2的脉冲数、1000

//此处的循环
outloop:
//设置为高电平
设置 r30、r30、15

//在这里等待一段时间
延迟:
SUB R1、R1、1
qbne 延迟、R1、0

//将其设为低电平
CLR r30、r30、15
R2、R2、1
qbne outloop、R2、0

//我们已完成、发送中断
mov R31.b0、19 + 16

//停止、否则 PWM 持续
停止

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    PRU 专家已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否有逻辑分析仪来查看 P8-11在外部发生了什么?

    我看不到您的汇编代码中的任何位置、您将使用10重新加载 R1的值。 因此、R1将保持为0、并且内部环路将很快被绕过、或者 R1将滚动到0xffffffff、在 R1再次在每个环路上递减到0之前需要~21.5秒(我认为这就是将发生的情况)。

    此外、我不确定它是否是复制和粘贴、但您的"elay:"标签不应缩进、否则不会将其识别为标签。

    Jason Reeder

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 Jason。

    我也做了一些其他的事情。 修复了它们、现在我得到了整洁的1000个脉冲。

    我有一个后续问题:

    我在 P8_10上连接了伺服编码器、我希望接收并计算那里的编码器节拍数。

    如果我使用 add_edge_Detect 设置正常回调(不是通过 PRU、而是通过正常的 C 程序)、我不会得到任何节拍、因为频率过高。 我是否可以通过 PRU#1获取值的任何方法? 此外、我是否能够并行运行两个 PRU?

    P.S:发布新代码以供参考:

    //程序开始
    .origin 0
    
    MOV R2、1000
    top:
    
    //设置高电平 P9_27
    设置 R30.T5
    
    //等待此处的某个时间
    MOV R1、1163
    HIDELAY:
    SUB R1、R1、1
    QBNE HIDELAY、R1、0
    
    //设置低
    CLR R30.T5
    SUB R2、R2、1
    
    //等待低电平
    MOV R1、1163
    LOWDELAY:
    SUB R1、R1、1
    QBNE LOWDELAY、R1、0
    
    //从顶部
    QBNE 顶部重复、R2、0
    
    //我们完成了、发送中断
    MOV R31.B0、19 + 16
    
    //停止、否则 PWM 持续
    停止 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很高兴听到您的 Bit-Bang 式 PWM 部分工作正常!

    虽然 PRU 可以实现这些专用功能、但 AM335x 器件上有专用外设、可用于执行您尝试实现的功能类型。 通过使用 PRU 子系统内 eCAP 外设的 PWM 模式、可以生成一个简单的 PWM 信号。 此外、您还可以让 PRU 控制 eQEP (增强型正交编码器脉冲)模块、以便对编码器节拍进行计数。

    请参阅此 TI 参考设计、该设计实际上实现了这两个功能(使用 PRU 生成 PWM 并读取正交编码器): http://www.ti.com/tool/TIDEP0073

    设计指南将介绍演示: http://www.ti.com/lit/pdf/tidubj6

    该页面和以下位置也提供了源代码: http://www.ti.com/lit/zip/tidcc20

    是的、两个 PRU 都可以完全并行运行、如我提到的 TI 设计中所示。

    Jason Reeder

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢 Jason、
    使用 SDK 进行了大多数设置。 但是、当我启动 PRU_pid_server 时、它所说的都是"无效的 RPMsg 文件。 正在退出"、这意味着未创建/dev/rpmsg_pru 文件。
    我已使用 USB 电缆将 BBB 连接到 Linux 主机、并已使用 USB 电缆建立以太网连接。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我使用 RPMsg 支持重新安装内核(processors.wiki.ti.com/.../RPMsg_Quick_Start_Guide)后、服务器开始工作。 服务器现在会在 stdout 上打印一些数据、并且可以使用 Web 浏览器查看图形并设置设定值、Kp、Ki、Kd 等的值 然而、电机不会移动、图形也不会更新。
    我缺少什么吗? 是否有某种方法可以测试 PRU 是否正常工作?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您现在可以看到/dev/rpmsg_pruX 器件是否正确? 您是否能够在连接到电机的引脚(使用逻辑分析仪)上看到 PWM 信号?

    您使用了设计指南中列出的处理器 SDK 版本、对吧?

    Jason Reeder

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我想我使用的是最新的 SDK 版本(03.03.00.04)、但除了环境变量的变化之外、所有这些都是顺利编译的。
    我将简要概述我的流程。 如果我在某个地方出错、请告诉我:
    1.使用默认配置运行 make,并编译 zImage 和设备树覆盖
    2.运行 create-sdcard.sh 并使用预编译的映像。
    3.将 zImage 和 dtb 文件复制到/boot/
    4.编译了 prupid_fw_0.c 和 prupid_fw_1.c 并将它们复制到/lib/firmware/pru 文件夹。 已将服务器文件复制到/usr/share/matrix_gui~
    5.更新了符号链接以指向复制的文件。
    6.将内存卡弹出 BBB 并启动。 (eMMC 已禁用、BBB 肯定从 SDCard 运行。)
    7.引脚上没有任何信号。

    此外、是否有任何方法可以检查放在/lib/firmware/pru 文件夹中的.out 文件在启动时是否正在运行?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    RPUMsg 会发生怪异的情况。 在使用 RPUMsg 支持编译内核后、我第一次启动 BeagleBone。 两个/dev/rpmsg_pruX 均可见。 但是、如果我重新启动 BBB、它们将消失、只有在我重新编译所有内容并将其加载到 SD 卡上之后、我才能查看它们。
    这可能是一个错误吗?
    我还尝试了从动手实验中运行第一个基本示例、甚至这似乎不起作用。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Puneeth、

    该 TI 参考设计中提供的代码针对2.0.2.11版的 Linux 处理器 SDK 进行了验证(如设计指南中所述)。 不保证与 SDK 的任何其他版本一起工作(未经修改)。

    在2.0.2.11发行版和当前3.3.0.4发行版之间、对默认器件树以及 rpmsg 在 PRU 和 ARM 内核之间工作的方式进行了更改。

    如果要运行3.3.0.4 SDK、则需要(1)确保器件启动后没有引脚冲突、以及(2)移植在 pru1上运行的 RPMsg 代码、以根据更新的 rpmsg_lib 进行构建  

    (1)引导后、在命令提示符下键入"dmesg | grep pinctrl"、并确保未报告冲突

    (2)从 TI 设计中提供的 pru1代码开始、并将 resource_table 替换为"ti-processor-sdk-linux-am335x-evm-03.03.00.04/example-applications/PRU-ICSS-5.1.0/examples/AM335x/PRU_RPMsg_Interrupt1/resource_table"中的代码。 您还需要更改 makefile 以根据更新的 rpmsg 库进行构建(导出 PRU_CGT=${HOME}/ti-processor-SDK-Linux-AM335x-EVM-03.03.00.04/linux-devkit/sysroots/x86_64 Arago-linux//usr/share/ti/CGT-PRU)。 然后、您需要更新 PRU_IO_1.c 文件中的 RPMsg 段、以匹配"ti-processor-sdk-linux-AM335x-evm-03.03.00.04/example-applications/PRU-ICSS-5.1.0/examples/AM335x/PRU_RPMsg_Interrupt1.c/rupt1.c 文件中的 RPMsg 段

    Jason Reeder

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我切换到了旧版本的 SDK,一切似乎都可以正常工作。 我将尝试将其移植到较新版本并进行检查。

    关于 PRU 的功能、我有一个稍微更广泛的问题。 我想使用 Cortex A8 (甚至 A9)驱动3个伺服电机。 我想知道、我是否可以仅使用两个 PRU 驱动所有这些电机并向所有电机并行(或至少以最小的延迟在它们之间切换)接收编码器反馈。 我认为有一些限制、例如 PRU 可用的 eQEP 引脚的数量等

    如果不可能这样做、那么最好的策略是什么? PRU 上反馈环路可运行的电机最大数量是多少?

    谢谢、
    Puneeth
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Puneeth、

    eQEP 引脚属于 PRU 子系统之外的 eQEP 模块。 在示例中控制 eQEP 外设的 PRU 代码(在 prupid_fw_1/PRU_IO_1.c 中)实际上只是使用 PRU 访问 SOC 的完整存储器空间来读取和写入 eQEP 寄存器。

    AM335x SOC 总共有3个 eQEP 模块(每个 PWM 子系统(PWMSS)内部各一个)、因此您应该能够为每个电机使用一个模块。 但是、如果您使用的是 BeagleBone Black、则似乎只有 eQEP1输出到接头引脚(该示例使用的引脚)。 不过、较新的 BeagleBone Blue 提供了所有3个 eQEP 模块的引脚以及4个电机驱动器(电路板上也有电机驱动 器)的足够 PWM 信号:beagleboard.org/.../。 原理图如下: https://github.com/beagleboard/beaglebone-blue。 BeagleBone Blue 的支持将来自 BeagleBoard 社区: http://beagleboard.org/discuss

    电机/编码器反馈的最大数量在很大程度上取决于您为应用编写的代码。 但是、由于2个内核以200MHz 的频率运行、似乎驱动3个电机应该完全处于 PRU 的能力范围之内。

    Jason Reeder

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Jason、
    正如您所说、BBB 仅提供一个 eQEP 引脚、仅提供一个编码器反馈。
    因此、我计划使用每个电机可用的 PWM 发送固定数量的脉冲。
    我能否以不同的并行频率运行4个 PWM、并通过轮询中断等方式使每个 PWM 以不同的间隔(或在发送特定数量的脉冲之后)停止? 或者是否有更好的方法来控制4个独立电机?

    谢谢、
    Puneeth
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Puneeth、

    是的、PRU 可以通过位拆裂其通用输出引脚来实现此目的(这是您在这篇文章的开头所做的事情?)。 但是、您必须编写软件才能执行此操作。

    PRU 有一个循环寄存器、您可以启用该寄存器、使每个周期(5ns)递增。 您可以在代码中使用此功能以及一些逻辑来确定是否应使用 R30寄存器切换4个通用输出中的每一个(在您的情况下为位拆裂 PWM)。

    Jason Reeder