Comparison Between running mechanism of WINXP and wince serial port

Source: Internet
Author: User
Tags readfile

// ================================================ ========================================
// Title:
// Comparison of Running Mechanism between WINXP and wince serial port
// Author:
// Norains
// Date:
// Saturday 25-November-2006
// Passed environment:
// PC: WINXP + vc6.0
// Ce: wince4.2 + evc4.0
// ================================================ ========================================
You can see that in the desktop operating system, there are two serial communication modes: synchronous and asynchronous. there is only one type of wince, but the document does not indicate the mode of ownership. in fact, the serial port communication mode of Wince is more like synchronous and asynchronous.

This section briefly introduces synchronization and Asynchronization. the so-called synchronization means that the read or write operations on the same device or file (only the serial port COM1 in the text) must wait until the previous operation is completed. ratio
For example, when the readfile () function is called to read the serial port, but the previous writefile () operation is not completed, the readfile () operation is blocked
Before the writefile () operation can be run. asynchronous, the current called operation will be executed no matter whether the previous operation is complete or not. In asynchronous mode, even if
Writefile () is not completed, and readfile () is executed immediately.


1. Differences in createfile () Parameters
First, describe the parameter differences between the port opened by wince and WINXP. take the serial port COM1 as an example. The name of Wince is "COM1:", and WINXP is "COM1". The only difference between the two is that there are multiple semicolons under wince.
For example:
Handle Hd = createfile (text ("COM1:"), generic_read | generic_write, 0, null, open_existing, 0, null); // WinCE
Handle Hd = createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, null); // WINXP
In this case, in the default environment, the text Macro will be compiled into dubyte in wince, while WINXP is a single byte. in other words, text ("COM1") is equivalent to L "COM1" under wince, while WINXP is "COM1 ".


2. Single-thread comparison
Still used Code This is a single-threaded code. First write the serial port and then read it. For WINXP, This is the synchronization mode. (The Code irrelevant to the subject is omitted)
Int winapi winmain (hinstance,
Hinstance hprevinstance,
Lptstr lpcmdline,
Int ncmdshow)
{
...
Handle hcom = createfile (text ("COM1:"), generic_read | generic_write, 0, null, open_existing, 0, null); // WinCE
// Handle COM = createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, null); // WINXP

...
DWORD dwbytes;
If (writefile (hcom, text ("COM1:"), 5, & dwbytes, null) = false) // WinCE
// If (writefile (hcom, text ("COM1"), 5, & dwbytes, null) = false) // WINXP
{
Return 0x05;
}

...
DWORD dwread;
Char szbuf [max_read_buffer];
If (readfile (hcom, szbuf, max_read_buffer, & dwread, null) = false)
{
Return 0x10;
}

...
}
After experiment, we can find that this code works normally in both Windows XP and Windows XP, and its performance is the same. It is only executed after the writefile () function returns ().
Because the asynchronous mode works normally in a single thread, the only difference is that when writefile () is executed, it may also execute readfile () (depending on the time when the writefile () function is executed ), the table is not listed here.

3. multi-thread comparison
The performance of a single thread is the same. What about multithreading? The following code uses multithreading. It first creates a read thread to monitor whether new data arrives at the serial port, and then writes data to the serial port in the main thread.
Assume that there are two devices, device A and Device B, and the following code runs on device A. Device B only responds. in other words, B returns a response signal only when a sends data to B.
// Main thread
Int winapi winmain (hinstance,
Hinstance hprevinstance,
Lptstr lpcmdline,
Int ncmdshow)
{
...
Createthread (null, 0, readthread, 0, 0, & dwthrdid); // create a read thread.

...
Handle hcom = createfile (text ("COM1:"), generic_read | generic_write, 0, null, open_existing, 0, null); // WinCE
// Handle COM = createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, null); // WINXP

...
DWORD dwbytes;
If (writefile (hcom, "At/R/N", 4, & dwbytes, null) = false) // WinCE
// If (writefile (hcom, "At/R/N", 5, & dwbytes, null) = false) // WINXP
{
Return 0x05;
}

...

}

// Read thread
DWORD winapi readthread ()
{
...
Setcommmask (hcom), ev_rxchar );
DWORD dwcommstatus = 0;
If (waitcommevent (hcom), & dwcommstatus, null) = false)
{
// Clear the error flag
DWORD dwerrors;
COMSTAT;
Memset (& COMSTAT, 0, sizeof (COMSTAT ));
Clearcommerror (hcom, & dwerrors, & COMSTAT );
Return 0x15;
}

...
Char szbuf [max_read_buffer] = {0 };
DWORD dwread;
If (readfile (hcom), szbuf, max_read_buffer, & dwread, null) = false | dwread = 0)
{
Return 0x20;
}

...
}

This code runs completely normally under wince. While the reading thread monitors the received data, the main thread smoothly sends data out.

However, the same Code cannot be completed in WINXP. By running this code, we will find that the CPU usage is as high as 99%. through single-step debugging, we find that the two threads are stuck in
Waitcommevent () and writefile () functions. According to the definition of synchronization mode, the current operation on the device must wait until the previous operation is completed.
In the code, because Device B does not receive a command from device A and does not send a response to device A, the waitcommevent () function is always occupying the serial port because it does not detect receiving data.
Waitcommevent () has been occupying the serial port so that writefile () is blocked because it does not obtain the serial port resources, which causes a deadlock.
This situation does not occur on WinCE. As long as waitcommevent () and writefile () are not in the same thread, they can work normally. This should be related to the System Scheduling Method.

If you want to perform both waitcommevent () and writefile () operations on the PC, you need to rewrite the serial port mode to the asynchronous mode.
The changed code is as follows:

// Main thread
Int winapi winmain (hinstance,
Hinstance hprevinstance,
Lptstr lpcmdline,
Int ncmdshow)
{
...
Createthread (null, 0, readthread, 0, 0, & dwthrdid); // create a read thread.

...
Handle COM = createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, file_flag_overlapped );

...
Overlapped olwrite;
Memset (& olwrite, 0, sizeof (m_olwrite ));
Olwrite. hevent = createevent (null, true, false, null );

DWORD dwbytes;
If (writefile (hcom, "At/R/N", 4, & dwbytes, & olwrite) = false)
{
If (getlasterror ()! = Error_io_pending)
{
Return 0x20;
}
}
If (getoverlappedresult (hcom, & olwrite, & dwbytes, true) = false)
{
Return 0x25;
}
...

}

// Read thread
DWORD winapi readthread ()
{
...
Memset (& olwaite, 0, sizeof (olwaite ));
Olwaite. hevent = createevent (null, true, false, null );
Setcommmask (hcom), ev_rxchar );
DWORD dwcommstatus = 0;
Waitcommevent (hcom, & dwcommstatus, olwaite );
DWORD dwbyte; // norains: It is only suitable for the getoverlappedresult (), not undefined here.
If (getoverlappedresult (hcom, olwaite, & dwbyte, true) = false)
{
If (getlasterror ()! = Error_io_pending)
{
Return 0x30;
}
// Clear the error flag
DWORD dwerrors;
COMSTAT;
Memset (& COMSTAT, 0, sizeof (COMSTAT ));
Clearcommerror (hcom, & dwerrors, & COMSTAT );
Return 0x35;
}

...
Memset (& olread, 0, sizeof (olread ));
Olread. hevent = createevent (null, true, false, null );
Char szbuf [max_read_buffer] = {0 };
DWORD dwread;
If (readfile (hcom, szbuf, max_read_buffer, & dwread, olread) = false)
{
If (getlasterror ()! = Error_io_pending)
{
Return 0x40;
}
If (getoverlappedresult (hcom, olread, & dwread, true) = false)
{
Return 0x45;
}
If (dwread = 0)
{
Return 0x50;
}
}

...
}

After testing the changed code, we can find that waitcommevent () and writefile () can be called simultaneously under WINXP without causing a deadlock.

Here we can find the differences between the serial scheduling of wince and WINXP: in a single thread, the serial running mode of Wince is consistent with the synchronous working mode of the WINXP serial port;
But it is in line with the asynchronous mode of WINXP. Although it is not possible to compare whether the single serial port mode of Windows XP is more advantageous than the dual-mode of Windows XP, it can be confirmed that
Yes, the serial port call method of Wince is Program Personnel bring great convenience.


4. WINXP asynchronous mode: two methods to determine whether the operation is successful
In the asynchronous mode of WINXP, writefile (), readfile (), and waitcommevent () are returned if the operation is not completed, therefore, you cannot simply judge whether the returned value is true or false.
Use the readfile () function as an example.
One is the method used above:
If (readfile (hcom, szbuf, max_read_buffer, & dwread, olread) = false)
{
If (getlasterror ()! = Error_io_pending)
{
Return 0x40;
}
If (getoverlappedresult (hcom, olread, & dwread, true) = false)
{
Return 0x45;
}
If (dwread = 0)
{
Return 0x50;
}
}
If readfile () returns true, it indicates that the read file has been completed. however, this situation will hardly occur, because the read and write operations on peripherals are very slow compared to the memory read and write operations, so the readfile () function has not been executed, and the program has been executed to the next statement.

When readfile () returns false, you must use the getlasterror () function to determine whether the read operation is performed in the background. If the read operation is performed in the background, you can call
The getoverlappedresult () function obtains the result of the readfile () function. Note that the getoverlappedresult () function
The last parameter of the number must be set to true, indicating that the result is returned only after the readfile () function is completed in the background. If the last parameter is set to false
Readfile () is still executed in the background, and the getoverlappedresult () function will return immediately, resulting in an error in judgment.

The other is to call the waitforsingleobject function for this purpose:
If (readfile (hcom, szbuf, max_read_buffer, & dwread, olread) = false)
{
If (getlasterror ()! = Error_io_pending)
{
Return 0x40;
}
If (waitforsingleobject (olread. hevent, infinite )! = Wait_object_0)
{
Return 0x55;
}
If (getoverlappedresult (hcom, olread, & dwread, false) = false)
{
Return 0x45;
}
If (dwread = 0)
{
Return 0x50;
}
}

Because readfile () sends an event after it is executed in the background, you can call waitforsingleobject () here to wait
After readfile () is executed, call getoverlappedresult () to obtain the final result of readfile (). Note that
Yes, the last parameter of getoverlappedresult () must be set to false, because waitforsingleobject () has captured
The event sent by readfile () is no longer passed to the getoverlappedresult () function. If
If the last parameter of getoverlappedresult () is set to true, the thread will stay in the getoverlappedresult () function without executing
Line.

 

There are many parameter errors in the Code. Please note that

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.