<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > DSP/BIOS中的I/O設備驅動(dòng)編程技術(shù)

DSP/BIOS中的I/O設備驅動(dòng)編程技術(shù)

作者: 時(shí)間:2006-05-07 來(lái)源:網(wǎng)絡(luò ) 收藏

摘要:介紹了/BIOS中I/O設備驅動(dòng)程序的編寫(xiě),并給出了一個(gè)在TMS320C5402 DSK上開(kāi)發(fā)語(yǔ)音處理程序的實(shí)例。

本文引用地址:http://dyxdggzs.com/article/242273.htm

關(guān)鍵詞:器() 實(shí)時(shí)操作系統 I/O設備驅動(dòng) 應用程序接口(API)

近年來(lái),隨著(zhù)信息技術(shù)的飛速發(fā)展,在航空、航天、雷達、通信、消費類(lèi)電子設備等方面都得到了廣泛應用;同時(shí),DSP的運算能力也越大越強大,TI公司新推出的TMS320C6400系列的運算能力可以達到8800MIPS。這些都要求開(kāi)發(fā)DSP的應用程序要縮短開(kāi)發(fā)時(shí)間,增加軟件的可編護性和可重用性。語(yǔ)音壓縮、語(yǔ)音識別、圖像處理等方面的應用要求DSP的開(kāi)發(fā)盡可能簡(jiǎn)單,還要求代碼的執行效率高。

DSP/BIOS是TI公司推出的一個(gè)實(shí)時(shí)操作系統。DSP/BIOS與TI的CCS(Code Composer Studio)集成在一起。目前最新的版本是CCS 1.2中的DSP/BIOS II。應用DSP/BIOS可以大大簡(jiǎn)化DSP應用程序的開(kāi)發(fā)和調試。與外部設備的I/O接口是DSP應用開(kāi)發(fā)中不可缺少的重要部分?;贒SP/BIOS的I/O設備驅動(dòng)將軟件與硬件分離,提高了軟件的可重用性,在軟件或硬件改動(dòng)時(shí)可使相互的影響降為最小。

1 DSP/BISO操作系統簡(jiǎn)介

DSP/BIOS實(shí)際上是一組可重復調用的系統模塊API的集合。只占用DSP很少的資源,可以滿(mǎn)足DSP實(shí)時(shí)運行時(shí)的調試性能分析,編寫(xiě)高效的程序。例如,在TMS320C6211上運行printf()函數需花費4000個(gè)周期,而運行LOG_printf()只花費36個(gè)周期,可printf()要比LOG_pfrintf()多花費100倍以上的時(shí)間。下面只對與I/O設備驅動(dòng)有關(guān)的模塊作簡(jiǎn)要介紹。

1.1 任務(wù)調度模塊(HWI/SWI/TSK)

在DSP/BIOS中,任務(wù)的調度是通過(guò)HWI、SWI和TSK三個(gè)模塊實(shí)現的。HWI(硬件中斷管理模塊)管理硬件中斷,主要負責DSP與外設的交互,從外設中讀寫(xiě)數據。由于硬件中斷直接與硬件打交道,對應的中斷服務(wù)程序ISR應盡可能短小精焊。HWI不引起任務(wù)調度,它在處理完數據的輸入輸出后調用SWI_post()來(lái)調度相應的軟件中斷SWI完成數據處理工作。

DSP/BIOS提供兩類(lèi)優(yōu)先線(xiàn)程:SWI(軟件中斷管理模塊)和TSK(任務(wù)管理模塊)。SWI是DSP/BIOS任務(wù)調度的核心,SWI任務(wù)是搶斷式的,即高優(yōu)先級的任務(wù)可以搶斷低優(yōu)先級的任務(wù)。但是SWI任務(wù)是不可阻塞的,所有SWI任務(wù)共享一個(gè)堆棧,SWI任務(wù)只能在程序編制時(shí)預先定義好。DSP/BIOS中對任務(wù)的動(dòng)態(tài)產(chǎn)生和對阻塞狀態(tài)的支持是通過(guò)TSK模塊來(lái)實(shí)現的。TSK也是可以搶斷的,但每個(gè)TSK任務(wù)使用獨立的堆棧。

1.2 通訊模塊(PIP/SIO)

PIP(帶緩沖管道管理模塊)和SIO(流輸入輸出管理模塊)是DSP/BIOS提供的兩個(gè)接口對象,用于支持DSP與外設之間 數據交換。PIP對象帶有一個(gè)緩沖隊列,可以執行帶緩沖的讀任務(wù)和寫(xiě)任務(wù)。SIO沒(méi)有緩沖隊列,SIO的操作get()和put()在應用程序和驅動(dòng)程序之間交換緩沖的指針,而不是數據的拷貝,因此執行效率比PIP高。

PIP和SIO對象支持基于幀的信號處理系統的實(shí)現。在多速率系統中需要使用優(yōu)先級線(xiàn)程來(lái)統一端口通信,在其它需要處理不同尺寸、不同速率的幀的系統中,優(yōu)先級線(xiàn)程也是必須的。PIP對象可被SWI或TSK線(xiàn)程使用,而SIO對象只能被TSK使用。

2 低級設備驅動(dòng)(LIO)

LIO(Low Level I/O)是一組基于DSP/BIOS設計的API函數。它由控制函數、I/O緩沖區管理函數、信令函數組成,如表1所示。應用程序可以通過(guò)LIO函數控制一個(gè)或多個(gè)外設通道。

表1 LIO API函數

函 數函數類(lèi)型描 述

Open
Close
Cntl
Start
Stop
GetBuf
PutBuf
IsEmpty
IsFull
SetCallback

控制
控制
控制
控制
控制
緩沖區隊列
緩沖區隊列
緩沖區隊列
緩沖區隊列
信令

分配資源,初始化設備
釋放資源,復位設備
設備特殊操作
緩沖區傳送使能
緩沖區傳送使不能
從設備輸出隊列重新得到緩沖區
將緩沖區放入設備輸入隊列
若設備輸出隊列為空返回真
若設備輸入隊列為滿(mǎn)返回真
當傳送畢,設置函數為調用

LIO函數不考慮數據的轉送方向,也就是說(shuō)僅執行輸出設備、僅執行輸入設備和能執行輸入、輸出的設備執行的是同樣的函數。輸入與輸出之間的主要不同點(diǎn)是傳送到緩沖區隊列函數的參數意義不同。既然所有其它的操作都是同樣的,大多數控制代碼能在單個(gè)驅動(dòng)程序中被所有通道共享。

2.1 總體設計、設想和命名規范

所有的驅動(dòng)程序函數都不能設置成全局中斷。驅動(dòng)程序應不影響全局中斷使能標記的狀態(tài),僅影響由它控制的外設所能觸發(fā)的中斷所對應使能標記的狀態(tài)。這樣可以阻止一個(gè)驅動(dòng)程序與其它驅動(dòng)程序或應用程序爭奪CPU資源。

為了避免由不同驅動(dòng)程序使用同一函數名引起的命名空間沖突,也為了改變驅動(dòng)程序而不需再編譯應用程序代碼,可以通過(guò)函數表訪(fǎng)問(wèn)驅動(dòng)程序函數。用這種方式,僅需要為每個(gè)驅動(dòng)程序定義一個(gè)外部符號。這種符號有其命名規范。此命名規范通過(guò)接線(xiàn)板、在片外設、LIO接口等來(lái)區分。如包含應用程序注釋的源代碼為T(mén)I TMS320VC5402 DSK的AD50音頻編解碼器執行基于DMA的驅動(dòng)程序,驅動(dòng)程序函數表名是DSK5402_DMA_AD50_TI_ILIO。

設備驅動(dòng)程序支持的各通道半雙工(輸入或輸出)通道。每個(gè)函數對應一個(gè)通道變量。一個(gè)能執行輸入和輸出的物理設備,如連接到音頻編解碼器的DSP串口,可通過(guò)兩個(gè)半雙工通道(一個(gè)輸入,一個(gè)輸出)來(lái)訪(fǎng)問(wèn)。一個(gè)驅動(dòng)程序支持多少個(gè)物理設備和通道依具體實(shí)現而實(shí)。一般一個(gè)驅動(dòng)程序應能控制一個(gè)物理設備,此設備可能有多個(gè)通道。通道號與物理設備通道的映射執行時(shí)確定。通道號應約定從0開(kāi)始。對I/O設備,一般約定偶數號為輸入,奇數號為輸出。

2.2 三類(lèi)函數

LIO接口中有三類(lèi)函數:控制函數、緩沖區和隊列管理函數、信令函數。

2.2.1 控制函數

控制函數用來(lái)實(shí)現設備的啟動(dòng)、關(guān)閉和控制。其初始函數為驅動(dòng)程序保存資源(物理外設和內存)。它使用結構指針作為可選變量,此結構是一種設備的特殊變量結構。

2.2.2 隊列管理

假定每個(gè)設備至少有一個(gè)用來(lái)傳送數據的緩沖區。許多設備(如McBSP和DMA)帶有允許雙緩沖的緩沖隊列。圖1是一個(gè)有三個(gè)存儲單元的LIO驅動(dòng)程序,驅動(dòng)程序中有:由外設填滿(mǎn)或清空的緩沖區“todevice”(到設備)隊列,將傳送的緩沖區返回到應用程序的緩沖區管理程序的“from device”(來(lái)自設備)隊列和當前傳送數據的緩沖區。在虛線(xiàn)框里的認為是在驅動(dòng)程序里面。當前傳送數據的緩沖一般由外設寄存器控制,如DMA源寄存器或目標寄存器,在圖1中畫(huà)在“外設”中。含硬件隊列(如DMA重新如載寄存器)的設備也會(huì )含一個(gè)或多個(gè)存儲單元用業(yè)存儲指針為以后傳送用,此隊列為“to device”隊列。能包含緩沖區指針的第三個(gè)存儲單元是“from device”隊列,在驅動(dòng)程序中為一變量。當設備準備傳送緩沖區時(shí),緩沖區從輸入隊列傳送到外設寄存器。這些緩沖區然后移到輸出隊列以完成傳送,作為對CPU中斷的響應。

PutBuf()將緩沖區從應用程序傳送到驅動(dòng)程序的輸入隊列。GetBuf()從輸出隊列得到緩沖區。IsEmpty()和IsFull()返回輸入隊列、輸出隊列的狀態(tài)。如果輸入隊列滿(mǎn),因為無(wú)空間裝新緩沖區,調用putBuf()會(huì )返回錯誤代碼。若IsFull()返回false,接下來(lái)可調用putBuf()。如果IsFull()返回true,但若在IsFull()返回true和調用putBuf()之間完成傳送,則調用putBuf()也可能會(huì )成功。

2.2.3 信令

如圖1所示,當傳送結束一般會(huì )觸發(fā)CPU中斷。此中斷會(huì )使應用程序將傳送的緩沖區轉移到輸出隊列,然后調用calback()傳到驅動(dòng)程序。Callback()應向應用程序發(fā)信號告知傳送完畢。

3 LIO驅動(dòng)程序例子

音頻處理如語(yǔ)音壓縮、呼叫過(guò)程音調檢測等,是DSP的一般應用。本例是使用TMS320C5402 DSK上的DMA將音頻編解碼數據從McBSP移到緩沖區中。

當驅動(dòng)程序響應應用程序調用和設備中斷時(shí),采用數據結構跟蹤驅動(dòng)程序的狀態(tài)。有效狀態(tài)是設備驅動(dòng)程序緩沖區隊列的狀態(tài),如圖1所示。

圖2給出了此模式中最簡(jiǎn)單的傳送狀態(tài)集。圓圈中單詞表示設備驅動(dòng)程序緩沖區隊列的狀態(tài)。第一個(gè)單詞是“to device”隊列,第二個(gè)表示外設占用緩沖區指針,第三個(gè)是“from device”隊列,第二個(gè)表示外設占用緩沖區指針,第三個(gè)是“from device”隊列。E表示空,F表示滿(mǎn),EEE是起始狀態(tài)。

每個(gè)隊列可以是空(E),滿(mǎn)(F),非空非滿(mǎn)(N)。應用程序調用PutBuf()將緩沖區放到“to device”隊列中。驅動(dòng)程序立即將緩沖區放進(jìn)外設,轉移到狀態(tài)“EFE”。當傳送完畢,外設向驅動(dòng)程序發(fā)中斷信號,然后驅動(dòng)中斷處理程序將緩沖區從外設寄存器轉移到“from device”隊列,轉移到狀態(tài)“EEF”,接著(zhù)調用應用程序的回調函數?;卣{函數調用GetBuf()從驅動(dòng)程序的“from device”隊列重新得到緩沖區,驅動(dòng)程序返回起始狀態(tài)。

如果驅動(dòng)程序支持硬件排隊,則當一個(gè)緩沖區正由外設傳送時(shí),“to device”隊列能控制另一個(gè)緩沖區。與圖2中狀態(tài)轉移不同,應用程序現在可能向“to device”隊列增加另一個(gè)緩沖區。驅動(dòng)程序將此緩沖區指針存進(jìn)一個(gè)隊列,此時(shí)狀態(tài)為“FFE”,“to device”隊列為滿(mǎn),外設正在傳送一個(gè)緩沖區,“from device”隊列為空。使用C數據結構實(shí)現這種狀態(tài)機器的狀態(tài)向量。

使用DMA全局重新加載寄存器來(lái)控制“to device”隊列,狀態(tài)結構如下所示。

Typedef struct drv_state{

Bool enabled;

Ptr currentBuffer;

Uns currentSize;

Ptr fullBuffer;

Uns fullSize;

LIO_TcallBack callback;

Arg calbackArg;

} LIO_Obj;

第一個(gè)字段“enabled”是一個(gè)布爾值,表示程序的開(kāi)始或結束。下面兩個(gè)字段“currentBuffer”“currentSize”控制當前傳送緩沖區的起始地址和尺寸。當傳送完畢,它們轉移到“from device”隊列?!癴ullBuffer”“fullSize”字段實(shí)現長(cháng)度為1的“from device”隊列。Callback()的地址和參數通過(guò)setCallback()存儲在狀態(tài)結構中。

驅程序對每個(gè)緩沖區只接收一個(gè)中斷,而不是每個(gè)采樣一個(gè)斷。發(fā)生中斷時(shí),驅動(dòng)程序已經(jīng)知道緩沖區傳送完畢,重新加載,DMA不需再重新編程。中斷處理程序首先將currentBuffer內容移到fullBuffer中。如果緩沖區已在“to device”隊列中,即已使用重新加載的DMA,則新緩沖區指針和長(cháng)度記錄進(jìn)currentBuffer字段中,然后調用callback()。一旦定義了基本的狀態(tài)機器,相似硬件的新驅動(dòng)程序就很容易寫(xiě)出。



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>