當(dāng)前位置:首頁 > 嵌入式 > 嵌入式軟件
[導(dǎo)讀]vxworks嵌入式操作系統(tǒng)串行設(shè)備驅(qū)動(dòng)程序的編寫

摘要:目前,基于嵌入式操作系統(tǒng)的軟件開發(fā)是國內(nèi)外研究的熱點(diǎn),vxworks嵌入式操作系統(tǒng)又是目前最流行的嵌入式操作系統(tǒng)之一。本文的目的在于通過分析vxworks操作系統(tǒng)下串行通信設(shè)備驅(qū)動(dòng)程序的運(yùn)行機(jī)制,提出在此操作系統(tǒng)下開發(fā)串行設(shè)備驅(qū)動(dòng)程序開發(fā)的基本思路。

1. 概 述

我們在基于vxworks嵌入式操作系統(tǒng)開發(fā)產(chǎn)品時(shí),經(jīng)常會根據(jù)自行設(shè)計(jì)的硬件電路開發(fā)專用的驅(qū)動(dòng)程序。Vxworks下的驅(qū)動(dòng)程序根據(jù)設(shè)備的不同特性,,大體可分為:char driver、serial driver、block driver、end driver、scsi driver等類型,其中以char driver最簡單,最基礎(chǔ),以serial driver最常用。掌握驅(qū)動(dòng)程序的基本工作流程,無論對我們開發(fā)上層的應(yīng)用還是自己編寫相應(yīng)的驅(qū)動(dòng)程序,都很有幫助。本文主要以i8250串口驅(qū)動(dòng)程序?yàn)槔榻B一下串行驅(qū)動(dòng)程序編寫的基本思路。

驅(qū)動(dòng)程序,簡而言之就是對具體的硬件設(shè)備進(jìn)行管理和服務(wù)的程序。為了提高代碼的可移植性,vxworks將所有的輸入/輸出設(shè)備都看成是一個(gè)文件,我們對設(shè)備的輸入/輸出操作,都可以看作是對指定文件的讀寫操作。例如,我們用c 標(biāo)準(zhǔn)庫函數(shù)open()打開一個(gè)文件,可以是打開一個(gè)傳統(tǒng)意義上的文本文件,也可以是指定一個(gè)輸入/輸出設(shè)備,如指定對某一個(gè)串口的輸入/輸出操作。在vxworks操作系統(tǒng)中,驅(qū)動(dòng)程序的主要作用是完成對相關(guān)設(shè)備的讀、寫、打開、建立、關(guān)閉及控制等功能中的一項(xiàng)或幾項(xiàng),具體情況視具體的設(shè)備及設(shè)計(jì)要求而定。

概括的說,驅(qū)動(dòng)程序主要完成以下幾項(xiàng)工作:

(1)相關(guān)設(shè)備的初始化。

(2)底層輸入/輸出函數(shù)與上層標(biāo)準(zhǔn)輸入/輸出函數(shù)的掛接。

(3)相關(guān)設(shè)備與對應(yīng)驅(qū)動(dòng)程序的掛接。

我們就按照這個(gè)思路,以I8250串口為例,分析一下串行設(shè)備驅(qū)動(dòng)程序的編寫及加載流程。首先,給出串行設(shè)備驅(qū)動(dòng)的結(jié)構(gòu)框圖:

 

 

需要說明的是,ttyDrv是一個(gè)虛擬的設(shè)備驅(qū)動(dòng),與tylib一起,用于處理I/O系統(tǒng)與底層實(shí)際設(shè)備之間的通信。主要完成以下工作:

(1)處理I/O系統(tǒng)的各種需求,如在driver talbe 中添加相應(yīng)的驅(qū)動(dòng)條目、創(chuàng)建設(shè)備標(biāo)識符(devise descriptor)。

(2)實(shí)現(xiàn)與上層標(biāo)準(zhǔn)I/O函數(shù)及實(shí)際驅(qū)動(dòng)程序的無縫連接。其中,ttyDrv完成open和ioctl兩項(xiàng)功能(ttyopen()和ttyioctl())。Tylib完成read和write兩項(xiàng)功能(tyRead()和tyWrite())。

(3)管理輸入/輸出數(shù)據(jù)緩沖區(qū)。

下面,我們結(jié)合圖(一)給出的框圖,以i8250為例,開始分析串行設(shè)備驅(qū)動(dòng)的設(shè)計(jì)流程。用戶在編寫自己的驅(qū)動(dòng)程序時(shí),可以不按照系統(tǒng)函數(shù)命名的方法命名,也可以不按照系統(tǒng)給定的方法進(jìn)行函數(shù)功能的劃分,但其初始化及實(shí)現(xiàn)流程卻不能改變。

2. 驅(qū)動(dòng)程序設(shè)計(jì)流程分析

⑴ i8250相關(guān)硬件設(shè)備的初始化。

編寫驅(qū)動(dòng)程序的第一步是完成相關(guān)硬件的初始化。與I8250相關(guān)的硬件初始化函數(shù)主要有以下三個(gè):sysSerialHwInit()、i8250HrdInit()、i8250InitChannel(),其調(diào)用順序是:sysSerialHwInit()ài8250HrdInit()ài8250InitChannel(),這條工作鏈的主要作用是,完成對I8250_CHAN數(shù)據(jù)結(jié)構(gòu)的初始化。

下面對分別這幾個(gè)函數(shù)的功能介紹一下:

l

sysSerialHwInit()

本函數(shù)完成的主要任務(wù)是初始化設(shè)備的中斷向量、串口的通信模式及相關(guān)存貯器,在函數(shù)的最后調(diào)用i8250HrdInit()對I8250_CHAN結(jié)構(gòu)進(jìn)一步初始化。

void sysSerialHwInit (void)

{

int i;

for (i=0;i

{

i8250Chan[i].int_vec = devParas[i].vector; /*初始化中斷向量*/

i8250Chan[i].channelMode = 0; /*初始化SIO_MODE 可以是INT或POLL*/

i8250Chan[i].lcr = UART_REG(UART_LCR,i); /*初始化line control register*/

………………………

i8250Chan[i].outByte = sysOutByte; /*掛接輸出函數(shù),此函數(shù)向指定的I/O地址寫入1bye*/

i8250Chan[i].inByte = sysInByte; /*掛接輸出函數(shù),此函數(shù)從指定的I/O地址讀出1byte*/

i8250HrdInit(&i8250Chan[i]);/*調(diào)用i8250HrdInit()進(jìn)一步完成初始化*/

}

}

l i8250HrdInit()

本函數(shù)完成的主要工作是掛接相應(yīng)的入口函數(shù),具體說明如下:

void i8250HrdInit

(

I8250_CHAN * pChan /* 指向相應(yīng)設(shè)備的指針*/

)

{

if (i8250SioDrvFuncs.ioctl == NULL)

{

i8250SioDrvFuncs.ioctl = (int (*)())i8250Ioctl;/*掛接用于處理控制I8250相關(guān)輸入

輸出命令的函數(shù)*/

i8250SioDrvFuncs.txStartup = (int (*)())i8250Startup;/*如果設(shè)備工作于中斷模式下,

啟用此函數(shù)用于打開中斷,使設(shè)備開始工作*/

i8250SioDrvFuncs.callbackInstall = i8250CallbackInstall;/*安裝上層提供的回調(diào)函數(shù),

本例中是安裝的tyIRd()、tyITx()*/

i8250SioDrvFuncs.pollInput = (int (*)())i8250PRxChar;/*掛接輸入輪詢函數(shù)*/

i8250SioDrvFuncs.pollOutput = (int (*)(SIO_CHAN *,char))i8250PTxChar;/*掛接輸出輪詢函數(shù)*/

}

pChan->pDrvFuncs = &i8250SioDrvFuncs;/*初始化CHAN結(jié)構(gòu),掛接接口函數(shù)列表*/

i8250InitChannel(pChan); /* reset the channel */

}

由上面掛接的函數(shù)可以看出,i8250驅(qū)動(dòng)主要實(shí)現(xiàn)了三個(gè)功能:read、write、ioctl,而并沒有實(shí)現(xiàn)所有和七項(xiàng)功能。同時(shí),值的注意的是,對同一種設(shè)備的驅(qū)動(dòng)只需掛接一次。

同時(shí)ttyDrv通過SIO_DRV_FUNCS使用xxDrv(i8250Drv)提供的服務(wù),而xxDrv通過回調(diào)函數(shù)(本例中是由i8250CallbackInstall()安裝的tyIRd()、tyITx())完成ttyDrv提出的請求。原理如下圖示:

 

 

i8250InitChannel()

本函數(shù)的主要作用是初始化特定的CHAN所描述的信道。具體分析如下。

static void i8250InitChannel

(

I8250_CHAN * pChan /* pointer to device */

)

{

int oldLevel;

ldLevel = intLock (); /*關(guān)中斷進(jìn)入臨界區(qū)*

(void) i8250BaudSet(pChan, I8250_DEFAULT_BAUD);/*設(shè)置信道的波特率*/

…………………………………

intUnlock (oldLevel); /*開中斷響應(yīng),出臨界區(qū)*/

}

⑵ 掛接中斷服務(wù)程序

對i8250的硬件初始化完成后,接著掛接相關(guān)的中斷服務(wù)程序。主要有sysSerialHwinit2()函數(shù)完成。需要注意的是,掛接中斷應(yīng)放在系統(tǒng)初始化的最后,主要是因?yàn)橹袛鄴旖雍瘮?shù)intCONnect()需要調(diào)用malloc()函數(shù),如果在系統(tǒng)的內(nèi)存分配還未初始化前調(diào)用,則會出錯(cuò)。下面請看源代碼:

void sysSerialHwInit2 (void)

{

int i;

for (i=0;i

if (i8250Chan[i].int_vec)

{

(void) intConnect (INUM_TO_IVEC (i8250Chan[i].int_vec), i8250Int, (int)&i8250Chan[i] );

sysIntEnablePIC (devParas[i].intLevel);

}

}

其中,宏INUM_TO_IVEC的作用是把中斷號轉(zhuǎn)為中斷向量。i8250Int是指向輸入/輸出中斷處理函數(shù)的指針。描述相應(yīng)硬件的結(jié)構(gòu)i8250Chan為函數(shù)i8250int()的入口參數(shù)。

至此,設(shè)備硬件的初始化、相關(guān)的低層函數(shù)的掛接、中斷初始化基本完成。開始進(jìn)行下一步,將設(shè)備的驅(qū)動(dòng)函數(shù)安裝在Driver Table 中。

⑶ 與上層標(biāo)準(zhǔn)輸入/輸出函數(shù)的掛接

在此處I/O系統(tǒng)通過調(diào)用ttyDrv()(在沒有定義INCLUDE_TYCODRV_5_2的情況下)將相應(yīng)驅(qū)動(dòng)函數(shù)添加到Driver Table中,從而完成與上層標(biāo)準(zhǔn)輸入/輸出函數(shù)的掛接。

 

 

由上圖知,iosDrvInstall()函數(shù)在Driver Table中掛接的函數(shù)是tyWrite()和tyRead(),而不是我們實(shí)際編寫的輸入/輸出函數(shù)。其具體的調(diào)用過程是:

① 當(dāng)用戶調(diào)用write函數(shù)進(jìn)行寫操作時(shí),根據(jù)相應(yīng)的fd調(diào)用在Driver Table中注冊的函數(shù)tyWrite(),此函數(shù)的作用是將用戶緩沖區(qū)的內(nèi)容寫入相應(yīng)的輸出ring buffer,當(dāng)發(fā)現(xiàn)緩沖區(qū)內(nèi)有內(nèi)容時(shí),開始調(diào)用回調(diào)函數(shù)tyITX(),從ring buffer讀取字符,由I8250Startup()啟動(dòng)中斷輸出,最后由設(shè)備的輸出中斷服務(wù)程序(在本例中調(diào)用的是sysOutbyte())將字符發(fā)往指定的串口。

② 當(dāng)串口接收到數(shù)據(jù)時(shí)會調(diào)用輸入中斷服務(wù)程序(在本例中是sysInbyte()),將輸入的字符寫入指定的緩沖區(qū)。然后由回調(diào)函數(shù)tyIRd()將緩沖區(qū)的內(nèi)容讀入ring buffer,當(dāng)用戶調(diào)用read函數(shù)進(jìn)行寫操作時(shí),會根據(jù)相應(yīng)的fd調(diào)用在Driver Table中注冊的函數(shù)tyRead(),此函數(shù)會將ring buffer中的內(nèi)容讀入用戶緩沖區(qū)。

關(guān)于具體的中斷輸入/輸出函數(shù)如何調(diào)用,本文不做詳細(xì)分析,請參閱i8250int()及i8250Startup()。

對于輸入/輸出控制函數(shù)ioctl()的掛接,則是直接將命令傳到由用戶編寫的i8250ioctl()函數(shù),其具體的實(shí)現(xiàn)代碼與驅(qū)動(dòng)的設(shè)計(jì)思路無緊密的聯(lián)系,本文也不做具體分析。

⑷ 具體設(shè)備與相關(guān)驅(qū)動(dòng)的掛接

當(dāng)Driver Table中相應(yīng)的驅(qū)動(dòng)函數(shù)掛接完成,開始編寫驅(qū)動(dòng)程序的最后一步:在Device Table中加入設(shè)備,完成具體設(shè)備與相關(guān)驅(qū)動(dòng)的掛接。此項(xiàng)工作是由ttyDevCreat()函數(shù)完成的。本函數(shù)主要實(shí)現(xiàn)以下功能:

① 分配并初始化一個(gè)device descriptor。

② 通過調(diào)用tyDevInit()初始化tyLib。此處主要完成輸入/輸出ring buffer的創(chuàng)建、建立用與相關(guān)函數(shù)的信號量、初始化selectLib。

③ 調(diào)用iosDevAdd()將串口設(shè)備加入Device Table。對于設(shè)備特性的描述信息是由sysSerialChanGet()函數(shù)得到,并以參數(shù)形式傳入的。

④ 為底層設(shè)備安裝回調(diào)函數(shù),在本例中是為i8250CHAN 安裝tyIRd()、tyITx()兩處回調(diào)函數(shù)。

⑤ 開中斷,設(shè)備開始以中斷方式工作。

至此,驅(qū)動(dòng)程序的分析全部完成。與掛接驅(qū)動(dòng)函數(shù)不同,在安裝設(shè)備的過程中,無論設(shè)備相同與否,有幾個(gè)設(shè)備則上述過程需調(diào)用幾次。以上各函數(shù)的加載主要在usrinit()函數(shù)中完成。

3. 結(jié)束語

需要說明的是,在VxWorks下,設(shè)備驅(qū)動(dòng)程序既可以嵌入內(nèi)核隨系統(tǒng)一起啟動(dòng),也可以作為可加載模塊在系統(tǒng)啟動(dòng)之后運(yùn)行。相比之下,后一種方式比較簡單,不用修改系統(tǒng)內(nèi)核,引入錯(cuò)誤的可能性小。但是無論采取哪種方式,其基本思路及需要完成的工作是相同的。本文沒有按照系統(tǒng)的調(diào)用過程進(jìn)行一步步分析,主要基于上述考慮。用戶在編寫相關(guān)驅(qū)動(dòng)程序時(shí),中心任務(wù)是按步驟完成上述功能,而沒有必要去死搬系統(tǒng)的加載步驟。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉