天天看點

第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

視訊監控—ALSA驅動架構的簡單分析

  • 硬體平台:韋東山嵌入式Linxu開發闆(S3C2440.v3)
  • 軟體平台:運作于VMware Workstation 12 Player下UbuntuLTS16.04_x64 系統
  • 開發環境:arm-linux-gcc-4.3.2工具鍊、linux-3.4.2核心(開發版根檔案系統)
  • 源碼倉庫:https://gitee.com/d_1254436976/Embedded-Linux-Phase-3

目錄

  • 視訊監控—ALSA驅動架構的簡單分析
    • 一、ALSA的簡單介紹
    • 二、架構分析
      • 1、sound.c檔案分析
        • 1.1 `snd_open()`函數,關鍵`snd_minor`數組
        • 1.2 `snd_minor`數組來源:`snd_register_device_for_dev()`聲霸卡裝置注冊函數
        • 1.3 誰來調用`snd_register_device_for_dev()`,建立聲霸卡裝置結點
        • 1.4 小結
      • 2、control.c檔案分析
        • 2.1 `snd_ctl_dev_register()`的調用來源
        • 2.2 誰來調用`snd_ctl_create()`函數
        • 2.3 小結
      • 3、pcm.c檔案分析
        • 3.1 `snd_pcm_dev_register()`函數
        • 3.2 `snd_pcm_dev_register()`的調用來源
        • 3.3 小結
    • 三、整體總結

一、ALSA的簡單介紹

ALSA是在Linux核心中的進階Linux聲音體系結構,為Linux作業系統提供音頻和MIDI功能。其具有以下重要功能:

  • 對所有類型的音頻接口的有效支援,從消費類聲霸卡到專業的多通道音頻接口。
  • 完全子產品化的聲音驅動程式。
  • SMP和線程安全設計。
  • 使用者空間庫(alsa-lib)可以簡化應用程式程式設計并提供更進階别的功能。
  • 支援較早的Open Sound System(OSS)API,為大多數OSS程式提供二進制相容性。

Linux中ALSA的主要檔案:

  • include/sound/driver.h

  • sound/core/*.c

二、架構分析

此架構分析針對的是對聲霸卡的控制接口與裝置接口的結構,會忽略一些其他的東西。

1、sound.c檔案分析

通過入口函數

alsa_sound_init()

,來進行分析,得到如下圖:

1.1

snd_open()

函數,關鍵

snd_minor

數組

這個檔案的

file_operation

結構體對應的

.open

函數,其要做一些初始化工作,找到對應的裝置fops結構體:

  1. 得到某個裝置的次裝置号
  2. 根據次裝置号在

    snd_minor

    數組中找到對應

    snd_minor

    結構體
  3. 擷取到對應的

    fops

    結構體
    第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

1.2

snd_minor

數組來源:

snd_register_device_for_dev()

聲霸卡裝置注冊函數

那麼

snd_minor

數組來自于哪裡呢?

通過在

sound.c

檔案中搜尋

snd_minor

數組,找到在

snd_register_device_for_dev()

函數構造:

  1. 根據傳進來的參數設定

    preg

    ,即

    snd_minor

    結構體
  2. 把設定好的

    preg

    放入

    snd_minors

    數組中
  3. 建立裝置
    第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

1.3 誰來調用

snd_register_device_for_dev()

,建立聲霸卡裝置結點

那麼誰來調用

snd_register_device_for_dev()

來建立聲霸卡裝置呢?

通過在核心中搜尋,得到以下結果:

分為兩個分支進行:

  • control.c檔案的

    snd_ctl_dev_register()

    函數(

    snd_register_device_for_dev()

    在core.h中定義的

    snd_register_device()

    函數中被調用,

    snd_register_device()

    最終在control.c檔案的

    snd_ctl_dev_register()

    函數調用)
  • pcm.c檔案的

    snd_pcm_dev_register()

    函數
    第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

1.4 小結

在sound.c檔案中,主要做了一下事情:

  1. 調用

    snd_register_device_for_dev()

    ,根據傳入的參數構造了

    snd_minor

    數組,并把傳入的

    fops

    結構體放入到數組中;
  2. 在sound.c檔案的

    fops

    結構體的

    .open

    函數,擷取到裝置的

    fops

    結構體

2、control.c檔案分析

2.1

snd_ctl_dev_register()

的調用來源

通過在control.c檔案中的追蹤可以知道:

  1. snd_ctl_create()

    函數中,建構了

    snd_device_ops

    結構體,在結構體内部把

    snd_ctl_dev_register()

    聯系起來;
  2. snd_ctl_dev_register()

    函數中,把control.c檔案中建構的

    file_operations

    結構體傳入到

    snd_register_device()

    函數中,同時制定了這個控制接口的名字

    sprintf(name, "controlC%i", cardnum);

  3. snd_register_device()

    函數中,最終通過

    snd_register_device_for_dev()

    函數把

    file_operations

    結構體放入到

    snd_minor

    數組
  4. 通過名字可以知道,control.c檔案中建構的

    file_operations

    結構體,即

    snd_ctl_f_ops

    ,是與聲霸卡控制接口相關的結構體。
    第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

2.2 誰來調用

snd_ctl_create()

函數

通過核心的檢索在發現:

  1. init.c

    檔案中的

    snd_card_create()

    中調用了

    snd_ctl_create()

    第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

2.3 小結

通過分析可以知道,這個分支的主要作用:

  1. 建立聲霸卡的控制接口
  2. 調用

    snd_register_device_for_dev()

    ,把與控制接口相關的fops結構體放入到

    snd_minior

    數組中.
  3. 聲霸卡控制接口的名字為

    controlC%i

3、pcm.c檔案分析

3.1

snd_pcm_dev_register()

函數

在這個函數中,主要完成如下事:

  1. 根據傳入的裝置類型(錄音/播放),注冊對應的聲霸卡裝置
  2. 制定聲霸卡裝置的名字
  3. 根據上述資訊,注冊聲霸卡裝置節點
    第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

3.2

snd_pcm_dev_register()

的調用來源

通過在pcm.c檔案中尋找可以知道如下調用順序:

  1. 與上述control.c分析和相似的,在

    _snd_pcm_new()

    函數中建構了

    snd_device_ops

    結構體,在結構體内部把

    snd_pcm_dev_register()

    聯系起來;
    第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

3.3 小結

通過分析可以知道,這個分支的主要作用:

  1. 建立聲霸卡的裝置接點,對于聲霸卡的錄音與播放,可以建立兩個不同的裝置節點;
  2. 最終調用

    snd_register_device_for_dev()

    ,把與裝置相關的fops結構體放入到

    snd_minior

    數組中.
  3. 聲霸卡裝置接口的名字為

    pcmC%iD%ip

    (播放)與

    "pcmC%iD%ic"

    (錄音)(其中, C0D0代表的是聲霸卡0中的裝置0, pcmC0D0c最後一個c代表capture, pcmC0D0p最後一個p代表

    playback)

三、整體總結

通過上述的分析,得到了如下的架構圖:

  1. 主要分為兩個分支:注冊聲霸卡控制節點與聲霸卡裝置節點
  2. 在注冊聲霸卡控制節點分支中:

    2.1 配置設定了記憶體,用來設定控制節點的結構體

    2.2 制定了節點的名字

    2.3 構造了控制接口相關的fops結構體

    2.4 最終調用

    snd_register_device_for_dev()

    ,把與控制接口相關的fops結構體放入到

    snd_minior

    數組中
  3. 在注冊聲霸卡裝置節點分支中:

    3.1 配置設定了記憶體,用來設定聲霸卡裝置節點的結構體

    3.2 制定了聲霸卡裝置節點的名字

    3.3 構造了聲霸卡裝置節點相關的fops結構體

    3.4 最終調用

    snd_register_device_for_dev()

    ,把與聲霸卡裝置節點相關的fops結構體放入到

    snd_minior

    數組中
  4. 在sound.c中,當使用者打開聲霸卡裝置時

    4.1 得到某個裝置的次裝置号

    4.2 通過上述步驟得到的

    snd_minior

    數組中,根據次裝置好找到對應的

    snd_minor

    結構體

    4.3 進而在

    snd_minor

    結構體中獲得對應的fops結構體
第三階段應用層——2.10 視訊監控—ALSA驅動層架構的簡單分析 視訊監控—ALSA驅動架構的簡單分析

繼續閱讀