新聞中心

EEPW首頁 > 消費(fèi)電子 > 設(shè)計應(yīng)用 > VxWorks串口驅(qū)動的研究與實現(xiàn)

VxWorks串口驅(qū)動的研究與實現(xiàn)

——
作者:西北工業(yè)大學(xué)航海學(xué)院 趙勛峰 吳旭光 時間:2007-02-06 來源:電子產(chǎn)品世界 收藏

摘要: 本文以基于ARM7TDMI內(nèi)核的S3C44B0X芯片的為例,分析了 的層次和機(jī)理,研究了tty驅(qū)動和底層SCC驅(qū)動的工作原理。結(jié)合S3C44B0X芯片的程序,給出了串口驅(qū)動程序設(shè)計方法和注意事項。

關(guān)鍵詞: ;串口驅(qū)動;tty設(shè)備

引言

VxWorks的程序開發(fā)者經(jīng)常需要解決串口驅(qū)動問題,這是BSP和上層應(yīng)用程序開發(fā)必不可少的基本步驟,特別是對于板級支持包(BSP)和上層應(yīng)用程序的開發(fā),掌握串口驅(qū)動的原理和開發(fā)串口驅(qū)動程序就顯得尤為重要。VxWorks串口通信由串行通信控制器SCC(Serial Communication Controller)控制,和標(biāo)準(zhǔn)I/O庫通信的是tty驅(qū)動,再由tty驅(qū)動和底層SCC驅(qū)動通信。本文研究VxWorks串口驅(qū)動特性,并以S3C44B0X為例,給出開發(fā)VxWorks串口驅(qū)動的步驟和實現(xiàn)方法。

串口設(shè)備層次與tty驅(qū)動

串口的層次

VxWorks串行設(shè)備的層次采用了3層抽象的軟件結(jié)構(gòu):標(biāo)準(zhǔn)I/O庫(ioLib)->tty庫(ttyDrv/tyLib)—>底層SCC驅(qū)動(xxDrv),如圖1所示。從圖中可看出串行設(shè)備的驅(qū)動xxDrv并不是直接和I/O system交互的,中間存在一個ttyDrv(包括tyLib)。實際上,內(nèi)核啟動時在驅(qū)動程序表中安裝的不是xxDrv的函數(shù),而是ttyDrv/tyLib提供的函數(shù)。串口tty驅(qū)動(ttyDrv/tyLib)使I/O系統(tǒng)獨(dú)立于具體SCC驅(qū)動,保證了代碼可復(fù)用和統(tǒng)一界面。SCC驅(qū)動(xxDrv/yyDrv)處理和底層硬件有關(guān)的部分。因此,在編寫串口驅(qū)動時需要了解串口tty驅(qū)動的原理以及串口輸入輸出過程。在此基礎(chǔ)上,根據(jù)VxWorks的程序執(zhí)行流程和具體的MCU芯片的特點,修改底層SCC驅(qū)動代碼。

圖1 VxWorks串口軟件結(jié)構(gòu)

串口tty驅(qū)動

創(chuàng)建tty設(shè)備包括驅(qū)動程序初始化和創(chuàng)建設(shè)備兩步,這兩步都在usrRoot()中完成。創(chuàng)建完tty設(shè)備后,用戶可以調(diào)用ioLib中的write()、read()函數(shù)對串口進(jìn)行讀、寫操作。

*驅(qū)動程序初始化
初始化ttyDrv()函數(shù)是一個虛擬的驅(qū)動,既管理著和I/O的交互,又管理著和底層硬件驅(qū)動的交互。它調(diào)用iosDrvInstall( )將ttyDrv和tyLib中的函數(shù)安裝到系統(tǒng)的驅(qū)動程序表中。ttyDrv負(fù)責(zé)著ttyOpen、ttyIoctl的接入,而tyLib負(fù)責(zé)著tyRead、tyWrite的接入。

*創(chuàng)建設(shè)備
創(chuàng)建設(shè)備函數(shù)ttyDevCreate()主要分配并初始化設(shè)備描述結(jié)構(gòu),調(diào)用tyDevInit( )進(jìn)行tyLib庫初始化,初始化selectLib(),創(chuàng)建輸入輸出環(huán)形緩沖,創(chuàng)建信號量,調(diào)用iosDevAdd()加設(shè)備到設(shè)備列表,以中斷方式啟動串口通道。它還進(jìn)行的另一個重要操作是安裝了tyLib設(shè)備提供的輸入輸出回調(diào)函數(shù)tyITx()和tyIRd(),以便給底層SCC驅(qū)動負(fù)責(zé)調(diào)用。

*tty輸入輸出
當(dāng)tty設(shè)備創(chuàng)建后,用open()打開相應(yīng)的串口,open函數(shù)返回的文件句柄就是設(shè)備的標(biāo)識fd,依據(jù)串口打開時的讀、寫標(biāo)志,可以對串口進(jìn)行讀、寫操作。用戶程序的基本I/O讀寫請求由tyLib的tyWrite( )和tyRead( )實現(xiàn),這兩個函數(shù)在ttyDrv( )初始化tty時安裝到驅(qū)動程序表中,如圖2所示。

圖2 VxWorks輸入輸出

底層SCC驅(qū)動—S3C44B0X串口驅(qū)動的實現(xiàn)

VxWorks串口驅(qū)動的編寫主要集中在target/config/bsname/目錄下的sysLib.c、sysSerial.c、s3c44b0xsio.c、config.h,target/config/all等文件。編寫串口驅(qū)動主要需要做以下幾個方面的工作。

設(shè)備初始化

確定系統(tǒng)要支持的串行通道的個數(shù),初始化數(shù)據(jù)結(jié)構(gòu)XX_CHAN,編寫SCC初始化代碼(對處理器串行I/O端口的初始化,RESET串口控制器)。

(1) 定義系統(tǒng)中串口驅(qū)動相關(guān)的參數(shù):具體在config.h 中定義。
#define INCLUDE_TTY_DEV                          /* 定義tty設(shè)備*/
#define INCLUDE_SERIAL                            /* 定義串口*/
#define NUM_TTY                 N_SIO_CHANNELS   /*定義串口通道數(shù)*/
#define CONSOLE_TTY            0              /*作為控制臺的通道為COM0*/
#define CONSOLE_BAUD_RATE    115200            /*設(shè)定控制臺串口波特率*/
如果系統(tǒng)還定義串口為WDB連接下載通道,還要進(jìn)行如下的相關(guān)配置:
#define WDB_COMM_TYPE         WDB_COMM_SERIAL /* WDB為串口模式 */
#define WDB_TTY_CHANNEL       1               /*WDB下載通道COM1  */
#define WDB_TTY_BAUD          115200         /* WDB連接通道的串口波特率*/
#define WDB_TTY_DEV_NAME     "/tyCo/1"    /*定義WBD通道在tty中的設(shè)備名*/

(2) 初始化數(shù)據(jù)結(jié)構(gòu):編寫串行設(shè)備根據(jù)具體的串行設(shè)備定義自己的設(shè)備描述符xx_ DEV 結(jié)構(gòu)。對于串行設(shè)備具體的成員主要是一個S3C44B0_CHAN結(jié)構(gòu), 表示設(shè)備的通道。

(3)SCC初始化代碼:SCC驅(qū)動分兩步如圖3所示,描述了VxWorks中有關(guān)串口初始化的順序,其中ttyDrv( )及ttyDevCreate( )涉及的I/O系統(tǒng)提供的一般化代碼,不需要修改。用戶需要修改的是涉及S3C44B0X芯片的串口數(shù)據(jù)結(jié)構(gòu)devParas[ ], 設(shè)置USART發(fā)送接收的中斷號、向量號、寄存器基地址等。

圖3 VxWorks串口初始化過程

系統(tǒng)在內(nèi)核啟動之前,在usrInit( )中進(jìn)行第一步初始化后,串口SCC被復(fù)位,禁止中斷,串口能通過查詢方式訪問,實現(xiàn)系統(tǒng)級調(diào)試如下。

sysHwInit():處理器I/O端口的初始化,在sysHwInit ()函數(shù)中調(diào)用portInit()函數(shù)設(shè)置相應(yīng)的串行I/O端口;需要注意的是對S3C44B0X芯片而言partB和partF都有一位對UART2的設(shè)置選項,只能選其一設(shè)成選擇UART2端,否則將無法用WDB下載VxWorks映像。

s3c44b0DevInit():初始化串口功能指針pChan->sio.pDrvFuncs = &s3c44b0SioDrvFuncs;再對串口芯片的ULCON、UFCON、UMCON進(jìn)行設(shè)定采用8位數(shù)據(jù)、禁止FIFO和AFC;調(diào)用s3c44b0Ioctl()選擇串口通訊模式為輪詢方式,并初始化波特率。系統(tǒng)激活內(nèi)核之后,在根任務(wù)usrRoot( )中進(jìn)行第二步初始化,使串口可以以中斷方式實現(xiàn)對tty庫的底層支持。

sysHwInit2():調(diào)用intLibInit初始化intVecTable; s3c44b0DevInit( )初始化中斷驅(qū)動,調(diào)用intConnect()將sysClkInt()、sysAuxClkInt()的入口地址寫入intVecTable, sysSerialHwInit2()函數(shù)連接串口中斷。

sysSerialHwInit2():通過intConnect()把串口的中斷處理程序s3c44b0xIntTx、s3c44b0xIntRcv連接到相應(yīng)的中斷向量;由intEnable()開啟兩個中斷;調(diào)用s3c44b0xDevInit2()對_UCON寄存器賦值完成對串口的最終配置由輪詢模式轉(zhuǎn)換為中斷模式。

編寫設(shè)備中斷服務(wù)程序(ISR)

串口中斷處理是當(dāng)有數(shù)據(jù)發(fā)送、接收時,硬件產(chǎn)生中斷,然后執(zhí)行相應(yīng)的中斷服務(wù)程序進(jìn)行處理,這樣CPU不必像輪詢方式那樣花費(fèi)大量的時間查詢外部設(shè)備的工作狀態(tài),有效的提高CPU的使用效率并使系統(tǒng)具有較高的實時性能。這里主要編寫與中斷處理相關(guān)的數(shù)據(jù)輸入輸出部分中斷處理的驅(qū)動程序。發(fā)送數(shù)據(jù)部分的驅(qū)動是一個啟動發(fā)送的函數(shù)s3c44b0xTxStartup()和一個發(fā)送輸出中斷的ISRs3c44b0xTxInt()。

① s3c44b0xTxStrartup()當(dāng)用戶要向設(shè)備寫數(shù)據(jù)時, 就調(diào)用了tyWrite。tyWrite將數(shù)據(jù)寫入到數(shù)據(jù)輸出環(huán)后, 調(diào)用s3c44b0xTxStrartup()啟動設(shè)備的數(shù)據(jù)發(fā)送。這里只需向串口緩沖區(qū)寫入一個字節(jié),然后開啟發(fā)送中斷;后續(xù)字節(jié)又發(fā)送中斷處理程序來處理。

② s3c44b0xTxInt()在中斷模式下,當(dāng)設(shè)備輸出完畢后, 設(shè)備就會產(chǎn)生一個中斷表示可以接收下一個字符, 這時調(diào)用中斷處理程序s3c44b0xTxInt()來完成剩下的數(shù)據(jù)發(fā)送工作。

接收數(shù)據(jù)部分的驅(qū)動與輸出驅(qū)動類似由一個s3c44b0xRxInt()組成。該中斷處理函數(shù)在收到數(shù)據(jù)時,向寄存器的數(shù)據(jù)通過回調(diào)函數(shù)寫入驅(qū)動程序的環(huán)形緩沖區(qū)中。通過上述的工作就可以完成對VxWorks串口驅(qū)動程序的編寫。

結(jié)語

對于VxWorks串口驅(qū)動開發(fā)而言,應(yīng)當(dāng)注意以下問題:掌握VxWorks的啟動流程和I/O系統(tǒng)層次與組織結(jié)構(gòu);要對硬件環(huán)境的物理地址、寄存器地址及其含義清楚;理解串口設(shè)備的軟硬件工作原理。在串口調(diào)試過程中的主要問題一般集中在起始時I/O端口進(jìn)行初始化是否正確,對串口設(shè)備寄存器的值設(shè)置是否符合軟件要求、能否正常使硬件工作,連接ISR程序以及中斷優(yōu)先級的設(shè)置和中段處理函數(shù)的編寫。

參考文獻(xiàn)

1. Wind River Inc.Tornado BSP Developer's Kit for VxWorks User's Guide[P].Tornado 2.0.Edition 1.1999
2. Wind River Inc. VxWorks BSP Reference [P]. Tornado 2.2.Edition 1.2000
3. 周啟平. VxWorks下設(shè)備驅(qū)動程序及BSP開發(fā)指南 [M]. 中國電力出版社 . 2004.9
4. 陳智育. VxWorks程序程序開發(fā)實踐[M].北京:人民郵電出版社,2004.5

可控硅相關(guān)文章:可控硅工作原理




評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉