Я проектирую класс, который обрабатывает последовательную связь.
Вот класс:
#include <stdio.h>
#include <Windows.h>
#include <process.h>
#include "port_class.h"
DCB blank_dcb = {0};
OVERLAPPED blank_ovl = {0};
com_port_cl::com_port_cl()
{
int jcs, jt;
int port_startup_error[4];
/*
* Open the port
*/
port_startup_error[0] = 0;
port_startup_error[1] = 0;
port_startup_error[2] = 0;
port_startup_error[3] = 0;
port_h = CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
0);
if(INVALID_HANDLE_VALUE == port_h)
{
port_startup_error[1] = (int) GetLastError();
}
port_wce_flag = CreateEvent(NULL,TRUE,FALSE,NULL);
port_shutdown_flag = CreateEvent(NULL,TRUE,FALSE,NULL);
port_tx_ready_flag = CreateEvent(NULL,TRUE,FALSE,NULL);
if(NULL == port_tx_ready_flag)
{
printf("CreateEvent() failed for port_tx_ready_flag\n");
}
port_rx_xpect_flag = CreateEvent(NULL,TRUE,FALSE,NULL);
if(NULL == port_rx_xpect_flag)
{
printf("CreateEvent() failed for port_rx_xpect_flag\n");
}
port_ha_t_r[1] = port_tx_ready_flag;
port_ha_t_r[2] = port_rx_xpect_flag;
port_ha_t_r[3] = NULL;
/*
* Configure the port
*/
dcb = blank_dcb;
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = TRUE;
/*
* Set up the DCB
*/
jcs = (int) SetCommState(port_h,&dcb);
if(0 == jcs)
{
port_startup_error[2] = (int) GetLastError();
}
/*
* Set up the comm mask.
*/
SetCommMask(port_h,0);
/*
* Set the port's timeouts (Times in millisec.)
*/
port_timeouts.ReadIntervalTimeout = MAXDWORD;
port_timeouts.ReadTotalTimeoutConstant = 0;
port_timeouts.ReadTotalTimeoutMultiplier = 0;
port_timeouts.WriteTotalTimeoutConstant = 0;
port_timeouts.WriteTotalTimeoutMultiplier = 0;
jt = SetCommTimeouts(port_h,&port_timeouts);
if(0 == jt)
{
port_startup_error[3] = (int) GetLastError();
}
if(0 == (port_startup_error[1]|port_startup_error[2]|port_startup_error[3]))
{
printf("Successfully set up port.\n");
}
else
{
printf("Error in port setup.\n");
}
/*
* Launch the worker thread.
*/
ui = (unsigned int) _beginthreadex(NULL,128,thread_t_r, (void *) this,
0,&work_thread_id);
if(0 == ui)
{
printf("Error starting up auxiliary thread: %d\n",errno);
}
else
{
printf("Launched auxiliary thread\n");
}
}
com_port_cl::~com_port_cl()
{
CloseHandle(port_wce_flag);
CloseHandle(port_rx_xpect_flag);
CloseHandle(port_tx_ready_flag);
CloseHandle(port_shutdown_flag);
CloseHandle(port_h);
}
unsigned int __stdcall thread_t_r(void *arglist)
{
int jwce, jwfso, jwfmo, n;
int shut_down;
DWORD comm_event_word;
OVERLAPPED ovlx;
com_port_cl *port;
port = (com_port_cl *) arglist;
ovlx = blank_ovl;
ovlx.hEvent = port->port_wce_flag;
shut_down = 0;
comm_event_word = 0;
while(0 == shut_down)
{
/*
* Check for shutdown.
*/
jwfso = WaitForSingleObject(port->port_shutdown_flag,500);
if(WAIT_OBJECT_0 == jwfso)
{
shut_down = 1;
printf("Auxiliary thread shutting down.\n");
}
else
{
/*
* Wait for an event.
*/
port->port_ha_t_r[0] = ovlx.hEvent;
jwce = WaitCommEvent(port->port_h,&comm_event_word,&ovlx);
if(0 == jwce)
{
n = (int) GetLastError();
if(997 != n)
{
printf("WaitCommEvent() error: %d\n",n);
}
}
jwfmo = WaitForMultipleObjects(3,port->port_ha_t_r,FALSE,5000);
/*
* Process the event.
*/
if((WAIT_OBJECT_0 + 1) == jwfmo)
{
printf("Thread detected port->port_tx_ready_flag\n");
ResetEvent(port->port_tx_ready_flag);
}
else if((WAIT_OBJECT_0 + 2) == jwfmo)
{
printf("Thread detected port->port_rx_xpect_flag\n");
ResetEvent(port->port_rx_xpect_flag);
}
else if(WAIT_OBJECT_0 == jwfmo)
{
printf("Thread detected event on serial port: ");
if(0 != (comm_event_word&EV_RXCHAR))
{
printf("EV_RXCHAR\n");
}
if(0 != (comm_event_word&EV_TXEMPTY))
{
printf("EV_TXEMPTY\n");
}
if(0 == comm_event_word)
{
printf("\n");
}
ResetEvent(port->port_wce_flag);
}
else if(WAIT_TIMEOUT == jwfmo)
{
printf("WaitForMultipleObjects() timed out\n");
}
else
{
printf("Wait abandoned or other situation\n");
}
}
}
_endthreadex(1);
return 1;
}
Вот port_class.h:
unsigned int __stdcall thread_t_r(void *);
class com_port_cl
{
public:
com_port_cl();
~com_port_cl();
HANDLE port_h;
HANDLE port_wce_flag;
HANDLE port_shutdown_flag;
HANDLE port_tx_ready_flag;
HANDLE port_rx_xpect_flag;
HANDLE port_ha_t_r[4];
protected:
COMMTIMEOUTS port_timeouts;
DCB dcb;
unsigned int ui, work_thread_id;
};
А здесь является основной программой:
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <process.h>
#include "port_class.h"
int main()
{
com_port_cl port;
if(0 == SetEvent(port.port_rx_xpect_flag))
{
printf("SetEvent() error: %d\n",GetLastError());
}
Sleep(2500);
if(0 == SetEvent(port.port_tx_ready_flag))
{
printf("SetEvent() error: %d\n",GetLastError());
}
Sleep(2500);
if(0 == SetEvent(port.port_shutdown_flag))
{
printf("SetEvent() error: %d\n",GetLastError());
}
Sleep(2500);
printf("\npress any key to exit.\n");
_getche();
}
Когда я использую встроенный последовательный порт, я получаю следующий вывод:
Successfully set up port.
Launched auxiliary thread
WaitCommEvent() error: 87
Thread detected port->port_rx_xpect_flag
WaitCommEvent() error: 87
Thread detected port->port_tx_ready_flag
WaitCommEvent() error: 87
press any key to exit.
WaitForMultipleObjects() timed out
Auxiliary thread shutting down.
Когда я переключаюсь на Prolifi c USB- к последовательному порту я получаю следующий вывод:
Successfully set up port.
Launched auxiliary thread
Thread detected event on serial port:
Thread detected event on serial port:
Thread detected event on serial port:
Thread detected event on serial port:
Thread detected event on serial port:
Thread detected event on serial port:
Thread detected event on serial port:
Thread detected event on serial port:
Thread detected event on serial port:
Auxiliary thread shutting down.
press any key to exit.
Вопросы: почему WaitCommEvent () показывает ошибку 87, «недопустимый параметр», когда я использую встроенный последовательный порт? Я не могу найти ничего плохого в любом из аргументов в вызове WaitCommEvent ().
Почему порт USB-последовательный порт Prolifi c видит событие на порту, когда данные не отправляются на или из порта? Почему порт USB-последовательный порт не видит события port_tx_ready_flag
и port_rx_xpect_flag
?
У меня установлены последние версии драйверов для обоих портов.