延伸DSP電路板配資料轉換器應用 分層驅動程式面世

數位訊號處理器(DSP)專門處理數位訊號,並提供強大的即時訊號處理能力;而資料轉換器連接處理真實世界類比訊號的裝置,同時提供數位訊號介面與DSP相連。DSP電路板的子卡介面提供一套增加資料轉換器的機制,可用來相連外部的類比應用,此外,DSP電路板還包含標準的資料轉換器。DSP電路板的支援套件(Board Support Packages, BSP)會提供這些標準轉換器的驅動程式,但設計人員須為轉換器子卡設計驅動程式。
轉換器有不同的組態參數、操作模式、實體連結和資料寬度,並用於控制和語音等不同的應用領域,這使驅動程式的設計更複雜。此外,開發人員若想發展適合特定平台的驅動程式,就須了解多執行緒環境及同步和非同步資料傳輸等作業系統限制,以及介質連接單元(MAU)、高低位元組順序(Endianism)和晶片內建周邊的程式設計等中央處理器核心特有的限制因素。本文將以德州儀器(TI)DSP和DSP/BIOS即時作業系統(RTOS)為基礎,探討驅動程式設計的影響因素,如轉換器特性、CPU核心的相依性及作業系統的驅動程式模型。  

DSP處理器執行即時訊號處理,並與馬達控制器等類比元件連接以取得外界訊號。類比與數位域之間的介面是由轉換器擔任,轉換器把某個域的訊號轉換成另一個域的訊號,如從類比到數位的轉換器稱為類比數位轉換器(ADC),從數位到類比的轉換器稱為數位類比轉換器(DAC);而編碼解碼器(Codec)則能在兩個域之間進行雙向轉換。標準DSP電路板上除特定轉換器外,還能透過子卡介面增加特定應用所需的轉換器,該介面會透過序列埠或處理器外部記憶體介面的記憶體映射周邊(Memory Mapped Peripheral)與處理器進行通訊,上述兩種方法為電路板與轉換器提供一套混合及搭配使用機制。  

轉換器的裝置驅動程式讓應用軟體獨立於底層轉換器之外,應用軟體將所有轉換器視為須要透過裝置驅動程式設定組態和控制並能交換資料的周邊裝置。裝置驅動程式須了解轉換器管理的所有相關細節。為進一步了解這些細節,本文首先從一般性角度討論轉換器,包括轉換器驅動程式所須了解的細節,接著從終端應用、使用者的角度介紹轉換器驅動程式的需求,並詳細說明如何透過建議的轉換器驅動程式架構及其實作達成這些要求,而關於驅動程式還會談到如何應付轉換器驅動程式的細微差別,最後將討論現有限制和未來改進。  

資料轉換器影響因素包含多種  

資料轉換器傳統上分為類比數位轉換器、數位類比轉換器及語音頻帶或音訊頻帶編碼解碼器三大類。此分類方式雖對資料傳送的方向及同時處理的通道數目等低階驅動程式的發展有某些影響,但只是驅動程式設計的因素之一,其他可能影響發展的因素包括以下各點:

資料轉換器技術
  有些技術對於從資料轉換器取出轉換結果的時間較不在意,管線式(Pipelined)資料轉換器即為一例。另外,逐次漸近暫存器(Successive Approximation Register, SAR)資料轉換器為確保轉換結果的精確度而對讀取資料的時間嚴格限制,這會限制應用系統與資料轉換器間的通訊實作。
資料轉換器應用領域
  不同的資料轉換器應用需不同的資料傳輸方式,有些工業控制應用必須控制讀取動作以便取得應用所需的一段資料;其他的語音和音訊處理應用則需要連續的資料串流。介面延遲使先進的DSP不適合採用連續傳輸方式,因此須利用某種機制將串流分成一塊一塊的資料,然後逐一傳送這些資料區塊。換言之,可根據資料轉換器的資料傳送方式把資料轉換器分為連續資料轉換器(Continuous Converter)或控制資料轉換器(Control Converter)。
處理器與資料轉換器間的介面機制
  資料轉換器可透過DSP的多通道緩衝式序列埠(McBSP)等序列介面或並列記憶體介面連接到處理器。若採用序列介面,資料轉換器會透過一個接收或傳送事件旗標或中斷(Interrupt)通知處理器將透過序列埠進行資料傳輸;若採用並列介面,資料轉換器的暫存器會映射到DSP的記憶體空間,接著轉換器會透過外部中斷接腳將事件通知處理器。因此,可根據資料轉換器傳輸資料所用的介面周邊將資料轉換器分為序列型和並列型。
資料轉換器資料寬
  資料轉換器資料寬度、CPU字元長度和介面周邊的資料傳輸長度不見得相同,如16位元處理器透過16/32位元McBSP連至24位元管線式類比數位轉換器,應用軟體的緩衝區須足以容納轉換器送來的24位元資料,驅動程式還要實作一套狀態機器以便與轉換器交談,表示驅動程式須開啟一個輸出通道以傳送命令至轉換器。另外,實體線路每次所能傳送的資料量可能小於轉換器的資料寬度,因此驅動程式必須保留轉換器多次傳送的資料,然後將資料組成正確的結果。

資料轉換器驅動程式的終端應用考量  

資料轉換器的驅動程式設計須了解前述所有的影響因素,以下討論應用情境(Usage Scenario)帶來的另外要求,即驅動程式的設計必須把終端應用使用者的兩項重要需求列入考慮,包括易於使用的資料轉換器組態設定介面,以及驅動程式須能在即時/非即時作業系統環境工作。

易於使用的資料轉換器組態設定介面
  資料轉換器種類繁多,又有各種不同組態,因此須易於使用的組態設定介面。舉例來說,一個資料轉換器可能有十個不同的組態暫存器,還有硬體規格詳細描述暫存器內每個位元代表的功能。應用開發人員不僅須了解所要求的功能,還要能針對特定組態將特定暫存器設為特定值,但此過程很容易出錯。
驅動程式須能在即時/非即時作業系統環境工作
  DSP上運行的簡單解碼器演算法可能不會用到大部分的即時作業系統服務,這類應用不會啟動多個執行緒,故可將即時作業系統服務視為額外負擔。儘管如此,應用軟體仍須裝置獨立的驅動程式控制/設定轉換器及進行資料傳輸,可見裝置驅動程式須能在獨立與耦合(Coupled)的環境工作。

資料轉換器組態藉由提供一套前端圖形使用者介面(GUI)進行管理,此GUI介面允許開發人員從功能層級直接設定資料轉換器的組態參數,而不是暫存器層級,這樣能把暫存器的低階細節隱藏,進而增加資料轉換器的抽象性。GUI根據開發人員輸入的組態為資料轉換器產生一個資料結構,此資料結構即可用來設定資料轉換器的組態,GUI還會驗證設計人員輸入的組態是否有效,同時將無效的資料轉換器參數組合告知設計人員。  

資料轉換器組態還會提供一組資料轉換器程式範本(Template),使前端GUI能根據此範本和資料轉換器組態產生C語言程式碼,這組程式範本包括每一種資料轉換器的第一層迷你驅動程式(Mini Driver Layer 1)。以德州儀器DSP/BIOS驅動程式為例,其為兩層式驅動程式模型,其中針對底層裝置的低階驅動程式稱為迷你驅動程式,負責執行裝置初始設定、控制、讀取/寫入作業、緩衝器管理和中斷處理。上層驅動程式則稱為類別驅動程式(Class Driver),負責作業同步。此驅動程式模型針對不同類別的應用提供PIO、SIO和GIO等不同類別的驅動程式,應用軟體可透過裝置中獨立的類別驅動程式使用這些驅動程式,再由類別驅動程式執行適當的迷你驅動程式。  

應用軟體可靜態或於執行期間動態註冊裝置驅動程式,DSP/BIOS API DEV_createDevice就能在執行期間向作業系統註冊裝置驅動程式,此API接受裝置名稱、驅動程式的初始設定函式、對應於迷你驅動程式功能的函式指標表、初始設定參數和裝置識別碼,API亦可呼叫迷你驅動程式的裝置初始設定函數。SIO類別驅動程式提供一套裝置獨立的I/O機制,基本上會提供下列API:

SIO_init
  作業系統會在啟動階段呼叫此函式,再由此函式針對所有須靜態註冊的裝置驅動程式呼叫適當的裝置初始設定函式。
SIO_create
  此API根據裝置名稱、輸入或輸出模式、預設組態參數等輸入參數建立一個SIO通道,應用軟體可利用函式傳回的通道與裝置驅動程式互傳資料。SIO_create會在程式內部建立SIO API與miniDriver API之間的對應關係。
SIO_get
  此API從驅動程式取得一筆資料,同時將下一個須填滿資料的緩衝區傳給驅動程式。
SIO_put
  此API將資料傳給轉換器,並取得一個空的緩衝區,對應於驅動程式前一次執行的資料傳輸動作。
此外,不同的類別驅動程式會使用同一組迷你驅動程式,因此迷你驅動程式須提供下列功能,且每種裝置都要實作這些API。
mdBindDev
  此函式是裝置驅動程式的初始設定函式。對於靜態註冊的裝置驅動程式,此函式是由SIO_init函式呼叫;對於執行期間註冊的裝置驅動程式,此函式是由DEV_createDevice函式呼叫。
mdCreateChan
  此函式由SIO_create函式呼叫,用來建立迷你驅動程式的通道。
mdSubmitChan
  此API用來傳送封包,封包內容包括資料緩衝區及現行傳輸動作是採用緒(Blocking)或回呼函式(Call Back)等資訊。SIO_get/put會產生一個資料傳輸封包(Transaction Packet),並呼叫此API。

分層式架構解決資料轉換器驅動程式問題  

分層式架構(圖1)是為解決在即時作業系統和非即時作業系統環境下,提供資料轉換器驅動程式的問題。迷你驅動程式架構分為兩層,底層稱為第一層迷你驅動程式(Mini-Driver-Layer-1),負責提供控制、組態設定及與資料轉換器間的資料傳輸等功能,這層功能與作業系統完全無關。迷你驅動程式的上層則稱為第二層迷你驅動程式(Mini-Driver-Layer-2),負責提供緩衝區管理及做為DSP/BIOS迷你驅動程式所需的語義功能。低階驅動程式透過晶片支援程式庫(Chip Support Library, CSL)使用EMIF、McBSP、DMA等介面周邊。

圖1 驅動程式架構分層圖

第一層迷你驅動程式負責與轉換器進行傳輸  

第一層迷你驅動程式控制、設定和執行其與資料轉換器之間的資料傳輸。迷你驅動程式利用底層的晶片支援程式庫設定介面周邊,並提供一組與資料轉換器無關的標準API供外界使用。這層驅動程式的函式表(Function Table)也包含這些函式的函式指標,讓上面各層不受資料轉換器影響以獨立使用這些API。  

驅動程式擁有介面周邊和底層轉換器組態參數的相關資料。所有透過McBSP進行通訊的序列資料轉換器都由一個稱為DCP_SERIAL的資料結構代表;並列資料轉換器則是由一個稱為DCP_PARALLEL的資料結構代表。由於底層轉換器的組態元素是各資料轉換器特有的資料,因此每一種資料轉換器在這個部分的表示資料(Representation)都會不同。  

資料轉換器的驅動程式表、周邊表示資料和組態參數都是某個資料結構的一部分。此結構代表驅動程式的資料元素,稱為資料轉換器資料結構(Converter-Data-Structure, CDS),資料結構的指標則代表驅動程式的代碼(Handle)。另外,低階驅動程式提供六個函式介面:

TIDCSTATUS configure (void *pDc)
  此函式可設定資料轉換器的組態。其先根據代碼開啟介面周邊,再透過該周邊設定資料轉換器的組態。函式參數pDc會指向CDS資料結構,其中包含資料轉換器的組態參數和介面周邊的相關資訊。
void power(void *pDc, int bDown)
  此函式可將資料轉換器開機或關機。
long read(void *pDc)
  此函式採取輪詢(Polling)方式,並回傳函式從資料轉換器讀取的資料。凡是從資料轉換器讀取一個單位的資料時都會採用輪詢的方式,因為就時間而言,透過輪詢從資料轉換器讀取一個單位的資料遠比中斷機制更有效率。
void write (void *pDc, long lData)
  此函式採取輪詢的方式,函式會將資料寫入資料轉換器然後離開。
void rblock(void *pDC, void *pData, unsigned long ulCount, void(*callback)(void *))
  此函式把緩衝區加入驅動程式內的佇列,等到pData所指的緩衝區填滿ulCount個字元的資料後,經由中斷機制所啟動的相關中斷服務常式(ISR)就會執行函式參數所設定的回呼函式。
void wblock(void *pDC, void *pData, unsigned long ulCount, void(*callback)(void *))
  此函式把緩衝區加入驅動程式內的佇列,等到pData所指的緩衝區已將其資料寫入資料轉換器後,經由中斷機制啟動的相關中斷服務常式就會執行函式參數所設定的回呼函式。

圖2所示為資料轉換器的資料結構。其中TTIDC結構類型(Structure Type)包含資料轉換器驅動程式的函式指標,能做為驅動程式的函式表;DCP_SERIAL是將介面周邊封裝的結構類型,所有序列轉換器的資料結構都會包含這個成員;TADS1216資料結構的其他成員還包括資料轉換器特有的各種屬性。上層軟體可看到CDC的一個全域實體(Global Instance),能透過此全域實體使用驅動程式的函式表。舉例來說,&Ads1216_l->configure(&Ads1216_l);這行程式就能透過Ads1216_l執行組態設定功能。

圖2 資料轉換器之資料結構

在資料轉換器中,還有幾個特定設計問題須注意:
輪詢式讀取/寫入功能
  對於資料轉換器,驅動程式須實作一套狀態機器以便讀取資料。以ADS1216資料轉換器為例,透過中斷機制執行讀取動作時,整個過程須八次中斷及其相關的服務時間。輪詢方式則僅須對McBSP執行三次的寫入和三次的讀取動作,因此輪詢方式的效能勝過中斷方式。
應用開發人員須了解輪詢式資料讀取動作,在多工環境裡,從轉換器讀取資料的工作在完成讀取前會阻止其他優先權較低的工作進入排程,這雖可能影響其他工作的執行,但由於控制類型的資料轉換器通常每次只讀取一個字元,需要連續資料的資料轉換器又會改用rblock函式,所以這個問題的實際影響並不大。
輪詢式初始化和組態設定
  轉換器的初始化和組態設定都是透過輪詢的方式完成,而不是採用中斷機制。初始設定階段通常會將中斷關閉,然後透過輪詢找出閒置可用的介面周邊、傳送和接收命令與回應,以及執行必要的資料傳輸動作。

第二層迷你驅動程式負責緩衝區管理

第二層迷你驅動程式須與轉換器無關,此驅動程式執行的重要功能包含:

建立與第一層迷你驅動程式API的關聯性
  建立第二層迷你驅動程式API與第一層迷你驅動程式API之間的關聯性,並呼叫適當的API完成資料轉換器組態設定、讀取和寫入功能、函式結束後執行先前註冊的回呼函式等工作。第一層迷你驅動程式可透過CDS元件間接使用其功能,資料轉換器相關元件會以裝置參數的方式傳給第二層迷你驅動程式,而第二層迷你驅動程式可透過資料轉換器相關元件內嵌的裝置函式表使用第一層迷你驅動程式的函式。
安裝中斷服務常式
  中斷服務常式的安裝需要名稱和對應功能的中斷編號。中斷服務常式的名稱會以組態參數的方式提供給驅動程式,晶片支援程式庫則提供API取得周邊裝置各種功能的中斷編號,如McBSP的接收中斷編號就能透過MCBSP_getRcvEventId (MCBSP_Handle hMcbsp)此API取得。
McBSP的晶片支援程式庫代碼(CSL Handle)儲存在CDS的DCP_SERIAL子物件。這層驅動程式須了解其所互動的資料轉換器為何種類型(序列或並列),再根據其類型存取CDS內的序列或並列子物件。
封包序列化
  裝置若正在執行傳輸動作,就將資料封包加入佇列等待傳送,第二層迷你驅動程式會提供一個旗標顯示轉換器是否正在執行傳輸動作。

此外,第二層迷你驅動程式在特定設計考量,有下列須注意的部分:

獨立中斷服務常式和DSP/BIOS中斷服務常式
  RTOS與RTOS獨立環境的中斷註冊及函式宣告機制並不相同。除此之外,中斷服務常式的功能在這兩個環境裡也有差異,宣告的問題可藉由提供一個組態選擇功能(Configuration Switch)解決。組態選擇功能可指定中斷須在RTOS或RTOS獨立的環境裡工作,在RTOS環境裡,第二層迷你驅動程式負責安裝中斷服務常式;在RTOS獨立的環境則是由第一層迷你驅動程式負責安裝。
read函式傳回值
  read函式的宣告型態為long read(void *pDc)。無論資料轉換器的資料傳輸長度為何,傳回值永遠是長整數。第二層迷你驅動程式與底層資料轉換器無關,所以無法得知應用軟體提供的緩衝區為16或32位元。為解決這個問題,第二層迷你驅動程式提供一個稱為IOMADC_ConvDataLength的類型定義(Typdef)以顯示轉換器的資料傳輸長度,第二層迷你驅動程式會將read函式的資料讀取結果轉換為IOMADC_ConvDataLength,應用軟體須根據資料轉換器的資料長度提供此定義。
資料轉換器週期組態
  有些資料轉換器每隔幾毫秒就要執行一次讀取動作,晶片內建計時器可用來支援這項功能。基本上,計時器是根據輸入時脈頻率進行計時,每隔幾毫秒就會產生一次中斷要求,除此之外,為確保這裡所用的計時器不會與DSP/BIOS衝突,晶片內建計時器還提供一個組態參數選擇計時器。
驅動程式組態參數
  根據以上討論,編譯這個驅動程式時必須指的是資料轉換器的資料傳輸長度、第一層迷你驅動程式的中斷服務常式名稱、資料轉換器的類型,如序列或並列的組態參數。驅動程式進行初始設定時,應用軟體須提供的組態參數包括CDS指標及介面周邊的相關組態參數。

資料轉換器現有限制及未來改進

以下將討論,資料轉換器現有的限制和未來如何改進的方式。

輪詢式讀取
  所有讀取動作都採用輪詢方式可讓資料轉換器提供更高的資料產出,優先權較低的工作也不會延誤太久。另一種值得嘗試的做法是提供一個組態參數,讓開發人員選擇不同方式設計資料讀取函式。
與高低位元組順序有關的資料轉換器暫存器表示法
  資料轉換器目前只能以低位元組在前(Little Endian)的方式表示暫存器的位元資料,如圖3所示。設計人員可考慮提供可設定的選擇功能(Configurable Switch),使所產生的程式碼也能支援高位元組在前(Big Endian)的模式。
圖3 暫存器的位元資料以低位元組在前的方式表示
以DMA為基礎的驅動程式
  並非所有的資料轉換器驅動程式都是以直接記憶體存取(DMA)為基礎。某些資料轉換器需一套商議協定(Handshake Protocol)以執行資料傳輸,因此不可能以DMA的方式傳送資料。資料轉換器雖會連續傳送資料,但其會將狀態資訊與資料元素一起傳送,只要高階應用軟體將資料與狀態資訊分開,設計人員就能為暫存器發展以DMA為基礎的驅動程式,目前的機制是由最低階的資料轉換器驅動程式負責將資料與狀態資訊分開,並且將資料寫入使用者提供的緩衝區。
然而,對於TLV320AIC23之類中元件所用的驅動程式,編碼解碼器傳送的資料並不會含有任何狀態資訊,因此這類驅動程式可以利用DMA傳送資料。總之,設計人員須針對個案分析是否應採用以DMA為基礎的驅動程式,不同的資料轉換器也可能需要不同的實作方式。

本文介紹轉換器驅動程式設計的兩個獨特層面,一是分層式驅動程式架構,另一是從驅動程式範本資料庫產生驅動程式的前端GUI介面。資料轉換器驅動程式的分層架構提供一套機制,讓驅動程式同時在RTOS和RTOS獨立的環境操作,第一層迷你驅動程式的API標準化、以序列/並列周邊類別為基礎的CDS資料結構,以及第二層迷你驅動程式的組態參數,是讓第二層迷你驅動程式與第一層迷你驅動程式進行交談的關鍵要素。前端GUI讓設計人員在功能層級上指定組態參數,而不是從暫存器層級,因此能增加轉換器組態的抽象性。  

(本文作者任職於德州儀器)

本站使用cookie及相關技術分析來改善使用者體驗。瞭解更多

我知道了!