为什么java.nio.FileChannel transferTo()和transferFrom()比一些JVM/OS组合上的逐字节传输(基于流或使用ByteBuffer)更快?
这些方法是否使用直接内存访问(DMA)而不是为每个字节传输发出中断请求(IRQ)?
stm32F4系列的DMA有一些高级功能,我可以在这里要求澄清吗?
并发流:两个流可以同时传输数据吗?由于允许一个字节传输.如果总线宽度为32位,则可以进行4次并发传输.顺便说一下,STM32的AHB总线宽度是多少?
FIFO模式:如果无法进行并发传输,我猜这里可以使用FIFO.FIFO将有助于将数据从低速外设等待到DMA而不占用AHB总线.当准备好一定数量的数据时,数据块将一起发送到内存.我的理解是否正确?
四字深度每个流32个先进先出存储缓冲器(FIFO)
那是什么意思?FIFO中可以存储多少数据?4或4*32?
突发模式:实际突发模式有什么作用?它在数据表中说可以传输65535个数据.65535与突发模式之间有什么关系?
双缓冲模式:
双缓冲区类型事务:使用两个
内存指针进行内存的双缓冲区传输(当DMA
从/向缓冲区读/写时,应用程序可以向/从另一个
缓冲区写入/读取).-----来自STM32F4的参考手册
我的问题是:在DMA传输期间,AHB总线不适用于Cortex M4,应用程序如何从其他缓冲区读取?
我对 DMA 有这个基本疑问。当CPU让出总线让DMA继续读取/存储数据时,它如何继续处理?
我的意思是,即使 CPU 也必须获取指令,通过总线将结果存储回内存/IO,不是吗?
我试图了解ARM体系结构的DMA内部,参考内核文档:http://lxr.free-electrons.com/source/Documentation/DMA-API-HOWTO.txt.
我的理解是我们在内核空间中分配内存(使用DMA约束)并将其传递给dma_map_single()函数,该函数将根据DMA需要更改内存的映射属性(写入组合或非高速缓存).然后,如果平台支持IOMMU,它将返回设备总线的虚拟地址,否则它将返回可以直接从设备访问的物理地址.
这是正确的理解吗?
目前,我无法映射它的源代码,任何带有代码片段的指针都会非常有用.
我想将非常大的内存块的内容传输到足够大的 GPU 缓冲区,然后立即更改 CPU 上的内存内容。在伪代码中是这样的:
glBindBuffer(/*very_large_buffer*/);
glBufferSubData(/*very_large_memory_chunk*/);
memset(/*zeros*/, /*very_large_memory_chunk*/);
Run Code Online (Sandbox Code Playgroud)
在这段代码中,glBufferSubData实际上做了什么?它是否在返回之前将 very_large_memory_chunk 传输到某个地方,还是只是安排传输操作以供稍后执行?因此,如果我立即开始更改 CPU 缓冲区,是否可能会传输部分更改的内存,从而在 GPU 的 very_large_buffer 中产生垃圾?
请注意,我不是在询问渲染调用。我知道如果缓冲区用于渲染,传输操作将等到渲染完成,反之亦然。我想知道 OpenGL 在 CPU 到 GPU 传输操作中的行为是否相同。
我有一个 STM32F4,我想对一个已与掩码进行“或”运算的 GPIO 端口进行 PWM 处理。
因此,也许我们想要以0b00100010200khz 进行一段时间的 PWM,但是,10khz 后,我们现在想要进行 PWM 0b00010001...然后,10kHz 后,我们想要在同一 GPIO 上对其他一些掩码进行 PWM。
我的问题是,如何使用 DMA 做到这一点?我正在尝试触发一个 DMA 传输,该传输将在上升沿设置所有位,然后触发另一个 DMA 传输,该传输将在下降沿清除所有位。
我还没有找到一个好的方法来做到这一点(至少使用 CubeMX 以及我对 C 和 STM32 的有限经验),因为看起来我只有机会在上升沿做一些事情。
我主要关心的问题之一是 CPU 时间,因为尽管我在上面的示例中提到了数百千赫兹,但我想让这个框架非常强大,因为它不会浪费 CPU 资源。这就是为什么我喜欢 DMA 的想法,因为它是专用硬件,可以无意识地将这里的一个单词提升到那里的一个单词之类的东西,而 CPU 可以做其他事情,比如处理 PID 的数字或其他东西。
编辑 为了清楚起见:我有一组 6 个值,可以写入 GPIO。它们存储在一个数组中。我想要做的是设置一个 PWM 定时器来在 PWM 的正宽度期间设置 GPIO,然后我希望在低周期宽度期间将 GPIO 设置为 0b00000000(如果 pwm. 因此,我需要查看上升沿何时,快速写入GPIO,然后查看下降沿何时,并向GPIO写入0。
我读到“软件 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 究竟是如何协同工作的。
我在 CubeMX 中为 ADC1 启用了 DMA 外设到内存传输并生成了代码。但是,我对来自 ADC 的数据将写入何处感到困惑?我应该明确定义一个变量来包含这些数据吗?如何检索 DMA 通道 1 ISR 中的数据?
为了简化讨论,我假设只有一个执行线程.以下是我的疯狂猜测:
1,如果CPU从存储器地址读取一个字节,则它可以重复从同一地址读取相同的值.
2,如果CPU重复从端口读取一个字节,则每次可能读取不同的值.
我认为这两种方式的区别在于端口控制器可以在每次读取操作后自动更新端口上的值.
但是,我找不到明确支持我的陈述的任何教科书.
我对么?
我正在STM32f3Discovery板上编写一个程序,该程序应该使用DAC生成正弦波。我有几个文件,在下面列出。
Utilities.h:
#ifndef UTILITIES_H
#define UTILITIES_H
/** @brief Configure GPIOE, pin 9 (LED) as output PP
*/
void GPIOE_init( void );
/** @brief Configure Timer 2, event frequency - 100Hz
*/
void Timer_init( void );
/** @brief Configure interrupt handler
*/
void NVIC_config( void );
/** @brief Configure and enable DAC channel 1 on pin PA4,
* with TIM2 TRGO as trigger
*/
void DACch1_config( void );
/** @brief Configure DMA to work with DAC
*/
void DMA_config( void ); …Run Code Online (Sandbox Code Playgroud)