ALSA PCM 运行状态机与数据路径
1. 对象
1 | snd_card |
runtime 保存 hw constraints、format/rate/channels、buffer/period、状态、hw_ptr/appl_ptr、wait queue 和 mmap control/status。
2. 设备打开
1 | open("/dev/snd/pcmC0D0p") |
同一 PCM device 可有多个 substream,但硬件/ASoC link 常只暴露一个。
3. 配置
用户态顺序:
HW_REFINE探测可行参数;HW_PARAMS确定 access/format/rate/channels/buffer/period;- 分配 DMA buffer;
- 驱动
hw_params配置 DAI/DMA; SW_PARAMS设置 start/stop threshold、avail_min、silence;PREPARE清状态并准备硬件。
ALSA constraint 求交确保 CPU DAI、codec DAI、platform DMA 与 machine policy 都能接受参数。
4. 状态
1 | OPEN -> SETUP -> PREPARED -> RUNNING |
非法状态 ioctl 返回 EBADFD 等;XRUN 后通常需 prepare 恢复。
5. Playback
1 | userspace write/mmap |
若 DMA 消费追上 appl_ptr,发生 underrun。
6. Capture
1 | PDM/I2S FIFO -> cyclic DMA writes ring |
若 producer 覆盖未读取数据,发生 overrun。
7. Pointer
驱动 pointer() 返回当前 DMA hardware position(frame)。Core 结合 boundary 处理环绕并校验跳变。错误 pointer、丢 period callback 或 IRQ 延迟均可能造成 XRUN/hw_ptr 异常。
8. mmap
ALSA 映射:
- DMA data buffer;
- status page;
- control page。
用户态直接读写 ring,但必须使用正确内存屏障和同步协议。mmap 减少 syscall/copy,不代表 DMA 一定 cache coherent。
9. 锁
- PCM open mutex;
- runtime stream lock:atomic PCM 使用 spinlock,
nonatomicPCM 使用 mutex; - group/link lock;
- card controls/files 锁;
- ASoC runtime/card mutex。
period callback 多在 DMA tasklet/IRQ 类上下文,不能执行可睡眠操作。
10. 关键文件
core/pcm.ccore/pcm_native.ccore/pcm_lib.ccore/pcm_memory.ccore/memalloc.ccore/pcm_dmaengine.c
11. 观测
1 | cat /proc/asound/cards |
正在加载留言…