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