C 覆盆子:通过DMA的PWM是如何工作的?

C 覆盆子:通过DMA的PWM是如何工作的?,c,raspberry-pi,hardware,dma,pwm,C,Raspberry Pi,Hardware,Dma,Pwm,我读到“软件PWM”的驱动程序以某种方式在PWM-HW上运行,并且在不使用CPU的情况下访问所有GPIO。有人能解释一下这是怎么回事吗?Raspberry Pi中是否有用于PWM和PCM模块的第二个处理器(是否有模块图) 这个问题与我在我的机器人中大量使用的技术有关 这是解释,不幸的是我不明白 驱动程序的工作原理是使用 最后一个链接回第一个,因此一旦初始化DMA控制器 连续循环,驾驶员无需参与,除非 当需要改变脉冲宽度时。对于给定的时间段,有两个DMA 控制块;第一个将单个字传输到GPIO“清除

我读到“软件PWM”的驱动程序以某种方式在PWM-HW上运行,并且在不使用CPU的情况下访问所有GPIO。有人能解释一下这是怎么回事吗?Raspberry Pi中是否有用于PWM和PCM模块的第二个处理器(是否有模块图)

这个问题与我在我的机器人中大量使用的技术有关

这是解释,不幸的是我不明白

驱动程序的工作原理是使用 最后一个链接回第一个,因此一旦初始化DMA控制器 连续循环,驾驶员无需参与,除非 当需要改变脉冲宽度时。对于给定的时间段,有两个DMA 控制块;第一个将单个字传输到GPIO“清除输出” 寄存器,而第二个将一些字数传输到PWM FIFO以 产生所需的脉冲宽度时间。此外,还穿插着这些 每个配置的伺服都有一个控制块,用于设置输出

虽然驱动器确实使用PWM外围设备,但它仅使用它来调整DMA的速度 传输,以便产生准确的延迟。”

以下理解是否正确:

DMA控制器类似于第二个处理器。您可以在其上运行代码。因此,这里使用它来控制所有Raspberry GPIO引脚的高/低状态以及PWM块。DMA控制器会连续执行此操作。Raspberry中可能有多个DMA控制器,因此操作系统Linux的速度不会因为一个MSI而受到太大影响ngdma控制器

我不明白DMA和PWM到底是如何一起工作的。

我建议与一起阅读,因为它稍微简化了一些,有助于理解。同样非常重要的是:它包含了所有细微的细节

有方块图吗

该手册包含了芯片提供的所有功能(但就我所见,不是在框图中)

以下理解是否正确:

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队列中读取数据,然后停止。无论如何“发送”(车身控制模块手册第139页,9.4
MSENi=0
),关键在于它需要固定的时间。事实上,它是被发送的:DMA控制器被配置为写入FIFO队列,然后等待PWM控制器完成数据发送,这会产生非常精确的延迟

产生脉冲的分辨率由PWM传输的持续时间给出,该持续时间取决于PWM控制器运行的频率

实例 我们有一个1ms的最大分辨率(由PWM延迟给出),我们希望有一个频率为125Hz的占空比为25%的脉冲。因此,脉冲的周期为8毫秒。将执行DMA操作

  • 将引脚设置为1(DMA写入GPIO mem)
  • 等待1ms(DMA写入PWM FIFO)
  • 等待1ms(DMA写入PWM FIFO)
  • 将引脚设置为0(DMA写入GPIO mem)
  • 等待1ms(DMA写入PWM FIFO)
  • …再重复“等待1ms”4次
  • 等待1ms(DMA写入PWM FIFO)并跳回到1
  • 因此,这将需要至少10个DMA控制块(8个等待指令,由周期/延迟加上2个写入操作给出)

    注意:在ServoBlaster和RPIO中,它将恰好消耗16个DMA控制块,因为(为了更高的精度),它们总是在“等待操作”之前执行“内存复制”操作。“内存复制”操作只是一个伪操作,除非它需要更改pin值