Jon*_*nny 2 c hardware dma raspberry-pi pwm
我读到“软件 PWM”的驱动程序以某种方式在 PWM-HW 上运行,并在不使用 CPU 的情况下访问所有 GPIO。有人可以解释它是如何工作的吗?Raspberry Pi 中是否有第二个处理器用于 PWM 和 PCM 模块(是否有块图)?
这个问题与我在我的机器人中经常使用的这个优秀的驱动程序有关。
这是解释,不幸的是我不明白......
驱动程序通过设置 DMA 控制块的链接列表来工作,最后一个链接回第一个,因此一旦初始化,DMA 控制器就会连续循环,除非需要更改脉冲宽度,否则驱动程序不需要参与. 对于给定的周期,有两个 DMA 控制块;第一个将单个字传输到 GPIO“清除输出”寄存器,而第二个将一定数量的字传输到 PWM FIFO 以生成所需的脉冲宽度时间。此外,穿插这些控制块的是每个配置的伺服器,用于设置输出。
虽然驱动程序确实使用了 PWM 外设,但它仅使用它来调整 DMA 传输的速度,从而产生准确的延迟。”
以下理解是否正确:
DMA 控制器就像第二个处理器。您可以在其上运行代码。因此,这里使用它与 PWM 块一起控制所有 Raspberry GPIO 引脚的高/低状态。DMA 控制器会连续执行此操作。Raspberry 中可能有不止一个 DMA 控制器,因此 OS Linux 的速度不会因为缺少一个 DMA 控制器而受到太大影响。
我不明白 DMA 和 PWM 究竟是如何协同工作的。
我建议阅读RPIO 源代码和ServoBlaster 的,因为它稍微简化了,可以帮助理解。同样非常重要:Broadcom 的 BCM2835 手册,其中包含所有微小的细节。
有没有方块图
该手册包含该芯片提供的所有功能(但就我所见,不在框图中)。
以下理解是否正确:
DMA 控制器是主芯片的一部分(Broadcom,虽然我认为桌面 CPU 上也会发生同样的情况)。它不能完全运行代码,但它可以自己跨外设复制内存,而不会消耗主处理器的时间。DMA 控制器有不同的通道,可以独立复制内存,独立于 CPU 运行。
它可以通过“控制块”(BCM 手册第 40 页,4.2.1.1)进行配置:您可以告诉 DMA 控制器首先将内存从 A 复制到 B,然后从 C 复制到 D,依此类推。
不明白 DMA 和 PWM 究竟是如何协同工作的
DMA用于将数据发送到 PWM 控制器(“脉宽调制器”,BCM 手册第 138 页,第 9 章),后者消耗数据并产生非常精确的延迟。有趣的是,PWM 控制器……不是用来产生任何 PWM 脉冲的,而是用来等待的。
有人可以解释它是如何工作的吗?
最终,您通过在特殊地址设置内存来配置 GPIO 引脚的值(或 PWM 或 PCM 发生器的设置);该区域中的内存代表外设配置(BCM 手册第 89 页,第 6 章)。
所以想法是: 使用DMA控制器将1复制到控制GPIO引脚值的内存上;等待脉宽;将 0 复制到 GPIO 引脚值;等待剩余时间;环形。由于 DMA 控制器执行此操作,因此不会消耗 CPU 周期。
这里的关键点是能够让 DMA 控制器“等待”一个确切的时间量,为此,RPIO 和 ServoBlaster 在 FIFO 模式下使用 PWM 控制器(PCM 发生器也有这样的功能,但让我们坚持使用 PWM) . 这意味着 PWM 控制器将“发送”它从其所谓的 FIFO 队列中读取的数据,然后停止。它是如何“发送”的并不重要(BCM 手册页 139, 9.4 MSENi=0),关键是它需要固定的时间。事实上,发送哪个数据并不重要:DMA 控制器被配置为写入 FIFO 队列,然后等待 PWM 控制器完成发送数据,这会产生非常精确的延迟。
结果脉冲的分辨率由 PWM 传输的持续时间决定,该持续时间取决于 PWM 控制器运行的频率。
我们有 1ms 的最大分辨率(由 PWM 延迟给定),我们希望有一个频率为 125Hz 的占空比为 25% 的脉冲。因此一个脉冲的周期是 8ms。执行的 DMA 操作将是
因此,这将需要至少 10 个 DMA 控制块(8 个等待指令,由周期/延迟加上 2 个写操作给出)。
注意: 在 ServoBlaster 和 RPIO 中,它将正好消耗 16 个 DMA 控制块,因为(为了更高的精度),它们总是在“等待操作”之前执行“内存复制”操作。“内存复制”操作只是一个虚拟操作,除非它需要更改引脚值。