/======================================================== =========================================== // Title: // comparison of Running Mechanism between WINXP and wince serial port // Author: // norains // Date: // Saturday 11-November-2006 // passedenvironment: // PC: WINXP vc6.0 // Ce: wince4.2 evc4.0 // ======================================== ========================================== serial Communication document, it can be found that in the desktop operating system, serial communication is divided into two 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 asynchronous. 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. for example, if you call the readfile () function to read the serial port, but the previous writefile () operation is incomplete, the readfile () operation is blocked until the writefile () operation is complete. asynchronous means that the currently called Operation is executed no matter whether the previous operation is complete or not. in asynchronous mode, even if the writefile () is not completed, readfile () will be executed immediately. 1. the differences between the createfile () parameters first describe the differences between parameters when the port is 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. example: handlehd = createfile (text ("COM1:"), generic_read | generic _ Write, 0, null, open_existing, 0, null); // wincehandlehd = createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, null); // WINXP. 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 uses code as an example to describe the comparison image. this is a single-threaded code. First, write the serial port and then read it. for WINXP, This is the synchronization mode. (Code irrelevant to the topic is omitted) intwinapiwinmain (hinstancehinstance, hinstancehprevinstance, lptstr lpcmdline, int n Cmdshow ){... handlehcom = createfile (text ("COM1:"), generic_read | generic_write, 0, null, open_existing, 0, null ); // wince // handlecom = createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, null); // WINXP... dworddwbytes; Software Development Network if (writefile (hcom, text ("COM1:"), 5, & dwbytes, null) = false) // wince // If (writefile (hcom, text ("COM1"), 5, & dwbytes, null) = false) // WINXP {return0x05 ;}... dworddwread; charszbuf [m Ax_read_buffer]; If (readfile (hcom, szbuf, max_read_buffer, & dwread, null) = false) {return0x10 ;}...} 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 multi-thread? 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 intwinapiwinmain (hinstancehinstance, hinstancehprevinstance, lptstr lpcmdline, int ncmdshow ){... createthread (null, 0, readthread, 0, 0, & dwthrdid); // create a read thread .... handlehcom = createfile (text ("COM1:"), generic_read | generic_write, 0, null, open_existing, 0, null); // wince // handlecom = Createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, null); // WINXP... dworddwbytes; If (writefile (hcom, "At \ r \ n", 4, & dwbytes, null) = false) // wince // If (writefile (hcom, "At \ r \ n", 5, & dwbytes, null) = false) // WINXP {return0x05 ;}...} // read thread dwordwinapireadthread (){... setcommmask (hcom), ev_rxchar); dworddwcommstatus = 0; If (waitcommevent (hcom), & dwcommstatus, null) = false) {// cleartheerrorflagdworddwerr ORS; comstatcomstat; memset (& COMSTAT, 0, sizeof (COMSTAT); clearcommerror (hcom, & dwerrors, & COMSTAT); return0x15 ;}... charszbuf [max_read_buffer] = {0}; dworddwread; If (readfile (hcom), szbuf, max_read_buffer, & dwread, null) = false | dwread = 0) {return0x20 ;}...} 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. run this code and we will find that the CPU usage is as high as 99%. through one-step debugging, it is found that the two threads are stuck in the waitcommevent () and writefile () functions respectively. because according to the definition of synchronization mode, the current You must wait until the previous operation is completed. in the above Code, because Device B does not receive a command from device A and does not send a response to device A, the waitcommevent () function keeps occupying the serial port because it does not detect receiving data; waitcommevent () keeps occupying the serial port so that writefile () is blocked because it does not get 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: // The main thread intwinapiwinmain (hinstancehinstance, hinstancehprevinstance, lptstr lpcmdline, int ncmdshow ){... creat ETHREAD (null, 0, readthread, 0, 0, & dwthrdid); // create a read thread .... handlecom = createfile (text ("COM1"), generic_read | generic_write, 0, null, open_existing, 0, file_flag_overlapped );... overlappedolwrite; memset (& olwrite, 0, sizeof (m_olwrite); olwrite. hevent = createevent (null, true, false, null); dworddwbytes; If (writefile (hcom, "At \ r \ n", 4, & dwbytes, & olwrite) = false) {If (getlasterror ()! = Error_io_pending) {return0x20 ;}} if (getoverlappedresult (hcom, & olwrite, & dwbytes, true) = false) {return0x25 ;}...} // read thread dwordwinapireadthread (){... memset (& olwaite, 0, sizeof (olwaite); olwaite. hevent = createevent (null, true, false, null); setcommmask (hcom), ev_rxchar); dworddwcommstatus = 0; waitcommevent (hcom, & dwcommstatus, olwaite); dworddwbyte; // norains: itisonlysuitableforthegetoverlappedresult (), notundefinedhere. If (getoverlappedresult (hcom, olwaite, & dwbyte, true) = false) {If (getlasterror ()! = Error_io_pending) {return0x30 ;}// response; comstatcomstat; memset (& COMSTAT, 0, sizeof (COMSTAT); clearcommerror (hcom, & dwerrors, & COMSTAT ); return0x35 ;}... memset (& olread, 0, sizeof (olread); olread. hevent = createevent (null, true, false, null); charszbuf [max_read_buffer] = {0}; dworddwread; If (readfile (hcom, szbuf, max_read_buffer, & dwread, olread) = false) {If (getlasterror ()! = Error_io_pending) {return0x40;} If (getoverlappedresult (hcom, olread, & dwread, true) = false) {return0x45;} If (dwread = 0) {return0x50 ;}}...} 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; in multithreading, the serial port running mode of Wince is consistent with the asynchronous mode of WINXP. although it is impossible to compare whether the single serial port mode of Wince is more advantageous than that of WINXP, it can be confirmed that the serial port call method of Wince has brought great convenience to programmers. 4. WINXP asynchronous mode two methods to determine whether the operation is successful because in WINXP asynchronous mode In most cases, writefile (), readfile (), and waitcommevent () are returned if the operation is not completed. Therefore, you cannot simply determine whether the return 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) {return0x40;} If (getoverlappedresult (hcom, olread, & dwread, true) = false) {return0x45;} If (dwread = 0) {return0x50 ;}} 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, use the getlasterror () function to determine whether the read operation is performed in the background. if it is performed in the background, call the getoverlappedresult () function to obtain the result of the readfile () function. note that the last parameter of the getoverlappedresult () function must be set to true, indicating that the readfile () function must be in Return only after the background is completed. if the last parameter is set to false, the getoverlappedresult () function will return immediately even if readfile () is still executed in the background, resulting in an incorrect judgment. the other is to call the waitforsingleobject function to achieve this goal: If (readfile (hcom, szbuf, max_read_buffer, & dwread, olread) = false) {If (getlasterror ()! = Error_io_pending) {return0x40;} If (waitforsingleobject (olread. hevent, infinite )! = Wait_object_0) {return0x55;} If (getoverlappedresult (hcom, olread, & dwread, false) = false) {return0x45;} If (dwread = 0) {return0x50 ;}} because after readfile () is executed in the background, an event will be sent, so here you can call waitforsingleobject () to wait until the readfile () is executed, and then call getoverlappedresult () to get readfile (). note that the last parameter of getoverlappedresult () must be set to false because waitforsingleobject () has captured the event sent by readfile, no more events are passed to the getoverlappedresult () function. if the last getoverlappedresult () parameter is set to true at this time, the thread will stay in the getoverlappedresult () function without executing it.
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.