【導讀】如果您的 MCU 應用程序需要處理數字音頻,請考慮采用多線程方法。使用多線程設計方法使設計人員能夠以直接的方式重用他們的設計部分。
如果您的 MCU 應用程序需要處理數字音頻,請考慮采用多線程方法。使用多線程設計方法使設計人員能夠以直接的方式重用他們的設計部分。
多核和多線程是設計實時系統的有效方法。使用這些技術,系統被設計為許多任務的集合,這些任務獨立運行并在需要時相互通信。將系統設計從大型單片代碼塊分解為更易于管理的任務,可以大大簡化系統設計并加快產品開發。因此,整個系統的實時屬性更容易理解。設計者只需要擔心每個任務實現的保真度,提出諸如“網絡協議是否正確實現?”之類的問題。
在本文中,我們將討論如何使用多線程或多核設計方法來設計對數據流進行操作的實時系統,例如數字音頻系統。我們使用幾個數字音頻系統來說明設計方法,包括異步 USB 音頻 2、以太網 AVB 和 MP3 播放器的數字基座。在展示如何有效地使用多核和多線程來設計所需的緩沖和時鐘方案之前,我們將簡要討論數字音頻、多核和多線程的概念。
數字音頻
在許多消費市場中,數字音頻已經取代了模擬音頻,原因有二。首先,大多數音頻源都是數字的。無論是以有損壓縮格式 (MP3) 還是以非壓縮格式 (CD) 交付,數字標準已經取代了傳統的模擬標準,例如磁帶和磁帶。其次,數字音頻比模擬音頻更容易處理。數據可以通過現有標準(例如 IP 或 USB)傳輸而不會丟失,并且硬件設計不需要任何“魔法”來降低本底噪聲。就數字路徑而言,本底噪聲是恒定的,不受移動電話可能引起的 TDMA 噪聲的影響。
數字音頻系統對樣本流進行操作。每個樣本代表一個或多個音頻通道在某個時間點的幅度,樣本之間的時間由采樣率控制。CD 標準有兩個通道(左聲道和右聲道)并使用 44.1 kHz 的采樣率。常見的音頻標準使用 2、6 (5.1) 和 8 (7.1) 通道,以及 44.1 kHz、48 kHz 或倍數的采樣率。我們使用 48 kHz 作為運行示例,但這絕不是唯一的標準。
多核和多線程
在多線程設計方法中,系統被表示為并發任務的集合。使用并發任務,而不是單一的單一程序,有幾個優點:
多任務是支持關注點分離的好方法,這是軟件工程最重要的方面之一。關注點分離意味著設計的不同任務可以單獨設計、實現、測試和驗證。一旦指定了任務之間的交互,團隊或個人就可以各自完成自己的任務。
并發任務提供了一個簡單的框架來指定系統應該做什么。例如,數字音頻系統將播放通過網絡接口接收的音頻樣本。換句話說,系統應該同時執行兩項任務:從網絡接口接收數據并在其音頻接口上播放樣本。將這兩個任務表示為單個順序任務是令人困惑的。
表示為并發任務集合的系統可以通過一個或多個多線程內核中的線程集合來實現(參見圖 1)。我們假設線程是在指令級調度的,就像XMOS XCore 處理器上的情況一樣,因為這使得并發任務能夠實時運行。請注意,這與 Linux 上的多線程不同,例如,線程被調度在具有上下文切換的單處理器上。這可能使這些線程對人類而言似乎是并發的,但對一組實時設備而言卻不是。
并發任務在邏輯上設計為通過消息傳遞進行通信,當兩個任務由兩個線程實現時,它們通過發送數據和控制通道進行通信。在內核內部,通道通信由內核本身執行,當線程位于不同的內核上時,通道通信通過交換機執行(參見圖 2)。
多線程設計已被嵌入式系統設計人員使用了數十年。為了實現嵌入式系統,系統設計人員過去常常使用大量微控制器。例如,在音樂播放器內部,可能會發現三個控制閃存、DAC 和 MP3 解碼器芯片的微控制器。
圖 1:線程、通道、內核、交換機和鏈接。并發線程通過內核內部、芯片上的內核之間或不同芯片上的內核之間的通道進行通信。
我們認為,現代多線程環境可以替代這種設計策略。單個多線程芯片可以替代多個 MCU,并提供任務之間的集成通信模型。該系統不必在單獨的 MCU 上的任務之間實現定制通信,而是作為一組通過通道進行通信的線程來實現。
使用多線程設計方法使設計人員能夠以直接的方式重用他們的設計部分。在傳統的軟件工程中,功能和模塊結合起來執行復雜的任務。但是,這種方法不一定適用于實時環境,因為依次執行兩個函數可能會破壞函數或模塊的實時性要求。
在理想的多線程環境中,實時任務的組合是微不足道的,因為它只是為每個新的實時任務添加一個線程(或核心)的情況。實際上,設計人員會對內核數量有所限制(例如,出于經濟原因),因此必須決定哪些任務將組成并發線程,以及哪些任務將作為集合集成到單個線程中的功能。
多線程數字音頻
一個數字音頻系統很容易拆分為多個線程,包括一個網絡協議棧線程、一個時鐘恢復線程、一個音頻傳輸線程,以及可選的用于 DSP、設備升級和驅動程序認證的線程。網絡協議棧可以像以太網/IP 棧一樣復雜并包含多個并發任務,或者像 S/PDIF 接收器一樣簡單。
圖 2:具有 24 個并發線程的三核系統的物理化身。頂部設備有兩個核心,底部設備有一個核心。
我們假設系統中的線程通過通道發送數據樣本進行通信。在這種設計方法中,線程是在單核還是多核系統上執行并不重要,因為多核只是為設計增加了可擴展性。我們假設每個線程的計算要求可以靜態建立并且不依賴于數據,這通常是未壓縮音頻的情況。
我們將把注意力集中在設計的兩個部分:線程之間的緩沖(以及它們對性能的影響)和時鐘恢復。一旦做出了這些設計決策,實現每個線程的內部就遵循正常的軟件工程原則,并且與人們預期的一樣難或容易。緩沖和時鐘恢復很有趣,因為它們都對用戶體驗有定性影響(促進穩定的低延遲音頻),并且在多線程編程環境中很容易理解。
緩沖
在數字解決方案中,數據樣本不一定在交付時進行傳輸。這需要緩沖數字音頻。例如,考慮一個采樣率為 48 kHz 的 USB 2.0 揚聲器。USB 層將在每 125 μs 窗口中傳輸六個樣本的突發。無法保證在 125 μs 的窗口中將傳送六個樣本,因此需要至少 12 個樣本的緩沖區,以保證樣本可以實時流式傳輸到揚聲器。
設計挑戰是建立適量的緩沖。在模擬系統中,緩沖不是問題。信號按時傳遞。在基于非實時操作系統設計的數字系統中,程序員通常堅持使用相當大的緩沖區(250 或 1,000 個樣本)以應對調度策略中的不確定性。然而,大緩沖區在內存方面、增加延遲方面以及證明它們足夠大以保證無點擊交付方面都是昂貴的。
多線程設計提供了一個很好的框架來非正式地和正式地推理緩沖并避免不必要的大緩沖區。例如,考慮上述 USB 揚聲器增加了環境噪聲校正系統。該系統將包括以下線程:
通過網絡接收 USB 樣本的線程。
過濾樣本流的一系列 10 個或更多線程,每個線程都有一組不同的系數。
使用 I 2 S將過濾后的輸出樣本傳送到立體聲編解碼器的線程。
從連接到麥克風采樣環境噪聲的編解碼器中讀取樣本的線程。
將環境噪聲二次采樣到 8 kHz 采樣率的線程。
建立環境噪聲頻譜特性的線程。
根據計算的光譜特性更改濾波器系數的線程。
所有線程都將在 48 kHz 基本周期的某個倍數上運行。例如,每個過濾線程將每 48 kHz 周期過濾一個樣本;交付線程將在每個周期交付一個樣本。每個線程也有一個定義的窗口,它在上面操作,以及一個定義的方法,通過這個方法推進這個窗口。例如,如果我們的過濾器線程是使用雙二階實現的,它將在一個包含三個樣本的窗口上運行,每個周期提前一個樣本。頻譜線程可以在每 64 個樣本推進 64 個樣本的 256 個樣本窗口(以執行 FFT(Fest Fourier Transform))上運行。
現在可以建立在同一周期運行的系統的所有部分,并將它們以同步部分的形式連接在一起。在這些同步部分內不需要緩沖區,盡管如果線程要在管道中運行,則需要單個緩沖區。在各個同步部分之間需要緩沖區。在我們的示例中,我們最終得到三個部分:
從 USB 接收樣本、過濾并以 48 kHz 傳輸的部分。
以 48 kHz 采樣環境噪聲并以 8 kHz 傳輸的部分。
建立頻譜特性并在 125 Hz 時更改濾波器設置的部分。
這三個部分如圖 3 所示。從 USB 緩沖區接收樣本的第一部分需要緩沖 12 個立體聲樣本。
圖 3:根據頻率分組在一起的線程。
傳遞的部分需要緩沖一個立體聲樣本。將 10 個過濾器線程作為管道運行需要 11 個緩沖區。這意味著從接收器到編解碼器的總延遲包括 24 個采樣時間,即 500 μs,并且可以添加一個額外的采樣以應對時鐘恢復算法中的中期抖動。這部分以 48 kHz 運行。
對環境噪聲進行采樣的第二部分需要在輸入端存儲一個樣本,并在二次采樣中存儲六個樣本。因此,在 48 kHz 或 145 μs 處有 7 個樣本延遲。
建立頻譜特性的第三部分需要以 8 kHz 的采樣率存儲 256 個樣本。不需要其他緩沖區。因此,環境噪聲和濾波器校正之間的延遲為 8 kHz 下的 256 個樣本,二次采樣時間為 145 μs,或剛好超過 32 ms。請注意,這些是我們選擇使用的算法的最小緩沖區大小;如果此延遲不可接受,則必須選擇不同的算法。
設計線程以對數據塊而不是單個樣本進行操作通常很容易,但這會增加所經歷的整體延遲,增加內存需求并增加復雜性。僅當有明顯的好處時才應考慮這一點,例如增加吞吐量。
計時數字音頻
數字音頻和模擬音頻之間的一個很大區別在于,模擬音頻基于此基礎采樣率,而數字音頻需要將時鐘信號分配給系統的所有部分。盡管組件都可以使用不同的采樣率(例如,系統的某些部分可能使用 48 kHz,而其他一些部分可能使用 96 kHz,中間有一個采樣率轉換器),所有組件都應就一秒的長度達成一致,并且因此在測量頻率的基礎上達成一致。
數字音頻的一個有趣特性是系統內的所有線程都與這個時鐘頻率的基數無關,假設有一個黃金標準的基頻。系統中的多個核心是否使用不同的晶體并不重要,只要它們對樣本進行操作即可。然而,在系統的邊緣,真正的時鐘頻率很重要,采樣在途中產生的延遲也很重要。
在多線程環境中,將留出一個線程來明確測量真實時鐘頻率,實施時鐘恢復算法,測量本地時鐘與全局時鐘,并在時鐘偏移上與主時鐘達成一致。
可以使用互連的底層比特率隱含地測量時鐘,例如 S/PDIF 或 ADAT。測量其中任何一個網絡上的每秒比特數將給出主時鐘的測量值。時鐘可以通過使用為此目的而設計的協議來明確測量,例如以太網上的 PTP。
在時鐘恢復線程中,可以實現一個控制循環,它估計時鐘頻率,并根據觀察到的誤差進行調整。在最簡單的形式中,誤差用作調整頻率的指標,但濾波器可用于減少抖動。該軟件線程實現了傳統上由 PLL 但在軟件中執行的功能,因此它可以廉價地適應環境。
結論
多線程開發方法使數字音頻系統能夠使用分而治之的方法進行開發,其中一個問題被分成一組并發任務,每個任務在多線程內核上的單獨線程中執行。
像許多實時系統一樣,數字音頻適合多線程設計方法,因為數字音頻系統顯然由一組處理數據的任務組成,并且還需要這些任務同時執。
免責聲明:本文為轉載文章,轉載此文目的在于傳遞更多信息,版權歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權問題,請聯系小編進行處理。
推薦閱讀: