windows 串口常用的几个函数

WaitCommEvent
                                          --------------------------

BOOL WINAPI WaitCommEvent
(
__in HANDLE hFile,
__out LPDWORD lpEvtMask,
__in LPOVERLAPPED lpOverlapped
);

hFile:指向通信设备的一个句柄,该句柄应该是由 CreateFile函数返回的。
lpEvtMask:一个指向DWORD的指针。如果发生错误,pEvtMask指向0,否则指向以下的某一事件

EV_DSR
0x0010
        
The DSR (data-set-ready) signal changed state. DSR(数据装置就绪)信号改变状态。
EV_ERR
0x0080
        
A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING
0x0100
        
A ring indicator was detected.
EV_RLSD
0x0020
        
The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR
0x0001
        
A character was received and placed in the input buffer.(在输入缓冲区中接收并放置一个字符)
EV_RXFLAG
0x0002
        
The event character was received and placed in the input buffer. The event character is specified in the device'sDCBstructure, which is applied to a serial port by using theSetCommStatefunction.
EV_TXEMPTY
0x0004
        
The last character in the output buffer was sent.(输出缓冲区的数据全部发送出去)

                                          CloseHandle()
                                            ----------------------

关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。

若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。

Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread.

                                             EVENT
                                            -------------
CreateEvent Creates or opens a named or unnamed event object.
CreateEventEx Creates or opens a named or unnamed event object and returns a handle to the object.
OpenEvent Opens an existing named event object.
PulseEvent Sets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate number of waiting threads.
ResetEvent Sets the specified event object to the nonsignaled state.
SetEvent Sets the specified event object to the signaled state.

Event原理解析
多线程同步Event,主要用于线程间的等待通知。

内核对象中,事件内核对象是个最基本的对象。它们包含一个使用计数(与所有内核对象一样),一个用于指明该事件是个自动重置的事件还是一个人工重置的事件的布尔值,另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。

事件能够通知一个操作已经完成。有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。

当一个线程执行初始化操作,然后通知另一个线程执行剩余的操作时,事件使用得最多。事件初始化为未通知状态,然后,当该线程完成它的初始化操作后,它就将事件设置为已通知状态。这时,一直在等待该事件的另一个线程发现该事件已经得到通知,因此它就变成可调度线程。


                                            TRACE
                                           ------------
In the debug version of MFC, this macro sends the specified string to the debugger of the current application.In a release build, this macro compiles to nothing (no code is generated at all).

                                     线程Signaled nonsignaled 状态的意思
                                    —————————————————
常见的线程同步方法(对象)有:
    互斥对象(Mutex),事件对象(Event),信号量(Semaphore),临界区(critical section)等。

    在线程同步过程中,需要先定义一个同步对象,同步对象一般具有两种状态:标志的(置位,signaled)和未标志的(未置位,nonsignaled)。线程根据是否已经完成操作将同步对象设置为标志的或未标志的。

    而等待函数的功能是专门用于等待同步对象状态改变。一个线程调用等待函数后执行会暂停,直到同步对象的状态改变后,等待函数才会返回,线程才会继续执行。等待函数分为“单对象”等待函数和“多对象”等待函数。

What is Signaled State?

One of two possible states for kernel-defined dispatcher objects, which support synchronization. When the kernel sets such an object to the Signaled state, any threads waiting on the object are released from their wait and become eligible for execution.

Wait handles have two states, signaled and nonsignaled.
A wait handle that is not owned by any thread is in the signaled state.
A wait handle that is owned by a thread is in the nonsignaled state.


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

hEvent

    A handle to the event that will be set to a signaled state by the system when the operation has completed. The user must initialize this member either to zero or a valid event handle using the CreateEvent function before passing this structure to any overlapped functions. This event can then be used to synchronize simultaneous I/O requests for a device. For additional information, see Remarks.

    Functions such as ReadFile and WriteFile set this handle to the nonsignaled state before they begin an I/O operation. When the operation has completed, the handle is set to the signaled state.

    Functions such as GetOverlappedResult and the synchronization wait functions reset auto-reset events to the nonsignaled state. Therefore, you should use a manual reset event; if you use an auto-reset event, your application can stop responding if you wait for the operation to complete and then call GetOverlappedResult with the bWait parameter set to TRUE.



                                   ClearCommError
                                 ---------------------------

ClearCommError函数的第一个参数hFile是由CreateFile函数返回指向已打开串行口的句柄。
Windows系统利用此函数清除硬件的通讯错误以及获取通讯设备的当前状态,
ClearCommError函数声明如下:

BOOL ClearCommError(
HANDLE hFile,
LPDWORD lpErrors,
LPCOMSTAT lpStat
);

ClearCommError函数的第一个参数hFile是由CreateFile函数返回指向已打开串行口的句柄。
第二个参数指向定义了错误类型的32位变量。
第三个参数指向一个返回设备状态的控制块COMSTAT。
如果函数调用成功,则返回值为非0;若函数调用失败,则返回值为0


                                        COMSTAT结构
                                      -------------------------

COMSTAT结构包含串口的信息,结构定义如下:

typedef struct _COMSTAT { // cst

    DWORD fCtsHold : 1; // Tx waiting for CTS signal
    DWORD fDsrHold : 1; // Tx waiting for DSR signal
    DWORD fRlsdHold : 1; // Tx waiting for RLSD signal
    DWORD fXoffHold : 1; // Tx waiting, XOFF char rec''d
    DWORD fXoffSent : 1; // Tx waiting, XOFF char sent
    DWORD fEof : 1; // EOF character sent
    DWORD fTxim : 1; // character waiting for Tx
    DWORD fReserved : 25; // reserved
    DWORD cbInQue; // bytes in input buffer 输入缓冲区中的字节数 (这部分的缓冲区是在
                                          函数 setupcom 设定的缓冲区大小,属于软件buffer)
    DWORD cbOutQue; // bytes in output buffer 输出缓冲区中的字节数(这部分的缓冲区是在
                                           函数 setupcom 设定的缓冲区大小,属于软件buffer)
} COMSTAT, *LPCOMSTAT;



__cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。

_stdcall 是StandardCall的缩写,是C++的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。这些堆栈中的参数由被调用的函数在返回后清除,使用的指令是 retn X,X表示参数占用的字节数,CPU在ret之后自动弹出X个字节的堆栈空间。称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。

PASCAL 是Pascal语言的函数调用方式,也可以在C/C++中使用,参数压栈顺序与前两者相反。返回时的清栈方式与_stdcall相同。

_fastcall是编译器指定的快速调用方式。由于大多数的函数参数个数很少,使用堆栈传递比较费时。因此_fastcall通常规定将前两个(或若干个)参数由寄存器传递,其余参数还是通过堆栈传递。不同编译器编译的程序规定的寄存器不同。返回方式和_stdcall相当。

_thiscall 是为了解决类成员调用中this指针传递而规定的。_thiscall要求把this指针放在特定寄存器中,该寄存器由编译器决定。VC使用ecx,Borland的C++编译器使用eax。返回方式和_stdcall相当。

_fastcall 和 _thiscall涉及的寄存器由编译器决定,因此不能用作跨编译器的接口。所以Windows上的COM对象接口都定义为_stdcall调用方式。

C中不加说明默认函数为_cdecl方式(C中也只能用这种方式)

带有可变参数的函数必须且只能使用_cdecl方式,例如下面的函数:
int printf(char * fmtStr, ...);
int scanf(char * fmtStr, ...);
*/几种调用约定的区别

--------------------------------------------------------------------------------------
dllimport, dllexport
Microsoft Specific
-------------------------------------------------------------------------------------------
#ifdef DLL_EXPORT
        #define DI_API extern "C" __declspec(dllexport)
#else
         #define DI_API extern "C" __declspec(dllimport)
#endif
------------------------------------------------------------------------------------------
__declspec( dllimport ) declarator

__declspec( dllexport ) declarator

The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. They enable you to export and import functions, data, and objects to and from a DLL. These attributes explicitly define the DLL’s interface to its client, which can be the executable file or another DLL. Declaring functions as dllexport eliminates the need for a module-definition (.DEF) file, at least with respect to the specification of exported functions. Note that dllexport replaces the __export keyword.

The declaration of dllexport and dllimport uses extended attribute syntax.Example

// Example of the dllimport and dllexport class attributes
__declspec( dllimport ) int i;
__declspec( dllexport ) void func();

extern "C" _declspec(dllexport) LRESULT KeyBoardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    if(nCode==HC_ACTION)
{
}
return 0;
}

-------------------------------------------------------------------------------------
                 windows 常用的几个函数
-----------------------------------------------------------------------------------
用途: 指定一组监视通信设备的事件
原型:BOOL SetCommMask(HANDLE hFile, //标识通信端口的句柄
DWORD dwEvtMask //能够使能的通信事件
);
参数说明:-hFile:串口句柄
-dwEvtMask:准备监视的串口事件掩码
串口上可能发生的事件如下表所示:

        
事件描述
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 received 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.
参数含义
编辑
EV_BREAK:收到BREAK信号。
EV_CTS:CTS(clear to send)线路发生变化。
EV_DSR:DST(Data Set Ready)线路发生变化。
EV_ERR:线路状态错误,包括了CE_FRAME / CE_OVERRUN / CE_RXPARITY 3种错误。
EV_RING:检测到振铃信号。
EV_RLSD:CD(Carrier Detect)线路信号发生变化。
EV_RXCHAR:输入缓冲区中已收到数据,即接收到一个字节并放入输入缓冲区。
EV_RXFLAG:使用SetCommState()函数设置的DCB结构中的等待字符已被传入输入缓冲区中。
EV_TXEMPTY:输出缓冲区中的数据已被完全送出。
另外,可以通过SetCommMask(hFile,0)来清除该通讯设备的所有事件

猜你喜欢

转载自blog.csdn.net/u012516419/article/details/78652007