alsa pcm函数调用流程

pcm_open()栈
请添加图片描述
用户的pcm_open()相当于先对ASoC各个驱动模块startup(),再做hw_params()。

pcm_open()
    pcm->fd = open("/dev/snd/pcmC0D0c")
        snd_pcm_capture_open()
            snd_pcm_open(SNDRV_PCM_STREAM_CAPTURE)
                snd_pcm_open_file()
                    snd_pcm_open_substream()
                        substream->ops->open()
                            soc_pcm_open()
                                cpu_dai->driver->ops->startup()
                                platform->driver->ops->open()
                                codec_dai->driver->ops->startup()
                                rtd->dai_link->ops->startup()
    ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_PARAMS, &params)
        snd_pcm_hw_params_user()
            snd_pcm_hw_params()
                substream->ops->hw_params()
                    soc_pcm_hw_params()
                        rtd->dai_link->ops->hw_params()
                        dai->driver->ops->hw_params()
                        platform->driver->ops->hw_params()
    ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)

pcm_read()栈
用户的pcm_read()相当于做从内核缓冲区到用户缓冲区的copy_to_user()。即把硬件写到内核缓冲区的数据拷贝到用户缓冲区。(mmap模式例外,其没有数据拷贝的动作,性能更好。)

pcm_read()
    if (!pcm->running)
        pcm_start()
        pcm->running = 1
    ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)
        snd_pcm_lib_read()
            snd_pcm_lib_read1(transfer)
                transfer(substream, appl_ofs, data, offset, frames)
                    snd_pcm_lib_read_transfer()
                        substream->ops->copy() *or* copy_to_user()

pcm_start()栈
用户的pcm_start()相当于对ASoC的各个驱动模块做prepare()和trigger(START)动作。

pcm_start()
    ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE)
        snd_pcm_prepare()
            snd_pcm_do_prepare()
                substream->ops->prepare()
                    soc_pcm_prepare()
                        rtd->dai_link->ops->prepare()
                        platform->driver->ops->prepare()
                        codec_dai->driver->ops->prepare()
                        cpu_dai->driver->ops->prepare()
    ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)
        snd_pcm_action_lock_irq()
            snd_pcm_do_start()
                substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START)
                    soc_pcm_trigger()
                        codec_dai->driver->ops->trigger()
                        platform->driver->ops->trigger()
                        cpu_dai->driver->ops->trigger()
                        rtd->dai_link->ops->trigger()

pcm_close()栈
用户的pcm_close()相当于对ASoC的各个驱动模块做trigger(STOP), hw_free()和shutdown()动作。

pcm_close()
    close(pcm->fd)
        snd_pcm_release()
            snd_pcm_release_substream()
                snd_pcm_drop(substream)
                    snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP)
                        snd_pcm_do_stop()
                            substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP)
                                soc_pcm_trigger()
                                    codec_dai->driver->ops->trigger()
                                    platform->driver->ops->trigger()
                                    cpu_dai->driver->ops->trigger()
                                    rtd->dai_link->ops->trigger()
                if (substream->hw_opened)
                    if (substream->ops->hw_free != NULL)
                        substream->ops->hw_free(substream)
                    substream->ops->close(substream)
                        soc_pcm_close()
                            cpu_dai->driver->ops->shutdown()
                            codec_dai->driver->ops->shutdown()
                            rtd->dai_link->ops->shutdown()
                            platform->driver->ops->close()
                    substream->hw_opened = 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值