国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

RTX系統(tǒng)下Moxa多串口卡驅(qū)動(dòng)程序的開發(fā)*

2019-11-13 02:59劉士勛劉滿國唐同斌
關(guān)鍵詞:板卡驅(qū)動(dòng)程序寄存器

劉士勛,劉滿國,唐同斌,喻 戈,岳 超

(西安現(xiàn)代控制技術(shù)研究所, 西安 710065)

0 引言

RTX系統(tǒng)憑借其兼容了Windows良好的人機(jī)交互特性的原因,逐漸走入各大高校、研究所的實(shí)驗(yàn)室內(nèi)。然而,板卡出廠時(shí)大多不提供RTX驅(qū)動(dòng),即使有些板卡提供RTX驅(qū)動(dòng),這些驅(qū)動(dòng)往往沒有源代碼,同時(shí)使用起來也未必方便,出現(xiàn)問題也不好定位[3]。對(duì)于大量使用RTX系統(tǒng)的研究生產(chǎn)單位而言,了解、掌握和開發(fā)板卡RTX驅(qū)動(dòng)程序是相當(dāng)必要的。當(dāng)前對(duì)RTX驅(qū)動(dòng)的研究工作還不是很多,已有的成果大多也是基于Rfm2g反射內(nèi)存卡的。因此,文中以Moxa CP-118U板卡為例,對(duì)RTX驅(qū)動(dòng)程序開發(fā)問題進(jìn)行討論,以求該技術(shù)能被更多探索。

1 RTX驅(qū)動(dòng)程序機(jī)理

1.1 RTX驅(qū)動(dòng)程序框架簡介

Windows操作系統(tǒng)的架構(gòu)相對(duì)復(fù)雜,用戶使用板卡API訪問底層硬件,需從頂層開始,層層穿越,跨越用戶模式和內(nèi)核模式,才能訪問硬件,驅(qū)動(dòng)程序可以理解為Windows內(nèi)核模式下的一塊“補(bǔ)丁”,所有驅(qū)動(dòng)程序都需要按照該模式開發(fā)。

相比Windows驅(qū)動(dòng)程序模型,RTX程序就相對(duì)靈活,RTX應(yīng)用程序可繞過Windows內(nèi)核直接通過RTX內(nèi)核訪問RTX硬件擴(kuò)展層,直接通往硬件進(jìn)行訪問[5,8]。RTX系統(tǒng)構(gòu)架示意如圖1所示。

圖1 RTX框架簡圖

當(dāng)板卡安裝好Windows驅(qū)動(dòng)后,在RTX管理器對(duì)該板卡增加RTX支持,然后在設(shè)備管理器轉(zhuǎn)換驅(qū)動(dòng)為RTX下的驅(qū)動(dòng)后,即可進(jìn)行RTX驅(qū)動(dòng)程序的開發(fā)工作。

1.2 RTX下PCI驅(qū)動(dòng)程序開發(fā)實(shí)質(zhì)

PCI板卡驅(qū)動(dòng)的開發(fā)實(shí)質(zhì)是操縱板卡上芯片的寄存器。每個(gè)寄存器有其特定的作用,只要了解每個(gè)寄存器的作用及其地址,通過寄存器地址對(duì)板卡上的寄存器置數(shù)取數(shù),即可完成數(shù)據(jù)交互等功能。

1.3 PCI板卡寄存器訪問地址的獲取

PCI板卡的各類寄存器的訪問地址均存放于一個(gè)稱作“PCI配置空間”的256 Byte的內(nèi)存中[10]。這個(gè)空間的前64 Byte是PCI協(xié)議標(biāo)準(zhǔn)預(yù)定義的,所有PCI板卡都會(huì)使用該標(biāo)準(zhǔn)。查詢板卡硬件手冊(cè),即可得到板卡寄存器地址。有些板卡如果使用了其他芯片,其硬件手冊(cè)會(huì)告訴用戶查找對(duì)應(yīng)芯片的手冊(cè)以尋找寄存器的作用及地址。

2 RTX驅(qū)動(dòng)程序開發(fā)框架

2.1 搜尋設(shè)備

板卡驅(qū)動(dòng)程序的第一步便是驗(yàn)證該板卡是否存在于當(dāng)前計(jì)算機(jī)系統(tǒng)中。

為了獲得指定板卡的PCI配置空間內(nèi)存,RTX系統(tǒng)為編程人員提供了RtGetBusDataByOffset函數(shù)。該函數(shù)的參數(shù)有總線類型、PCI總線編號(hào)、插槽編號(hào),傳入正確參數(shù)即可獲得PCI配置空間的參數(shù),比較DeviceID和VendorID即可判斷該板卡是否為指定板卡。如果遍歷所有總線以及所有總線插槽仍無結(jié)果,則搜尋該板卡失敗,程序退出或返回失敗。

2.2 保存I/O映射寄存器基地址

Moxa CP-118U板卡給用戶提供I/O映射的方式來訪問寄存器。寄存器的基地址存儲(chǔ)在PCI配置空間的基址寄存器2中,保存該值方便后續(xù)對(duì)各個(gè)串口通道的相關(guān)寄存器進(jìn)行訪問。

2.3 相關(guān)寄存器配置

操作板卡的核心便是讀寫板卡上的各個(gè)寄存器。深刻理解寄存器的意義和用法對(duì)操縱板卡有相當(dāng)重要的幫助。

Moxa CP-118U板卡的配置包括各個(gè)串口通道的波特率的設(shè)置、數(shù)據(jù)位長度、奇偶校驗(yàn)位的設(shè)置等。

2.4 掛接中斷服務(wù)函數(shù)

板卡一般都提供了中斷標(biāo)識(shí)寄存器。中斷服務(wù)函數(shù)中就是對(duì)中斷標(biāo)識(shí)寄存器中的各個(gè)中斷二進(jìn)制位進(jìn)行判斷,如果某個(gè)二進(jìn)制位為1則對(duì)該中斷進(jìn)行響應(yīng)。

3 RTX驅(qū)動(dòng)程序開發(fā)示例

Moxa CP-118U板卡有8路RS 422/485串口,每路串口都配備了一塊TL16C550C異步串并行收發(fā)器轉(zhuǎn)換芯片,通過操作對(duì)應(yīng)串口的芯片,可以順利的完成數(shù)據(jù)的傳輸。其中,每路串口的寄存器共占有8 Byte,8路串口總共占用64 Byte,如圖2所示。

圖2 板卡寄存器組分配示意

對(duì)于每路串口,其8 Byte寄存器分配如圖3所示。

圖3 每路串口寄存器分配示意

欲操作一路串口,需對(duì)該路串口對(duì)應(yīng)芯片的寄存器有如下了解:

1)配置鏈路控制寄存器LCR:完成數(shù)據(jù)位長度設(shè)置(5~8 bit),停止位長度設(shè)置(1,1/2,2),奇偶校驗(yàn)位設(shè)置;

2)中斷使能寄存器IER:完成各類中斷的使能與關(guān)閉;

3)中斷標(biāo)識(shí)寄存器IIR:對(duì)當(dāng)前是否發(fā)生中斷與當(dāng)前中斷類型進(jìn)行標(biāo)識(shí);

4)發(fā)送保持寄存器THR與接收緩沖區(qū)寄存器RBR:串口發(fā)數(shù)和接數(shù)會(huì)分別頻繁使用這兩個(gè)寄存器;

5)波特率分辨率寄存器DLL、DLM:配置這兩位寄存器完成串口波特率設(shè)置。

有了以上了解,即可開始驅(qū)動(dòng)程序的開發(fā)。

3.1 打開板卡函數(shù)——InstallMoxa118UCard

在打開板卡函數(shù)的實(shí)現(xiàn)中,主要操作為根據(jù)DeviceID和VendorID查找板卡,如果搜尋到板卡,保存板卡的I/O映射地址,方便后續(xù)操作寄存器使用。

示例代碼如下:

for ( bus=0; bFlag; bus++ )

for(deviceNumber=0;deviceNumber

for(functionNumber=0;functionNumber

{

bytesWritten = RtGetBusDataByOffset(…)

if((PciData->VendorID==vendorID) && (PciData->DeviceID==deviceID))

…;//找到板卡

}

其中,PciData是通過RTX系統(tǒng)提供的RtGetBusDataByOffset接口所獲得的PCI配置空間的內(nèi)存指針,將該內(nèi)存中的DeviceID和VendorID成員與118U板卡的進(jìn)行對(duì)比,即可驗(yàn)證當(dāng)前所遍歷板卡是否為118U板卡。對(duì)于Moxa CP-118U而言,DeviceID為0x1180,VendorID為0x1393。

3.2 打開串口——OpenMoxa118UPort

在打開串口函數(shù)中,主要操作就是對(duì)欲使用的串口進(jìn)行參數(shù)設(shè)置,其核心就是操縱對(duì)應(yīng)串口的LCR寄存器。

1)波特率設(shè)置

Moxa CP-118U板卡上有參考輸入脈沖,其頻率為XIN=14.745 6 MHz,對(duì)每路串口的波特率設(shè)置就是對(duì)該脈沖進(jìn)行分頻,分頻因子計(jì)算方法如公式(1)所示:

(1)

例如,欲設(shè)置波特率為115 200 bit/s,則分頻因子divisor=14.745 6×106/115 200/16=8。

下面的工作就是將分頻因子寫入到分頻寄存器DLL和DLM中即可,需要注意的是,讀寫DLL和DLM,需先置LCR的BIT7為1。示例代碼如下:

RtWritePortUchar(moxa118uBaseAdd+(port-1)*8+LCR, (UCHAR)(c|0x80));

RtWritePortUchar(moxa118uBaseAdd+(port-1)*8+DLL,(UCHAR)(divisor&0x00FF));

RtWritePortUchar(moxa118uBaseAdd+(port-1)*8+DLM,(divisor>>8)&0x00FF);

2)數(shù)據(jù)位設(shè)置

配置LCR的BIT0和BIT1可以設(shè)置數(shù)據(jù)位長度,示例代碼如下:

setting=WordLength-5;

3)停止位

配置LCR的BIT2可以設(shè)置停止位長度,示例代碼如下:

setting |= 0x00;//1位停止位

4)校驗(yàn)位

配置LCR的BIT3-BIT5可以設(shè)置校驗(yàn)位使能及校驗(yàn)位類型。

if(parity ==PARITY_DISABLE_118){setting |=0x00;}

else if(parity == PARITY_ODD_118){setting |=0x08;}

else if (parity == PARITY_EVEN_118){setting |=0x18;}

RtWritePortUchar(moxa118uBaseAdd+(port-1)*8+LCR,(UCHAR)setting);

3.3 打開中斷模式——OpenInterruptMode

使用RtAttachInterruptVector函數(shù)掛接中斷服務(wù)函數(shù)。

3.4 中斷發(fā)數(shù)——WriteMoxaPort

使用中斷模式向外發(fā)數(shù),具體實(shí)現(xiàn)為向發(fā)數(shù)寄存器寫數(shù),當(dāng)數(shù)據(jù)發(fā)送成功后,會(huì)進(jìn)入2號(hào)中斷(“發(fā)送保持寄存器空”中斷),在該中斷發(fā)生時(shí)繼續(xù)給發(fā)數(shù)寄存器寫入待發(fā)送的數(shù)據(jù)。循環(huán)這個(gè)過程直至欲發(fā)送的數(shù)據(jù)全部發(fā)送結(jié)束。

a)WriteMoxaPort的核心代碼示例

WriteCounter[port-1] = 0;//清理已發(fā)送數(shù)據(jù)計(jì)數(shù)器

WriteDataLength[port-1] = iLength;//記錄發(fā)送數(shù)據(jù)長度

RtWritePortUchar(moxa118uBaseAdd+(port-1)*8+THR,WriteBuffer[port-1][WriteCounter[port-1]++]);//向發(fā)送寄存器寫數(shù),當(dāng)前已發(fā)送計(jì)數(shù)器+1

b)中斷服務(wù)函數(shù)相關(guān)實(shí)現(xiàn)示例

if(WriteCounter[port-1]

{

RtWritePortUchar(moxa118uBaseAdd+(port-1)*8+THR,WriteBuffer[port-1][WriteCounter[port-1]++]); //繼續(xù)向緩沖區(qū)寫數(shù)當(dāng)前已發(fā)送計(jì)數(shù)器+1

}

else

{

WriteDataLength[port-1]=0; //結(jié)束本次發(fā)送,清空標(biāo)志位

WriteCounter[port-1] =0;

}

3.5 中斷收數(shù)——ReadMoxaPort

收數(shù)是一個(gè)被動(dòng)的過程,當(dāng)串口總線有數(shù)據(jù)到來并且超過中斷觸發(fā)深度時(shí)會(huì)自動(dòng)觸發(fā)收數(shù)中斷,觸發(fā)之前,數(shù)據(jù)會(huì)存儲(chǔ)在板卡的硬件緩沖區(qū)內(nèi)。由于板卡的硬件緩存只有128 Byte,因此需要在驅(qū)動(dòng)程序?qū)釉黾右粚泳彌_區(qū)。文中設(shè)計(jì)的ReadMoxaPort函數(shù)的參數(shù)列表中有一項(xiàng)為用戶提供欲接收數(shù)據(jù)的長度,當(dāng)數(shù)據(jù)接收量大于該值時(shí)返回,具體流程如下:

1)當(dāng)數(shù)據(jù)來臨時(shí)存儲(chǔ)在驅(qū)動(dòng)層緩沖區(qū)內(nèi);

2)定時(shí)器檢測(cè)數(shù)據(jù)長度到達(dá)用戶欲得到的數(shù)據(jù)長度;

3)當(dāng)數(shù)據(jù)長度滿足要求后,將數(shù)據(jù)填入用戶傳進(jìn)的緩沖區(qū)內(nèi)存,返回結(jié)束。

具體實(shí)現(xiàn)如下:

a)中斷服務(wù)函數(shù)的核心實(shí)現(xiàn)

ReadBuffer[port-1][ReadCounter[port-1]++]=RtReadPortUchar(moxa118uBaseAdd+RBR);

b)定時(shí)器函數(shù)的核心實(shí)現(xiàn)

if(ReadCounter[port-1]-ReadPostion[port-1]>=iDrvTriggerLevel[port-1])

RtSetEvent(hRecWaitEvent[port-1]);

c)ReadMoxaPort的核心實(shí)現(xiàn)

if(RtWaitForSingleObject(hRecWaitEvent[port-1],INFINITE)==WAIT_FAILED)

return-3;

for(counter=0;counter

Buffer[counter]=ReadBuffer[port-1][ReadPostion[port-1]++];

4 RTX驅(qū)動(dòng)程序測(cè)試

使用RTX Application Wizard創(chuàng)建RTX應(yīng)用程序,加載使用上述方法創(chuàng)建的驅(qū)動(dòng)程序靜態(tài)庫對(duì)驅(qū)動(dòng)程序性能進(jìn)行測(cè)試,測(cè)試結(jié)果如表1所示。

表1 驅(qū)動(dòng)性能測(cè)試結(jié)果

由于高波特率條件下中斷頻繁觸發(fā),過于占用計(jì)算機(jī)資源,同時(shí)也受計(jì)算機(jī)CPU性能等因素影響,921 600 bit/s波特率的條件下最多容許4路串口穩(wěn)定工作,超過4個(gè)串口會(huì)丟失數(shù)據(jù);230 400 bit/s及以下波特率條件下8路串口可以穩(wěn)定工作。該性能滿足了絕大多數(shù)工作的條件,可以用于日常仿真研究工作。

5 結(jié)束語

文中以Moxa CP-118U板卡為例,介紹了在RTX實(shí)時(shí)系統(tǒng)下PCI板卡的驅(qū)動(dòng)編寫方法,出色的實(shí)現(xiàn)了板卡提供的所有功能,驅(qū)動(dòng)性能可以滿足絕大多數(shù)工業(yè)、生產(chǎn)、仿真的要求。同時(shí)對(duì)于Moxa公司其他類型的多串口卡,亦可借鑒文中列舉的方法和框架進(jìn)行開發(fā)驅(qū)動(dòng)。

猜你喜歡
板卡驅(qū)動(dòng)程序寄存器
避免Windows系統(tǒng)更新反復(fù)安裝顯示驅(qū)動(dòng)
Lite寄存器模型的設(shè)計(jì)與實(shí)現(xiàn)
RTX系統(tǒng)下并行I/O卡驅(qū)動(dòng)程序的開發(fā)
航空電子設(shè)備機(jī)上線路故障研究
阻止Windows Update更新驅(qū)動(dòng)程序
常用電子測(cè)速法在某數(shù)字信號(hào)處理器中的應(yīng)用*
移位寄存器及算術(shù)運(yùn)算應(yīng)用
妙用鼠標(biāo)驅(qū)動(dòng)
驅(qū)動(dòng)程序更新與推薦