DMAengine PCM 缓冲与实时性

DMAengine PCM 缓冲与实时性

1. 数据路径

1
2
3
4
5
userspace ALSA ring
-> coherent/streaming DMA buffer
-> DMAengine cyclic descriptor
-> Rockchip I2S/PDM/SPDIF FIFO
-> serial pins / codec

Capture 方向相反。

2. 公共层

core/pcm_dmaengine.csoc-generic-dmaengine-pcm.c 提供:

  • DMA channel request;
  • slave config;
  • cyclic prep;
  • submit/issue pending;
  • residue 转 PCM pointer;
  • period callback;
  • pause/resume/terminate;
  • preallocated buffer。

Rockchip I2S/TDM、PDM、SPDIF Kconfig 通常 select SND_SOC_GENERIC_DMAENGINE_PCM

3. DMA data

CPU DAI 通过 snd_soc_dai_init_dma_data() 提供:

  • FIFO physical address;
  • bus width;
  • maxburst;
  • channel name;
  • flags。

hw_params 将 sample format 转 bus width,并建立 dma_slave_config

4. Cyclic DMA

DMA buffer 分成 periods,硬件循环:

1
buffer_bytes = period_bytes * periods

每 period completion 调 snd_pcm_period_elapsed()。过小 period 增加 IRQ/callback 和调度压力;过大增加基础延迟。

5. Pointer

通常根据 DMA residue:

1
pos = buffer_size - residue

DMA controller residue 粒度或延迟会影响时间戳和 avail。驱动需处理 residue=buffer size、环绕和暂停状态。

6. Buffer 分配

ALSA memalloc 支持 coherent DMA、SG、vmalloc 等类型。SoC DMA 常用 coherent buffer,并 mmap 给用户态。是否需要 cache sync 由 DMA API 和架构一致性决定,驱动不能直接假设所有 ARM64 DMA 完全 coherent。

7. XRUN 来源

  • period 太小;
  • CPU 调度/IRQ 延迟;
  • DMA IRQ 被屏蔽;
  • 错误 IRQ affinity;
  • DMA channel contention;
  • FIFO threshold/突发不匹配;
  • clock drift;
  • userspace未及时读写;
  • runtime PM/clock误关;
  • hw pointer错误。

8. 延迟估算

理论环形缓冲时长:

1
2
latency ≈ buffer_frames / sample_rate
period_time = period_frames / sample_rate

实际还包括应用、插件、PulseAudio/PipeWire、调度、codec filter、HDMI sink。

9. 调优

  1. 先用 hw: 绕过软件插件;
  2. 从稳定的大 buffer/period开始;
  3. 逐步减小 period;
  4. 观察 XRUN、CPU、IRQ;
  5. 固定 CPU 频率或 QoS 做对照;
  6. 设置合理实时优先级;
  7. 不把 period 设成 DMA 不支持的 burst/alignment。

10. 观测

1
2
3
4
cat /proc/interrupts
cat /proc/asound/card0/pcm0p/sub0/status
trace-cmd record -e snd_pcm -e dma_fence -e irq
aplay -v --period-size=1024 --buffer-size=4096 test.wav

可用 tracepoint 依本分支配置确认。

文章互动

阅读 --

留言

0 条留言

正在加载留言…