给定起始内存地址和字数,DMA 控制器在 CPU 处理其他进程时传输数据。输入输出处理器也处理给定起始地址和字数的 I/O 进程..(如果我有错误,请纠正我)
那么 IOP 和 DMA 控制器在功能上有什么区别呢?
将 MPLAB X 1.70 与 dsPIC33FJ128GP802 微控制器一起使用。
我有一个应用程序,它以不同的采样率(一个为 50Hz,另一个为 1000Hz)从两个传感器收集数据,两个传感器数据包的大小也不同(一个是 5 字节,另一个是 21 字节)。到目前为止,我一直使用手动 UART 传输,如下所示:
void UART_send(char *txbuf, char size) {
// Loop variable.
char i;
// Loop through the size of the buffer until all data is sent. The while
// loop inside checks for the buffer to be clear.
for (i = 0; i < size; i++) {
while (U1STAbits.UTXBF);
U1TXREG = *txbuf++;
}
}
Run Code Online (Sandbox Code Playgroud)
不同大小的数组(5 或 21 字节)被发送到这个函数,它们的大小和一个简单的 for 循环遍历每个字节并通过 UART tx 寄存器 U1TXREG 输出它。
现在,我想实现DMA来减轻传输大量数据时对系统的压力。我已将 …
我需要与基于 AXI-burst 接口的 FPGA 设备进行通信。在不涉及 DMA 的情况下,通过 Linux 访问此类设备的方法有哪些?突发是 AXI 标准的固有属性,通常应在传输大量数据时自动触发。更大的问题是 FPGA 被设计为仅响应 AXI 总线上的突发类型请求。因此,当应用程序尝试顺序复制时,这会导致 Linux 上出现严重问题。我已经尝试过了memcpy,但它不起作用。
DMA 控制器存在于磁盘、网络设备上。因此他们可以直接将数据传输到主存储器。那么处理器芯片内部的DMA控制器有什么用?我还想知道,处理器芯片外部是否有不同的总线(i2c,pci,spi)而处理器内部只有一条总线(AXI)。这是如何工作的?(应该\xe2\x80\x99t它会导致一些瓶颈)
\n我需要在嵌入式 Linux(2.6.37) 中尽可能快地将传入的 DMA 缓冲区写入到 HD 分区作为原始设备 /dev/sda1。缓冲区按要求对齐,长度相等,为 512KB。该过程可能会持续很长时间并填充多达例如 256GB 的数据。我需要使用内存映射文件技术(O_DIRECT 不适用),但无法理解如何执行此操作的确切方法。所以,在伪代码“正常”写作中:
fd=open(/dev/sda1",O_WRONLY);
while(1) {
p = GetVirtualPointerToNewBuffer();
if (InputStopped())
break;
write(fd, p, BLOCK512KB);
}
Run Code Online (Sandbox Code Playgroud)
现在,我将非常感谢如何利用内存映射技术编写本文的类似伪/真实代码示例。
UPDATE2:感谢 kestasx,最新的工作测试代码如下所示:
#define TSIZE (64*KB)
void* TBuf;
int main(int argc, char **argv) {
int fdi=open("input.dat", O_RDONLY);
//int fdo=open("/dev/sdb2", O_RDWR);
int fdo=open("output.dat", O_RDWR);
int i, offs=0;
void* addr;
i = posix_memalign(&TBuf, TSIZE, TSIZE);
if ((fdo < 1) || (fdi < 1)) {
printf("Error in files\n");
return -1; }
while(1) {
addr = mmap((void*)TBuf, TSIZE, PROT_READ …Run Code Online (Sandbox Code Playgroud) 我正在尝试让 UART 传输在 stm32f405 上通过 DMA 工作。我的应用程序的这一部分旨在作为命令行界面发送文本字符串。我让 UART 的 RX 部分与 DMA 配合良好(使用 1 字节循环 DMA 来处理传入的任何内容),但 TX 端被证明有点棘手。
我可以使用以下方式发送数据字符串:HAL_UART_Transmit_DMA(&handle, pData[], strlen(pData))前提是函数的连续调用之间存在延迟。一旦我的程序决定依次发送两个字符串,新的数据指针就会被忽略。
通过使用,while(HAL_UART_Transmit_DMA(...) != HAL_OK){}我可以让程序等待所需的时间并发送连续的字符串。
这可以工作一段时间(几十次传输),然后由于 HAL_NOT_OK 而卡住。
作为参考,我的 DMA 设置是:DMA2 stream 7, channel 4, mem to periph, periph inc disabled, mem inc enabled, mem and periph align byte, normal mode (not circular), low priority, fifo disabled。
UART 设置为9600 baud, 8 bit word, …
我正在使用一台 STM32F4,我想与我的 LSM303 加速度计进行通信。为此,我使用 I2C,仅使用 I2C 工作正常,但当我尝试使用 DMA 时,它停止工作。当我使用 HAL_I2C_Master_Transmit_DMA 时,它可以工作,并且我得到了 IRQHandler 和 . 但是之后当我想使用 HAL_I2C_Master_Receive_DMA 时,它说 I2C 的状态尚未准备好...我读到 I2C 与 STM32FX 有点混乱,但我不明白为什么它在没有 DMA 的情况下工作正常。
此外,当它命中 Master_Transmit_DMA 的回调 I2C_DMAXferCplt 时,它表示 I2C_HandleTypeDef 的 CurrentState 仍然等于 HAL_I2C_STATE_BUSY_TX,因此它不会将状态恢复为 READY。这就是为什么当我调用 Master_Receive_DMA 时它没有收到任何东西。
这是我的 I2C 初始化:
void MX_I2C2_Init(void)
{
I2C_ST_INS.Instance = I2C2;
I2C_ST_INS.Init.ClockSpeed = 400000;
I2C_ST_INS.Init.DutyCycle = I2C_DUTYCYCLE_2;
I2C_ST_INS.Init.OwnAddress1 = 0;
I2C_ST_INS.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2C_ST_INS.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2C_ST_INS.Init.OwnAddress2 = 0;
I2C_ST_INS.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2C_ST_INS.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
HAL_I2C_Init(&I2C_ST_INS);
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(i2cHandle->Instance==I2C1) …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 I2S 麦克风 (Invensense ICS43432) 连接到运行 Arch Linux 的 Raspberry Pi (B+),但失败了。我已经在相关的 Arch Linux ARM 论坛中寻求了具体的建议,但我的问题实际上比这更笼统:如何调试 Linux 音频输入问题?
我已经使用逻辑分析仪验证了 I2S 麦克风正在正确的通道(左)和 Raspberry Pi 的正确引脚中发送敏感数据。I2S 麦克风在 ALSA 下显示为“声卡”。 arecord我非常高兴从该设备进行录音,并且我已将该设备的增益提高了alsamixer30 dB。然而记录文件的所有数据字节都是零。
在Linux下如何检查音频数据流、DMA操作?
我正在 Qemu 上编写 PCI 设备,并在来宾操作系统中编写驱动程序(LKM)。虽然 Qemu 提供了一个示例 PCI 设备edu(edu.txt和edu.c)及其发行版,但我在编写内核模块来进行 DMA 传输时遇到了问题。这里介绍了一个基本的驱动程序,但它不支持 DMA。
我正在跟踪 link 和this的实现。我尝试将缓冲区从 IRQ 处理程序传输到 PCI 设备。设备可以读取数据(pci_dma_read),但我没有得到我应该接收的正确数据。这是进行 DMA 传输的代码段:
static int write_to_HyPerf(void *dev, void* addr, uint32_t size)
{
/* ----------------------------------------------------------------------------
* PCI address 'addr':
* addr -> DMA source address
* 0x40000 -> DMA destination address
* 100 -> DMA transfer count
* 1 -> DMA command register
* while (DMA command register & 1)
*-------------------------------------------------------------------------------- …Run Code Online (Sandbox Code Playgroud)