日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WINCE6.0+S3C6410串口驱动

發布時間:2025/4/16 编程问答 130 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WINCE6.0+S3C6410串口驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

********************************LoongEmbedded************************
作者:
LoongEmbedded(kandi)
時間:
2011.05.21
類別:WINCE驅動開發

********************************LoongEmbedded************************

WINCE串口驅動

?

備注:本博文基于Real6410+WINCE6.0的系統來學習的

?

1.????? 硬件設計

?

1

UART接口在此開發板中的應用如下:

UART0作為調試口來使用

?

2

UART1用于和GPRS模塊SIM900通信

?

3

UART2用于和GPS模塊COMPASS_EB818通信

?

4

UATR3用于和藍牙模塊通信

?

5

?

2.????? 軟件設計

?

2.1?? WINCE串口驅動的架構

WINCE系統中,串口驅動是作為一個流驅動的形式存在,其驅動架構如下圖所示:

?

6

串口驅動分為MDD層和PDD層,DD層對上層的Device Manager(device.dll)提供了標準的流設備驅動接口(COM_xxx)PDD層實現了HWOBJ結構及結構中若干針對于串口硬件操作的函數指針,這些函數指針將指向PDD層中的串口操作函數。DDSI是指MDD層與PDD層的接口,在串口驅動中實際上就是指HWOBJPDD層會傳給MDD層一個HWOBJ結構的指針,這樣MDD層就可以調用PDD層的函數來操作串口。

?

2.2?? MDD層的導出接口函數

MDD層為系統提供流設備接口,這些接口微軟已經實現,但還是有必要學習一下

?

2.2.1???????? COM_Init

此函數始化串口設備,該函數通過讀取注冊表獲得串口設備號,并獲得相應的HWOBJ的結構指針,通過該指針調用PDD層的硬件初始化函數初始化串口。

Identifier:如果驅動被設備管理器加載,那么這個參數將包含一個注冊表鍵值在” HKEY_LOCAL_MACHINE/Drivers/Active”路徑下。如果驅動是通過調用RegisterDevice函數來加載的,那么這個值等于dwInfo的值。在COM_Init中,會先打開該鍵值,用返回的句柄來查詢DeviceArrayIndex值,并根據該值獲得PDD層的HWOBJ結構指針,下圖是COM_Init函數的一部分

?

7

?

?

2.2.2???????? COM_Deinit

卸載串口設備,該函數中主要做了一些釋放資源的操作。也可以被DeregisterDevice函數調用,而DeregisterDevice函數可以被應用程序調用。

?

2.2.3???????? COM_PreDeinit

?

2.2.4???????? COM_Open

打開串口設備,當應用程序調用CreateFile函數打開串口時,該函數會被調用來打開串口設備。

pContextCOM_Init函數返回的Handle。

AccessCode:設置訪問模式,比如共享讀或者是讀寫模式。

ShareMode:在參數從應用程序中的CreateFile函數中傳來,表示是否支持獨自占有。

?

2.2.5???????? COM_Close

關閉串口設備,當應用程序調用CloseHandle函數的時候會調用這個函數。

pContextCOM_Init函數返回的Handle。

?

2.2.6???????? COM_PreClose

?

2.2.7???????? COM_Read

讀串口數據,應用程序調用ReadFile函數讀串口的時候,會調用該函數。

pContextCOM_Open函數返回的Handle

pTargetBuffer:指向一個用于存放讀到數據的Buffer

BufferLengthpTargetBuffer指向的Buffer的大小。

pBytesRead:實際讀到的數據的大小。

?

2.2.8???????? COM_Write

寫串口數據。應用程序調用WriteFile函數寫串口的時候,該函數被調用。

pContextCOM_Open函數返回的Handle

pSourceBytes:指向一個Buffer,該Buffer包含要寫入串口的數據。

NumberOfBytes:要寫入串口的數據的大小。

?

2.2.9???????? COM_Seek

?

2.2.10?????? COM_PowerDown

該函數主要用于串口設備從正常模式進入suspend狀態之前需要做的動作。

pContext:串口設備的Handle。

?

2.2.11?????? COM_PowerUp

該函數主要用于串口設備從suspend模式恢復到正常模式。

pContext:串口設備的Handle

?

2.2.12?????? COM_IOControl

該函數主要實現了一些串口的IO控制,它會被應用層的一些串口函數調用來獲得或者設置串口的狀態。

dwOpenDataCOM_Open函數返回的Handle

dwCodeI/O控制操作碼。

pBufIn:傳入的Buffer。

dwLenIn:傳入的Buffer的大小。

pBufOut:傳出的Buffer

dwLenOut:傳出的Buffer的大小。

pdwActualOut:實際傳出的數據的大小。

對于串口驅動來說,COM_IOControl函數非常有用,應用程序通過調用COM_IOControl函數并傳入不同的操作碼,實現了控制串口的功能。這里列舉一些操作碼如下:

操作碼 ? 解釋

IOCTL_SERIAL_CLR_DTR

設置串口的DTR管腳為低

IOCTL_SERIAL_CLR_RTS

設置串口的RTS管腳為低

IOCTL_SERIAL_DISABLE_IR

禁用串口的紅外模式

IOCTL_SERIAL_ENABLE_IR

啟用串口的紅外模式

IOCTL_SERIAL_GET_COMMSTATUS

清除串口設備的異常標記并返回當前狀態

IOCTL_SERIAL_GET_DCB

獲得串口的DCB結構

IOCTL_SERIAL_GET_MODEMSTATUS

獲得當前Modem的控制寄存器值

IOCTL_SERIAL_GET_PROPERTIES

重新獲得當前串口設備的硬件屬性

IOCTL_SERIAL_GET_TIMEOUTS

獲得串口設備的讀寫超時

IOCTL_SERIAL_GET_WAIT_MASK

獲得等待事件標記掩碼

IOCTL_SERIAL_IMMEDIATE_CHAR

在發送數據前,先發送一個特定的字符

IOCTL_SERIAL_PURGE

清除串口中的輸入輸出Buffer,也可以中止未進行的讀寫操作

IOCTL_SERIAL_SET_BREAK_OFF

串口通訊從中斷狀態恢復

IOCTL_SERIAL_SET_BREAK_ON

設置串口為中斷狀態,停止發送接收數據

IOCTL_SERIAL_SET_DCB

設置串口的DCB結構

IOCTL_SERIAL_SET_DTR

設置串口的DTR管腳為高

IOCTL_SERIAL_SET_QUEUE_SIZE

目前,在微軟的MDD層代碼中沒有支持

IOCTL_SERIAL_SET_RTS

設置串口的RTS管腳為高

IOCTL_SERIAL_SET_TIMEOUTS

設置串口的讀寫操作超時

IOCTL_SERIAL_SET_WAIT_MASK

設置等待事件標記掩碼

IOCTL_SERIAL_SET_XOFF

軟件流控模式下,終止數據傳輸

IOCTL_SERIAL_SET_XON

軟件流控模式下,啟動數據傳輸

IOCTL_SERIAL_WAIT_ON_MASK

等待一個與事件掩碼中匹配的事件

上述的操作碼,很多都會被應用程序調用,看看MDD層中的實現,其中一些也是調用了PDD層下的函數來完成對串口硬件的設置。

?

2.3?? PDD層為MDD層提供的接口

MDD層和PDD層交互的接口是結構體HWOBJ,在串口驅動中,HWOBJ結構中的函數實現了對串口硬件的操作,并在MDD層被調用,定義如下:

?

8

BindFlags:用于控制MDD層還是PDD層來啟動IST,具體值如下

?

9

dwInitID:系統的中斷號 ,此成員本來用于當BindFlags取值為THREAD_IN_MDD,也就是在MDD層啟動IST線程時記錄串口使用的邏輯中斷號,但是當前的串口驅動實在PDD層啟動IST,所以現在dwIntID成員的取值不是中斷號信息,而是借用來記錄與串口驅動程序的PDD層對應的串口的端口號。

?

pFuncTbl 指向一個PHW_VTBL結構,該結構中包含一個函數指針列表,這些函數指針指向串口硬件操作函數,用于操作串口。

?

那么結構體HWOBJ的成員是在哪里賦值的呢?從圖7我們控制COM_Init函數調用函數GetSerialObject來獲取PDD層的創建并且初始化的串口對象,就是在該函數中初始化HWOBJ的結構體成員的,如下圖

?

10

下面我們來看HW_VTBL類型的全局變量IoVTbl的定義

?

11??????????????????

????????????? 12

下面來學習這些函數的功能

2.3.1???????? HWInit函數

結合圖71112可知COM_Init函數在調用GetSerialObject函數來填充全局變量IoVTbl的成員函數指針后,就調用HWInit也就是SerInit函數來初始化PDD層,下面來看看這個函數的實現

?

13

下面就來看看CreateSerialObject函數體

?

14

?

2.3.2???????? HWPostInit函數

MDDCOM_Init函數的末尾階段,在初始化所有的數據結構之后和準備IST開始處理中斷之前,會調用該函數來執行一些必要的操作。代表性地,可以在該函數中enable硬件中斷,但這里只是具體沒有做實質上的工作,只是

m_dwInterruptFlag = INTR_NONE;

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

?

?

?

2.3.3???????? HWDeinit函數

當卸載串口驅動的時候,MDD層會調用該函數來釋放一些資源。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

15

2.3.4???????? HWOpen函數

MDD層調用該函數來打開一個串口設備,并且為此串口設備供電。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

16

下面我們學習InitLine函數

?

17

下面看看EnableInterrupt函數

?

18

繼續深入看看Write_UINTSP函數,如下:

?

19

假如現在加載的是UART1對應的出口驅動,我們先來看下面調用關系m_pReg在哪里初始化的,

CreateSerialObject()->CPdd6410Serial1::()->CPdd6410Uart::Init()->CPdd6410Uart::MapHardware()+CPdd6410Uart::CreateHardwareAccess()下面就來看看這兩個函數體:

?

20

結合下圖

?

21

?

2.3.5???????? HWClose函數

關閉由HWInit函數初始化的設備。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

2.3.6???????? HWGetIntrType函數

當中斷發生的時候,MDD層會調用該函數來獲取中斷類型,可能的中斷類型值有INTR_NONEINTR_LINE、INTR_RXINTR_TXINTR_MODEM。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

2.3.7???????? HWGetRxStart函數

返回硬件接收buffer的起始位置。

pContext:這個參數目前沒有使用。

?

2.3.8???????? HWGetBytes函數

RX_INTRHWGetIntrTypes函數返回時,MDD層會調用HWGetBytes函數來從UART中獲取接收到的數據。

?

2.3.9???????? HWRxIntrHandler函數

接收數據中斷處理函數。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

pTargetBuffer:接收到的數據要存放的buffer的起始地址。

pByteNumber:接收到的數據的字節數。

該函數實際會調用ReceiveInterruptHandler函數,我們下面就來看此函數

?

22

2.3.10?????? HWLineIntrHandler函數

該函數調用LineInterruptHandler()->GetModemStatus()來收集串口的line狀態并且更新串口驅動狀態信息。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

23

?

2.3.11?????? HWGetRxBufferSize函數

該函數返回硬件buffer能夠保持的最大字節數,確保要接收保存數據的buffer至少大于一個硬件buffer要保存的數據數。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

2.3.12?????? HWTxIntrHandler函數

該函數處理串口數據發送中斷,該函數指針就是由XmitInterruptHandler來賦值的,下面來分析這個函數。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

pSourceBuffer:發送數據Buffer。

pByteNumber:最大能夠發送的數據的大小。函數返回時,指向實際發送的數據的大小。

?

24

m_AutoFlowEnabled:用于表示是否支持自動流控。

fOutxCtsFlow:表示串口在發送數據時要檢測CTS(清除發送)引腳的信號狀態,如果該成員為TRUE并且對方將CTS的電平拉低,則發送數據;如果CTS引腳恢復為高電平時就暫停發送數據。

fOutxDsrFlow:成員表示串口在發送數據時要監視DSR(數據通信設備就緒,比如GPRS模塊SIM900)引腳的信號狀態,如果該成員為TRUE并且對方(這里假設是SIM900模塊)DSR的電平拉低,則發送數據;如果DSR引腳恢復為高電平時才繼續發送數據。

IsCTSOff()IsDSROff()函數分別用于判斷UMSTAT寄存器的第4和第5位的狀態值,見下圖

?

25

2.3.13?????? HWModemIntrHandler函數

該函數代替了HWOtherHandler函數,該函數實際會調用

ModemInterruptHandler函數,然后通過調用GetModemStatus函數來實現,下面來看此函數

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

26

2.3.14?????? HWPutBytes函數

該函數用于寫數據到硬件來直接發送數據。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

pSrc:指向要發送的數據Buffer

NumberOfBytes:要發送的數據長度。

pBytesSent:實際發送的數據長度。

?

?

?

?

2.3.15?????? HWPowerOff函數

在進入睡眠狀態前,MDD層調用該函數來通知PDD層對關閉PCLK對串口提供時鐘,以節省功耗,見下圖

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

?

?

2.3.16?????? HWPowerOn函數

在從睡眠狀態喚醒的時候,MDD層調用該函數來通知PDD層對關閉PCLK對串口提供時鐘,以節省功耗

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

27

?

2.3.17?????? HWClearDTR函數

該函數用于清除DTR(數據終端設備就緒)信號,通過調用SetDTR函數來實現

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

2.3.18?????? HWClearRTS函數

該函數用于清除RTS(請求發送)信號,通過調用SetRTS函數來實現

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

?

28

結合下圖可以更深刻去理解

?

29

?

?

2.3.19?????? HWSetDCB函數

該函數用于設置串口設備的信息,通過調用SetDCB函數來實現。

pContext:指向HWIint函數返回的設備上下文結構體,此結構體包含了對設備進行具體描述的數據信息。

pDCB:指向DCB結構,該結構描述相關的串口硬件設置信息。

?

30

2.3.20??????

?

?

2.4?? 流控的相關概念和方式

流控的“流”指進出串口的數據流,數據在串口之間傳輸時,如果接收方由于CPU負荷很重或者串口的中斷優先級很低而導致接收數據緩沖區被充滿,而發送方并不知情的情況下繼續發送的數據就會被接收方丟掉,為了解決這個問題,引進了串口的流控機制。這樣當接收方數據處理不過來時,就會發出“暫停接收”的信號,發送端就停止發送,直到收到“可以繼續發送”的信號再繼續發送數據。

流控的方式有硬件和軟件流控的方式,其中硬件流控有DTR/DSRRTS/CTS另種不同的硬件流控方式;軟件流是通過向對方發送特殊的指示字符,這就是被稱為X-ON/X-OFF的軟件流控方式,下面主要學習硬件流控方式

?

RTS/CTS流控方式

?

31

RTS/CTS流控方式的工作原理其實就是RTSCTS兩個引腳的工作方式,我們以DTE(這里為UART1)DCE(這里為SIM900)為例來說明。當UART1要發送數據時,就將nRTS的引腳拉低,表示UART1要向SIM900發送數據。nCTS信號時nRTS的響應信號,在SIM900準備好以后,就將引腳nCTS引腳信號拉低(結合圖2529來理解),這就表示SIM900準備好接受UART1發來的數據,這時候UART1就可以從TX引腳給SIM900發送數據了。

?

DTR/DSR流控方式

這種方式和RTS/CTS相似,DTR(data terminal ready,數據終端就緒)引腳置高表示數據終端設備處在有效的可使用狀態,DSR(data set ready,數據通信設備就緒)引腳置高則表示數據通信設備處于可使用的狀態。這兩個引腳為高電平僅表示對應的設備有效存在,并不表示它們之間的通信鏈路可以進行數據傳輸,這是它們和RTS/CTS的不同之處。在串口直接通信并且不使用DTR/DSR流控的情況下,通常將這兩個引腳直接接到電源上,串口一上電就拉高有效。

?

總結

以上是生活随笔為你收集整理的WINCE6.0+S3C6410串口驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。