1, 什么是SGI
SGI:软件触发中断(Software Generated Interrupt)。在arm处理器中,SGI共有16个,硬件中断号分别为ID0~ID15.它通常用于多核间通讯.SGI在Linux内核中通常被用作IPI中断(inter-processor interrupts).
在linux内核中,已经定义了如下的IPI中断,所以用户使用自定义的IPI中断时,建议使用8~15这些未用的中断
//arch\arm\kernel\smp.c
enum ipi_msg_type {
IPI_WAKEUP,
IPI_TIMER,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
IPI_CPU_STOP,
IPI_IRQ_WORK,
IPI_COMPLETION,
IPI_CPU_BACKTRACE,
/*
* SGI8-15 can be reserved by secure firmware, and thus may
* not be usable by the kernel. Please keep the above limited
* to at most 8 entries.
*/
};
2, ALSA DMA Buffer
APP -> 驱动 -> 硬件声卡 -> DAC -> 播放出去
DMA(Direct Memory Access,直接内存存取),顾名思义,不占用cpu资源,从一个硬件存储区域把一部分连续的数据复制到另一个硬件存储区域。
这里的用例就是:
录音时,把录音数据从I2S搬运到驱动内存。
放音时,把驱动里的播放数据搬到I2S。
1, DMA Buffer的分配
音频初始化创建pcm的时候会调用soc_new_pcm():
soc_new_pcm -> soc-pcm.c
platform->driver->pcm_new ->
dmaengine_pcm_new -> soc-generic-dmaengine-pcm.c //这里就调用到了。
snd_pcm_lib_preallocate_pages -> //参数config->prealloc_buffer_size前面说了config->pcm_hardware->buffer_bytes_max在rockchip_pcm_hardware结构中赋值。
snd_pcm_lib_preallocate_pages1 ->
preallocate_pcm_pages -> //预分配
snd_dma_alloc_pages -> pcm_memory.c
dmab->area = snd_malloc_dev_pages(......,dmab->addr)) //type是SNDRV_DMA_TYPE_DEV, dmab->area存虚拟地址,dmab->addr存物理地址
dmab->bytes = size; //保存分配的size
2, 分配完后的DMA buffer注册到DAI和runtime当中
A,分配完成之后,snd_pcm_set_runtime_buffer->dma的buffer信息会被放到pcm runtime中管理
B,snd_soc_dai_set_dma_data() -> I2S的buffer 信息放到dai中, 这样snd_soc_dai_get_dma_data()就可以获取到了.
3, 用户空间就可以直接访问DMA Buffer了
snd_pcm_capture_ioctl -> pcm_lib.c
snd_pcm_capture_ioctl1 ->
snd_pcm_lib_read ->
snd_pcm_lib_read1 ->
snd_pcm_lib_read_transfer
Reference:
https://blog.csdn.net/qq_23274715/article/details/103524515