1. 程式人生 > >ALSA音效卡筆記1---ALSA驅動框架

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