• ALSA声卡笔记1---ALSA驱动框架


    1、声卡驱动程序sound.c

    (1)入口函数里通过register_chrdev()函数注册file_operations 结构体

    (2)file_operations 结构体,里面只有open函数,没有发现读写函数,可知open函数是起中转作用的函数,肯定会找到一个新的file_operations 结构体


    (3)调用过程

    • 以minor变量保存传入节点inode结构体的次设备号
    • 以minor为下标在结构体数组中取出一项,让mptr指针指向此项
    • 表示取出mptr结构体指针里的file_operations 结构体
    • 调用file_operations 结构体里面的open函数


    2、谁来设置snd_minors[]结构体数组

    (1)谁来设置snd_minors[]结构体数组


    函数里面有数组项snd_minors外,为了mdev或udev能自动创建设备节点,我们有class_create()函数创建类,下面创建设备device_create(),类在Sound_ core.c入口函数里面被创建,sound.c的入口函数里面注册字符设备函数,snd_register_device_for_dev()函数里面创建声卡逻辑设备时有device_create()


    (2)snd_register_device_for_dev()函数被谁调用(有两路调用)

    一路声卡设备的控制接口

    另一路声卡设备的数据接口


    两路分析之---第一路

    3、第一路调用分析

    (1)snd_register_device()被谁调用(Core.h)


    (2)创建声卡设备的控制接口函数snd_ctl_dev_register()被谁调用(control.c)



    (3)由上面可知函数snd_ctl_create()在init.c程序的


    中被调用

    (4)由可知创建一个snd_card结构体

    两路分析之---第二路

    4、第二路调用分析

    (1)创建声卡设备的数据接口函数snd_pcm_dev_register()函数被谁调用(Pcm.c)


    (2)创建一个新的PCM设备函数_snd_pcm_new()被谁调用


    (3)snd_pcm_new()被谁调用

    某个声卡的驱动程序

    5、代码框架重新梳理(第1路)

    (1)snd_card_create()函数(Init.c)


    除了创建一个snd_card结构体外,还会调用snd_ctl_create()


    这表示所有声卡里面,必定会有控制接口

    (2)创建控制类的逻辑设备snd_ctl_create()函数


    里snd_device_new()函数可以看出,对于同一个声卡,里面可能有多个逻辑设备,device应该就是逻辑设备的意思(有control、pcm等),参数SNDRV_DEV_CONTROL表示其类别,最终snd_ctl_dev_register()被调用

    (3)snd_ctl_dev_register()函数

    里面的snd_register_device()函数注册一个file_operations 结构体snd_ctl_f_ops


    (4)snd_register_device()函数


    (5)snd_register_device_for_dev()函数

    填充结构体数组snd_minors[]


    6、代码框架重新梳理(第2路)

    (1)snd_pcm_new()调用


    (2)_snd_pcm_new()调用  (创建播放流和录音流)


    创建声卡的逻辑设备,这个逻辑设备最后会导致snd_pcm_dev_register()函数被调用


    (3)snd_pcm_dev_register()函数


    (4)snd_pcm_f_ops结构体数组,第0项表示播放,第1项表示录音,在Pcm.c里

    7、创建设备节点的名字的取值(第1路)

    (1)snd_register_device_for_dev()函数里的device_create()函数,其中“%s”来源于name,这个name是snd_register_device_for_dev()函数传进来的参数



    (2)snd_register_device_for_dev()函数被 snd_register_device()函数调用,也就是snd_register_device_for_dev()函数里面的name参数是 snd_register_device()函数传过来的


    (3)snd_register_device()函数 snd_ctl_dev_register()函数调用,由下面可以看出name参数根据可知为controlC%i,C表示Card声卡,其中i值来源于右边的cardnum,这个cardnum来源于snd_card结构体中的成员。而snd_card结构体来源于snd_device结构体的snd_card结构体。


    8、创建设备节点的名字的取值(第2路)

    (1)snd_register_device_for_dev()函数里的device_create()函数,其中“%s”来源于name,这个name是snd_register_device_for_dev()函数传进来的参数



    (2)snd_register_device_for_dev()函数被snd_pcm_dev_register()函数调用


    里面的str参数正是name参数,下面有pcmC%iD%ip和pcmC%iD%ic,C表示Card的意思,%i表示哪一个声卡,D表示哪一个声卡下的哪一个逻辑设备,p表示播放,c表示录音


    9、总结(如何写alsa声卡驱动)

    (1)构造snd_card结构体snd_card_create()构造snd_card结构体并自动创建控制接口。调用函数snd_ctrl_create

    (2)初始化;如snd_pcm_new(),创建逻辑设备(播放设备或录音设备)

    (3)注册 snd_card_register


    转自:http://blog.csdn.net/qingkongyeyue/article/details/52328991

  • 相关阅读:
    ActiveSync合作关系对话框的配置
    WINCE对象存储区(object store)
    Wince 隐藏TASKBAR的方法
    Wince输入法换肤换语言机制
    poj 3080 Blue Jeans 解题报告
    codeforces A. Vasily the Bear and Triangle 解题报告
    hdu 1050 Moving Tables 解题报告
    hdu 1113 Word Amalgamation 解题报告
    codeforces A. IQ Test 解题报告
    poj 1007 DNA Sorting 解题报告
  • 原文地址:https://www.cnblogs.com/alan666/p/8311873.html
Copyright © 2020-2023  润新知