DMAengine PCM 缓冲与实时性
1. 数据路径
1 | userspace ALSA ring |
Capture 方向相反。
2. 公共层
core/pcm_dmaengine.c 和 soc-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 | latency ≈ buffer_frames / sample_rate |
实际还包括应用、插件、PulseAudio/PipeWire、调度、codec filter、HDMI sink。
9. 调优
- 先用
hw:绕过软件插件; - 从稳定的大 buffer/period开始;
- 逐步减小 period;
- 观察 XRUN、CPU、IRQ;
- 固定 CPU 频率或 QoS 做对照;
- 设置合理实时优先级;
- 不把 period 设成 DMA 不支持的 burst/alignment。
10. 观测
1 | cat /proc/interrupts |
可用 tracepoint 依本分支配置确认。
正在加载留言…