Function documentation for API com Serial Port Programming

Source: Internet
Author: User

Recording:
1. Advantages of asynchronous non-blocking Serial Communication
2. Basic principles of asynchronous non-blocking Serial Communication
3. Basic knowledge of asynchronous non-blocking Serial Communication
4. Implementation steps of asynchronous non-blocking Serial Communication
2005.01.05

I. Advantages of asynchronous non-blocking Serial Communication

When reading and writing a serial port, it can be executed simultaneously or asynchronously.
During synchronous execution, the function is not returned until the operation is complete. This means that the thread will be blocked during synchronous execution, resulting in lower efficiency.
During overlapping operations, the called function returns immediately even if the operation is not completed. Time-consuming I/O operations are performed in the background so that threads can do other things.
For example, a thread can execute I/O operations on different handles at the same time, or even perform read/write operations on the same handle at the same time. This is the meaning of the word "Overlap.

Ii. Basic principles of asynchronous non-blocking Serial Communication
First, determine the serial port name, baud rate, parity method, data bit, and stop bit to be opened and pass it to the createfile () function to open a specific serial port;
Second, to protect the system's initial settings for the serial port, call getcommtimeouts () to obtain the original timeout settings for the serial port;
Then, initialize the DCB object, call setcommstate () to set DCB, call setcommtimeouts () to set serial port timeout control;
Once again, call setupcomm () to set the buffer size for the serial port to receive and send data. The serial port settings are basically complete, and then the read/write thread can be started.

III. Basic knowledge of asynchronous non-blocking Serial Communication
The following describes and illustrates several key functions that will be used in programming asynchronous non-blocking serial communication.

Createfile ()
Function: Enable the serial port device.
Function prototype
Handle createfile (
Lptstr lpfilename, // serial port name string; for example: "COM1" or "com2"
DWORD dwdesiredaccess, // set the read/write attribute (access mode); Generally, it is generic_read | generic_write,
DWORD dw1_mode, // share mode; "required" is 0, that is, cannot share
Lpsecurity_attributes lpsecurityattributes, // Security Attribute; generally null
DWORD dwcreationdistribution, // creation method. This value must be set for serial port settings. "required" is open_existing
DWORD dwflagsandattributes, // file attributes and flag; here we set it to file_flag_overlapped to Implement Asynchronous I/O
Handle htemplatefile // temporary file handle, usually null
);
Note:
If the call is successful, the function returns the file handle. If the call fails, the function returns invalid_handle_value.
Forexample:

Handle m_hcomm = createfile (COM1, generic_read | generic_write, 0, null, open_existing, file_flag_overlapped, 0 );

Closehandle ();
Function: Disable the serial port.
Bool closehandle (
Handle hobject // handle to object to close
)
I don't want to say much about this!

Getcommstate ()
Function: Obtain the serial port status.
Bool getcommstate (
Handle hfile, // handle of communications device
Lpdcb // address of device-Control Block Structure
);

Setcommstate ()
Function: sets the serial port status.
Bool setcommstate (
Handle hfile, // handle of communications device
Lpdcb // address of device-Control Block Structure
);
Note:
After the communication device handle is opened, you often need to initialize the serial port. This requires a DCB structure. The DCB structure contains information such as the baud rate, the number of data digits for each character, the parity and the number of stopped digits. When querying or configuring the properties of a serial port, the DCB structure is used as the buffer zone.
Call the getcommstate function to obtain the serial port configuration. This function fills the current configuration in a DCB structure. After using createfile to open a serial port, you can call the getcommstate function to obtain the initial configuration of the serial port. To modify the configuration of a serial port, you should first modify the DCB structure, and then call the setcommstate function to set the serial port with the specified DCB structure.
Forexample:
DCB;
Memset (& dec, 0, dizeof (DCB ));
If (! Getcommstate (hcomm, & DCB) // obtain the current DCB Configuration
Return false;
DCB. baudrate = cbr_9600; // modify the data transfer rate
............
If (setcommstate (hcomm, & DCB) // set the New Parameter
... // Handle errors

Buildcommdcb ()
Function: Initialize the DCB structure.
Bool buildcommdcb (
Lptstr lpdef, // pointer to device-control string
Lpdcb // pointer to device-Control Block
);
Forexample:
DCB;
Memset (& DCB, 0, sizeof (DCB ));
DCB. dcblength = sizeof (DCB );
If (! Buildcommdcb ("9600, N, 9600", & DCB) // "baud = parity = n data = 8 stop = 1"
{
... // Parameter modification Error
Return false;
}
Else
{
... // Ready
}
Note: The function is similar to the preceding example.

Setupcomm ()
Function: sets the size of the I/O buffer.
Function prototype:
Bool setupcomm (
Handle hfile, // handle to communications device
DWORD dwinqueue, // size of input buffer
DWORD dwoutqueue // size of output buffer
);
Note:
In addition to the settings in DCB, the program generally needs to set the size and timeout of the I/O buffer. Windows uses an I/O buffer to store input and output data of a serial port. If the communication speed is high, a large buffer zone should be set. You can call the setupcomm function to set the input and output buffer sizes of the serial port.

 

First introduce a structure: commtimeouts

Typedef struct _ commtimeouts {
DWORD readintervaltimeout; // read interval timeout
DWORD readtotaltimeoutmultiplier; // read time coefficient
DWORD readtotaltimeoutconstant; // read Time Constant
DWORD writetotaltimeoutmultiplier; // write time coefficient
DWORD writetotaltimeoutconstant; // write time constant
} Commtimeouts, * lpcommtimeouts;

Two more functions
Getcommtimeouts
Function: Read the value of timeout.
Function prototype:
Bool getcommtimeouts (
Handle hfile, // handle of communications device
Lpcommtimeouts // address of Comm. time-outs Structure
);
Setcommtimeouts
Function: set the value of timeout.
Function prototype:
Bool setcommtimeouts (
Handle hfile, // handle of communications device
Lpcommtimeouts // address of communications time-out Structure
);

Here, we will introduce the two properties of the timeout mechanism:

Timeout Function
Note:
Timeout must be considered when readfile and writefile are used to read and write the serial port. If no specified number of characters are read or written within the specified time period, the readfile or writefile operation ends. To query the current timeout settings, call the getcommtimeouts function, which will fill in a commtimeouts structure. You can call setcommtimeouts to set the timeout value using the content of a commtimeouts structure.

There are two types of Timeout: interval timeout and total timeout. The interval timeout refers to the maximum latency between two characters at the time of receiving. The total timeout refers to the maximum time spent in read/write operations. Write operations only support total timeouts, while read Operations Support both timeouts. The commtimeouts structure can be used to specify the read/write operation timeout. The structure is defined as: Members of the commtimeouts structure are all in milliseconds. The formula for calculating the total timeout is:

Total timeout = time coefficient × number of characters required to read/write + Time Constant

For example, if you want to read 10 characters, the formula for calculating the total read operation timeout is:

Total read timeout = readtotaltimeoutmultiplier × 10 + readtotaltimeoutconstant

It can be seen that the interval timeout and total timeout settings are irrelevant, which allows the communication program to flexibly set various timeout settings.

If all write timeout parameters are 0, write timeout is not used. If readintervaltimeout is 0, the read interval timeout is not used. If both readtotaltimeoutmultiplier and readtotaltimeoutconstant are 0, the total read timeout is not used. If the read interval time-out is set to maxdword and the total read time-out between the two is 0, the read operation is completed immediately after the content in the input buffer is read, regardless of whether the required characters are read.

When reading and writing a serial port in overlapping mode, although readfile and writefile may return before the operation is completed, the timeout still works. In this case, the timeout specifies the operation completion time, rather than the return time of readfile and writefile.

Forexample:
Commtimeouts timeover;
Memset (& timeover.0.sizeof (timeover ));
Dwordtimemultiplier, timeconstant;
Timeover. readtotaltimeoutmultiplier = timemultiplier;
Timeover. readtotaltimeoutconstant = timeconstant;
Setcommtimeouts (hcomport, & timeover );

Readfile ()
Function: Read data.
Function prototype:
Bool readfile (
Handle hfile, // serial port name string (file handle)
Lpvoid lpbuffer, // read buffer
DWORD nnumberofbytestoread, // number of bytes to be read
Lpdword lpnumberofbytesread, // number of bytes actually read
Lpoverlapped // point to an overlapped Structure
); // If true is returned, the operation is successful.

Forexample:
Char * precivebuf;
DWORD nwantread = 100,
Nreadread;
Lpoverlapped m_overlappedread;
Bool breadstatus = readfile (m_hcomm, precivebuf, nwantread, & nreadread, & m_overlappedread );

Writefile ()
Function: Write Data to serial port.
Function prototype:
Bool writefile (
Handle hfile, // handle to file to write
Lpvoid lpbuffer, // pointer to data to write to file
DWORD nnumberofbytestowrite, // number of bytes to write
Lpdword lpnumberofbyteswritten, // pointer to number of bytes written
Lpoverlapped // pointer to structure needed for overlapped I/O
);

Note:
The readfile function completes the operation by reading a specified number of characters in the input buffer of a serial port.
The writefile function not only needs to merge a specified number of characters into the output buffer, but also completes the operation after these characters are sent from the serial port.

When readfile and writefile return false, the operation may not necessarily fail. The thread should call the getlasterror function to analyze the returned results. For example, if the operation is not completed before the overlapping operation, the function returns false, and the getlasterror function returns error_io_pending.

If the getlasterror function returns error_io_pending, the overlap operation is still completed, and the thread can wait for the Operation to complete.
There are two ways to wait: one is to use a wait function like waitforsingleobject to wait for hevent members in the overlapped structure,
You can specify the waiting time. Call getoverlappedresult after the function returns.
Another method is to call the getoverlappedresult function to wait. If the bwait parameter of the function is specified as true,
This function will wait for the hevent event of the overlapped structure.
Getoverlappedresult returns an overlapped structure to report the overlapping operation results, including the actual transmitted bytes.

If the read/write operation times out, the hevent member will become a signal when the specified time is exceeded. Therefore, after a timeout occurs, both waitforsingleobject and getoverlappedresult end the wait. The dwmilliseconds parameter of waitforsingleobject specifies a wait timeout value. The actual wait time of this function is the minimum value of the two timeout values. Note that the getoverlappedresult cannot be set as the waiting time limit. Therefore, if the hevent member does not have a signal, the function will keep waiting.

Clearcommerror ()
Function: literally, it is used to clear errors, but in fact it can also get some information about the current communication device.
Function prototype:
Bool clearcommerror (
Handle hfile, // handle to communications device
Lpdword lperrors, // pointer to variable to receive error codes
Lpcomstat lpstat // pointer to buffer for communications Status
);
Note:
Before calling readfile and writefile, the thread should call the clearcommerror function to clear the error mark.
This function is used to report specified errors and the current status of the device.

Purgecomm ()
Function: terminates the read or write operations currently in progress.
Function prototype:
Bool purgecomm (
Handle hfile, // handle of communications Resource
DWORD dwflags // action to perform
);
Parameter description:
Handle hfile, // serial name string
Dwflags has four types of flags:

Purge_txabort: ends the currently ongoing (background) write action.
Purge_rxabort: The (background) read currently in progress
Purge_txclear: Buffer written by flush
Purge_txclear: Buffer read by flush
You can call the purgecomm function to terminate ongoing read/write operations. This function also clears the content in the input or output buffer.

Getcommmask ()
Function: Obtain the communication event mask.
Function prototype:
Bool getcommmask (
Handle hfile, // handle of communications device
Lpdword lpevtmask // address of variable to get event mask
);

Setcommmask ()
Function: sets the mask of the communication event to be obtained.
Function prototype:
Bool setcommmask (
Handle hfile, // handle of communications device
DWORD dwevtmask // mask that identifies enabled events
);
Note:
Configurable communication event flag (that is, the mask set by the setcommmask () function)
The options include ev_break, ev_cts, ev_dsr, ev_err, ev_ring, ev_rlsd, ev_rxchar, ev_rxflag, and ev_txempty.

Note: If you have strict response time requirements on port data, you can use event-driven I/O read/write. In Windows, nine serial communication events are defined, which are commonly used:

Ev_rxchar: receives a byte and puts it in the input buffer.

Ev_txempty: The last character in the output buffer is sent out.

Ev_rxflag: receives event characters (evtchar members in the DCB structure) and puts them in the input buffer.

The following is an explanation on msdn:
Ev_break a break was detected on input.
Ev_cts the CTS (clear-to-send) signal changed state.
Ev_dsr the DSR (data-set-ready) signal changed state.
Ev_err a line-status error occurred. Line-status errors are ce_frame, ce_overrun, and ce_rxparity.
Ev_ring a ring indicator was detected.
Ev_rlsd the RlSD (receive-line-signal-detect) signal changed state.
Ev_rxchar a character was stored Ed and placed in the input buffer.
Ev_rxflag the event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the setcommstate function.
Ev_txempty the last character in the output buffer was sent.

Waitcommevent ()
Function: waits for the occurrence of the specified communication event.
Function prototype:
Bool waitcommevent (
Handle hfile, // handle of communications device
Lpdword lpevtmask, // address of variable for event that occurred
Lpoverlapped, // address of overlapped Structure
);
Note:
Waitcommevent () will block until the specified communication event occurs.
Therefore, when waitcommevent () returns, you can obtain the event from lpevtmask and decide how to handle it.

Waitforsingleobject ()
Function: The waiting function for thread synchronization.
Function prototype:
DWORD waitforsingleobject (handle hhandle, // synchronization object handle
DWORD dwmilliseconds // timeout interval in milliseconds. If it is set to infinite, the timeout interval is infinite.
);
Note:
Meaning of Return Value
Wait_failed function failed
The synchronization object specified by wait_object_0 is in a signal state.
Wait_abandoned the thread with a mutex has been interrupted, but the mutex has not been released
Wait_timeout is returned, and the synchronization object has no signal.

Waitformultipleobjects ()
Function: Monitors multiple synchronization objects at the same time.
Function prototype:
DWORD waitformultipleobjects (DWORD ncount, // Number of handles in the handle Array
Const handle * lphandles, // represents a handle Array
Bool bwaitall, // indicates the waiting type (). If it is true, the function returns only after all objects have signals,
// If it is false, the function returns the result as long as one object becomes signaled.
DWORD dwmilliseconds // timeout interval in milliseconds
);
Note:
Meaning of Return Value
Wait_object_0 To Wait _ object_0 + nCount-1 if bwaitall is true, the return value indicates that all objects have signals.
If bwaitall is false, the return value minus wait_object_0 is the minimum index of the signal pairs in the array.

Wait_abandoned_0 To Wait _ abandoned _ 0 + nCount-1 if bwaitall is true, the return value indicates that all objects have signals, but a mutex is abandoned. If bwaitall is false, the returned value minus wait_abandoned_0 indicates that the mutex index in the object array is discarded.
Wait_timeout

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.