2009年12月31日 星期四

串口通訊編程一日通2(Overlapped IO模型)

第一篇初步瞭解串口的大致運作,接下來我們看基本操作

先看串口操作的數據結構:

串口操作有幾個比較重要的Struct

1.Overlapped I/O 異步I/O模型

異步I/O和同步I/O不同,同步I/O時,程序被掛起,一直到I/O處理完,程序才能獲得控制。異步I/O,調用一個函數告訴OS,進行I/O操作,不等I/O結束就立即返回,繼續程序執行,操作系統完成I/O之後,通知消息給你。Overlapped I/O只是一種模型,它可以由內核對像(hand),事件內核對像(hEvent), 異步過程調用(apcs) 和完成端口(I/O completion)實現。

Overlapped數據結構:

typedef struct _OVERLAPPED {
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;



DWORD Internal; 通常被保留,當GetOverlappedResult()傳回False並且GatLastError()並非傳回ERROR_IO_PENDINO時,該狀態置為系統定的狀態。
DWORD InternalHigh; 通常被保留,當GetOverlappedResult()傳回False時,為被傳輸數據的長度。
DWORD Offset; 指定文件的位置,從該位置傳送數據,文件位置是相對文件開始處的字節偏移量。調用 ReadFile或WriteFile函數之前調用進程設置這個成員,讀寫命名管道及通信設備時調用進程忽略這個成員;
DWORD OffsetHigh; 指定開始傳送數據的字節偏移量的高位字,讀寫命名管道及通
信設備時調用進程忽略這個成員;
HANDLE hEvent; 標識事件,數據傳送完成時把它設為信號狀態,調用ReadFile
WriteFile ConnectNamedPipe TransactNamedPipe函數前,調用進程設置這個成員. 相關函數
CreateEvent ResetEvent GetOverlappedResult
WaitForSingleObject CWinThread GetLastError

OVERLAPPED和數據緩衝區釋放問題:
在請求時,不能釋放,只有在I/O請求完成之後,才可以釋放。如果發出多個overlapped請求,每個overlapped讀寫操作,都必須包含文件位置(socket),另外,如果有多個磁盤,I/O執行次序無法保證。(每個overlapped都是獨立的請求操作)。


內核對像(hand)實現:
例子:用overlapped模型讀一個磁盤文件內容。
1.把設備句柄看作同步對象,ReadFile將設備句柄設為無信號。ReadFile 異步I/O字節位置必須在OVERLAPPED結構中指定。
2.完成I/O,設置信息狀態。為有信號。
3.WaitForSingleObject或WaitForMultipleObject判斷
或者異步設備調用GetOverLappedResult函數。

view plaincopy to clipboardprint?
int main()
{
BOOL rc;
HANDLE hFile;
DWORD numread;
OVERLAPPED overlap;
char buf[READ_SIZE];
char szPath[MAX_PATH];
CheckOsVersion();

GetWindowsDirectory(szPath, sizeof(szPath));
strcat(szPath, "\\WINHLP32.EXE");
hFile = CreateFile( szPath,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open %s\n", szPath);
return -1;
}

memset(&overlap, 0, sizeof(overlap));
overlap.Offset = 1500;

rc = ReadFile(
hFile,
buf,
READ_SIZE,
&numread,
&overlap
);
printf("Issued read request\n");
if (rc)
{
printf("Request was returned immediately\n");
}
else
{
if (GetLastError() == ERROR_IO_PENDING)
{
printf("Request queued, waiting...\n");
WaitForSingleObject(hFile, INFINITE);
printf("Request completed.\n");
rc = GetOverlappedResult(

參考來源:

"串口通訊編程一日通2(Overlapped IO模型)"
- 串口通讯编程一日通2(Overlapped IO模型) - September - CSDN博客 (在「Google 網頁註解」中檢視)

沒有留言:

張貼留言