鄧春梅, 董貴山, 王亞棟
(①四川衛(wèi)士通信息安全平臺技術(shù)有限公司,四川 成都610041;②中國電子科技集團公司第三十研究所十部, 四川 成都 610041)
在嵌入式安全平臺的研制項目中,需要解決好多通路并發(fā)的串行高速數(shù)據(jù)傳輸及安全處理問題。如果采用8位的基于8250的通用串口芯片,難以滿足大批量,多通道串口數(shù)據(jù)的同步接收和發(fā)送,為此,需要采用高速串口芯片。本文以 OXFORD 半導體有限公司生產(chǎn)的 OX16PCI958高速串口芯片為對象,研究了在vxworks嵌入式實時系統(tǒng)下高速串行通信驅(qū)動的實現(xiàn)技術(shù)。OX16PCI958串口芯片,是由PCI接口擴展而出的,是一個帶有32字節(jié),可擴展八路串行通道FIFO的通用異步收發(fā)器,通過配置能適應 RS-232/RS-422協(xié)議規(guī)范應用的需要,能同時支持I/0和內(nèi)存映射訪問,每路通道最高速率可達115.2 kb/s。標準的VxWorks操作系統(tǒng)缺乏對此高速串口芯片的驅(qū)動支持,本文提出了專用的多通道高速串口驅(qū)動程序設計,解決了此問題。
在VxWorks系統(tǒng)中,串行設備的驅(qū)動程序不是直接安裝在I/O系統(tǒng)中,而是通過虛擬設備ttyDrv來使用。串行設備不但需要支持 I/O系統(tǒng)也需要支持目標機代理接口,同時它還必須支持在中斷或者輪詢2種方式下工作[1]。
如圖1所示的串行設備驅(qū)動程序的工作方式。其中,與設備無關的部分已經(jīng)在虛擬設備ttyDrv中實現(xiàn),驅(qū)動程序開發(fā)人員只需要根據(jù)系統(tǒng)給出的接口,實現(xiàn)驅(qū)動程序并將其安裝到ttyDrv。
圖1 串行設備驅(qū)動程序的工作方式
虛擬設備ttyDrv負責管理真實驅(qū)動程序與 I/O系統(tǒng)之間的通信[2]。一方面,虛擬設備 ttyDrv將系統(tǒng)的I/O請求作必要處理后,傳遞給設備驅(qū)動程序,再通過設備驅(qū)動程序來實現(xiàn)實際的 I/O操作;另一方面,虛擬設備ttyDrv將自己的入口點函數(shù)掛接在I/O系統(tǒng)上,初始化設備描述符并將其添加到設備列表中。當I/O系統(tǒng)中有請求包到達時,I/O系統(tǒng)會調(diào)用ttyDrv提供的相應的函數(shù)響應請求。圖2的ttyDrv數(shù)據(jù)流給出了該過程的數(shù)據(jù)流向。
[3],函數(shù)ttyDrv()調(diào)用函數(shù)iosDrv Install()將tyRead()、tyWrite()、ttyOpen()、ttyIoctl()等函數(shù)加入到驅(qū)動程序表中,以供I/O系統(tǒng)調(diào)用。
首先初始化設備描述符,然后調(diào)用函數(shù)tyDevInit()初始化select功能,初始化tyLib,創(chuàng)建信號量,創(chuàng)建輸出輸入緩沖區(qū),最后調(diào)用函數(shù)iosDevAdd()將設備加到設備列表中并設置設備的工作模式為中斷方式。
當應用程序調(diào)用函數(shù)write()執(zhí)行寫操作的時候,數(shù)據(jù)請求包首先會通過I/O系統(tǒng)傳給ttyDrv,然后運行函數(shù)tyWrite(),將用戶緩沖區(qū)的內(nèi)容復制到輸出環(huán)形緩沖區(qū),并調(diào)用函數(shù)xxTxStartUp初始化發(fā)送循環(huán),開啟中斷準備發(fā)送,最后通過調(diào)用中斷服務程序xxIntTx發(fā)送字符并清除中斷。I/O系統(tǒng)發(fā)送數(shù)據(jù)操作流程如圖3。
當串口接收到數(shù)據(jù)時會調(diào)用接收中斷服務程序xxRcvInt,將接收的字符寫入指定的緩沖區(qū)。然后由回調(diào)函數(shù)tyIRd()將數(shù)據(jù)傳給高層協(xié)議。當用戶調(diào)用read()函數(shù)進行讀操作時, I/O系統(tǒng)調(diào)用函數(shù)tyRead(),將輸入環(huán)形隊列中的內(nèi)容讀入用戶緩沖區(qū)。I/O系統(tǒng)接收數(shù)據(jù)操作流程如圖4。
當應用程序調(diào)用函數(shù)ioctl()的時候,tty Ioctl()函數(shù)直接將命令傳到由用戶編寫的stl6c958ioctl()函數(shù),如果所需要的功能在stl6c958ioctl()中未實現(xiàn),則調(diào)用函數(shù)tyIoctl(),如果tyIoctl()調(diào)用也失敗,ttyIoctl()才會返回失敗。
基本設計需求如下:①基于 OX16PCI958串口芯片;②支持多任務并發(fā)訪問每路串口通道;③支持中斷共享方式,能正確區(qū)分是否有效中斷,提高CPU利用率;④支持端口設置,如波特率配置從50BPS---115200BPS、8位有效數(shù)據(jù)位、奇偶校驗、流控;⑤支持應用程序與芯片間數(shù)據(jù)的正確交互。
(1)多任務并發(fā)訪問設計
為保障驅(qū)動程序?qū)Χ嗳蝿詹l(fā)通信訪問的支持,在驅(qū)動程序內(nèi)部采用了任務鎖(TaskLock)、中斷鎖(IntLock)來保證對臨界資源的唯一修改權(quán),同時確保了必須的連續(xù)寄存器操作指令不被打斷。在具體的程序設計中每個通道都有一個獨立的數(shù)據(jù)結(jié)構(gòu)ST16C958_CHAN與之對應,使每個通道間互不干擾,可并發(fā)訪問。
(2)中斷共享設置
中斷是CPU和外部設備進行通信的有效方法,它可以避免因反復查詢外部設備的狀態(tài)而浪費CPU時間,從而提高了 CPU的工作效率。首先在sysSerial.c文件的sysSerSerialHwInit()函數(shù)中調(diào)用函數(shù)pciConfigInByte(),參數(shù)設為PCI_CFG_DEV_INT_LINE,從寄存器中獲取中斷線,然后調(diào)用函數(shù)pciIntConnect()掛接中斷回調(diào)函數(shù) ST16C958Int(),最后調(diào)用函數(shù)sysIntEnablePIC()使能共享中斷。在中斷回調(diào)函數(shù)中必須正確處理共享于同一中斷信號線上的其它設備所產(chǎn)生的中斷。
(3)端口設置
當用戶使用 ioctl()函數(shù)訪問虛擬設備 ttyDrv時, I/O系統(tǒng)調(diào)用ttyIoctl()函數(shù), ttyIoctl()則接著訪問函數(shù)ST16C958Ioctl(),ST16C958Ioctl ()函數(shù)中主要實現(xiàn)波特率的設置、查詢,工作模式的設置及查詢等。
(4)應用程序串口訪問數(shù)據(jù)交互設計
1)初始化,首先操作系統(tǒng)要能夠正確識別該接口芯片、建立虛擬設備節(jié)點、映射基地址及掛接中斷,這就需要修改VxWorks系統(tǒng)config目錄下與嵌入式平臺的CPU相對應的文件夾中的sysSerial.c和sysSerail.h兩個文件,在 sysSerialHwlnit()函數(shù)中對接口芯片進行初始化,獲取基地址,設置讀寫及中斷回調(diào)函數(shù), 設置初始狀態(tài), 建立虛擬設備節(jié)點與驅(qū)動程序的關鍵數(shù)據(jù)結(jié)構(gòu)ST16C958_ CHAN (如圖5所示)的對應關系。芯片內(nèi)的每個關鍵寄存器的正確設置,關系到是否能讓芯片正確運轉(zhuǎn),如PCI設置寄存器,異步收發(fā)中斷狀態(tài)寄存器,異步收發(fā)時鐘寄存器,EEPROM控制寄存器等。最后在syslib.c文件中的 sysHwInit()函數(shù)中調(diào)用 sysSerialHwInit()函數(shù)實現(xiàn)串口芯片的初始化,而這個過程是在Vxworks系統(tǒng)內(nèi)核初始化之前完成的。
2)數(shù)據(jù)收發(fā),當應用程序調(diào)用 write 函數(shù)發(fā)送數(shù)據(jù)時,IO請求包將會通過I/O系統(tǒng)傳給ttyDrv,使tyWrite()開始運行。tyWrite開始執(zhí)行后,將會把用戶數(shù)據(jù)拷貝到 ttyDrv的環(huán)形緩沖區(qū)中,并調(diào)用ST16C958Startup()開始一個發(fā)送周期。每一次中斷,設備都會通過中斷服務程序發(fā)送一個或多個字節(jié)。ST16C958Startup()的任務包括初始化發(fā)送循環(huán),開啟中斷準備發(fā)送。當硬中斷回調(diào)函數(shù)ST16C958Int()發(fā)現(xiàn)有數(shù)據(jù)需要發(fā)送時,則調(diào)用ST16C958PTxChar ()從高層協(xié)議驅(qū)除字符并將其傳送出去同時清除響應中斷,如果此時高層協(xié)議不再傳送數(shù)據(jù),則重置傳送中斷,完成一個傳送周期,等待ST16C958Startup()開啟另一個傳送循環(huán)。當有數(shù)據(jù)收中斷產(chǎn)生時,ST16C958PRxChar()函數(shù)就從設備中接收數(shù)據(jù)并傳送到高層協(xié)議。
typedef struct{ /* ST16C958_CHAN */
SIO_DRV_FUNCS * pDrvFuncs;/* 驅(qū)動程序所需的
函數(shù) */
STATUS (*getTxChar) ();/* 傳送函數(shù)指針 */
STATUS (*putRcvChar) ();/* 接收函數(shù)指針 */
void * getTxArg;
void * putRcvArg;
UINT16 int_vec;/* 中斷向量 */
UINT16 channelMode; /* 模式中斷或輪詢 */
UCHAR (*inByte) (int); /* 從硬件讀取一個字節(jié)
函數(shù)指針 */
void (*outByte)(int,char); /* 向硬件寫入一個
字節(jié)函數(shù)指針 */
ULONG lcr; /* 在線控制寄存器 */
ULONG lst; /* 在線狀態(tài)寄存器 */
ULONG mdc; /* MODEM控制寄存器*/
ULONG msr; /* MODEM狀態(tài)寄存器 */
ULONG ier; /* 中斷使能寄存器 */
ULONG iid; /* 中斷狀態(tài)寄存器*/
ULONG brdl; /* 波特率寄存器*/
ULONG brdh; /*波特率寄存器*/
ULONG data; /* 數(shù)據(jù)寄存器 */
ULONG options;
ULONG fcr; /* FIFO狀態(tài)寄存器*/
ULONG spr;
} ST16C958_CHAN;
通過測試,證明該驅(qū)動程序能夠在50~115 200 b/s的速率下正確傳送數(shù)據(jù),且在多任務同時訪問不同的串口虛擬通道時,每個串口通道都能夠以 50~115 200 b/s的速率正確工作,且相互間互不干擾。
本文針對基于vxworks的嵌入式安全平臺缺乏對高速多通道串口芯片驅(qū)動支持的問題,提出了vxworks下基于0X16PCI958芯片的多串口的驅(qū)動程序設計,實現(xiàn)了八通道串口通信驅(qū)動能力,并通過任務鎖、中斷鎖及數(shù)據(jù)結(jié)構(gòu)的合理運用達到了較好的效果。進一步,通過對串口配置寄存器的設置進行優(yōu)化,并通過驅(qū)動模塊內(nèi)部嵌入密碼運算過程,可以實現(xiàn)穩(wěn)定的數(shù)據(jù)傳輸,并可實現(xiàn)該安全平臺的高速串行數(shù)據(jù)通信和加解密處理。本文的研究成果,對廣泛采用vxworks系統(tǒng)的嵌入式安全平臺的研制,有較高的實用價值。
參考文獻
[1] Wind River Inc.Tornado BSP Developer's Kit for VxWorks User's Guide[EB/OL].(1999-02-11)[2011-10-01]. http://www.vxdev.com/html/42/756.htm.
[2] Wind River Inc. VxWorks BSP Reference[EB/OL].(2000-10-11)[2011-10-01].http://www-kryo.desy.d e/.../vxWorks/.../VxWorks_BSP.
[3] 周啟平,張楊.VxWorks下設備驅(qū)動程序及BSP開發(fā)指南[M].北京:中國電力出版社,2004.