COM порт WriteFile пишет лишние байты
Собственно сам вопрос почему это происходит и как с этим бороться?
if(s0.Open("COM1")) cout << "error when open port" << endl;
...
typedef vector<uint8_t> vec;
vec data;
data.push_back(0xFF);
data.push_back(0x60);
data.push_back(0xFF);
data.push_back(0x60);
int err;
if((err=s0.Write(data))) cout << "write error " << err << endl;
почему-то этот код записывает в com порт следующие данные (перехватывал снифером):
FF 60 FF 60 08 FF
т.е. аж целых шесть байт, заместо четырех, что видно из отладочного вывода метода Write.
А вот если в записываемых данных не содержится 0xFF все работает нормально :confused:
вот код реализации метода Open
{
if(_openned) Close();
_h = ::CreateFile(("\\\\.\\" + dev).c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(_h==INVALID_HANDLE_VALUE)
{
_lastError = ::GetLastError();
switch(_lastError)
{
case ERROR_FILE_NOT_FOUND:
return EERROR_DEVICENOTFOUND;
break;
case ERROR_ACCESS_DENIED:
return EERROR_DEVICEINUSE;
break;
default:
return EERROR_UNKNOWN;
break;
}
}
_openned = true;
if(!::SetCommMask(_h, EV_RXCHAR))
{
_lastError = ::GetLastError();
return EERROR_INITIALIZE;
}
_inQueue = inQueue;
_outQueue = outQueue;
if(!::SetupComm(_h, inQueue, outQueue))
{
_lastError = ::GetLastError();
return EERROR_INITIALIZE;
}
::COMMCONFIG m_cfg;
DWORD m_cfgsize = sizeof(::COMMCONFIG);
if(!::GetDefaultCommConfig(dev.c_str(), & m_cfg, & m_cfgsize))
{
_lastError = ::GetLastError();
return EERROR_INITIALIZE;
}
_dcb = m_cfg.dcb;
_dcb.fOutxCtsFlow = false; // Disable CTS monitoring
_dcb.fOutxDsrFlow = false; // Disable DSR monitoring
_dcb.fDtrControl = DTR_CONTROL_DISABLE; // Disable DTR monitoring
_dcb.fOutX = false; // Disable XON/XOFF for transmission
_dcb.fInX = false; // Disable XON/XOFF for receiving
_dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send)
m_cfg.dcb = _dcb;
if(!::SetCommState(_h, & _dcb))
{
_lastError = ::GetLastError();
return EERROR_INITIALIZE;
}
::COMMTIMEOUTS m_t;
_CalcTimeouts(m_t);
if(!::SetCommTimeouts(_h, & m_t))
{
_lastError = ::GetLastError();
return EERROR_INITIALIZE;
}
SetTimeout(TTY_TIMEOUT);
_ntries = TTY_NTRIES;
return EERROR_SUCCESS;
}
и код реализации метода Write
{
if(!_openned) return EERROR_NOTINITIALIZED;
const uint8_t * m_buf = &data[0];
DWORD m_len = data.size();
DWORD m_feedback = 0;
if(!::WriteFile(_h, m_buf, m_len, & m_feedback, NULL))
{
_lastError = ::GetLastError();
return EERROR_UNKNOWN;
}
cout << "feedback = " << m_feedback << endl;
if(m_feedback!=m_len) return EERROR_WRITEFAILURE;
return EERROR_SUCCESS;
}
Только что проверил со стандартным COM портом программа работает нормально :confused:, без таких глюков с WriteFile. Куда рыть, где копать, вообще ХЗ, весь google.ru перерыл (((
Перерыл всю структру DCB, пробовал всякое - ничего не помогло. Пробовал сторонние реализации классов враперов типа CSerial - работают точно так же. И вот что самое интересное, программа Comm Operator нормально отправляет данных с этим байтом 0xFF.
Разработчику я уже написал, вот только ответа от него все нет и нет... А вот насчет WriteFile тут вот что интересно - он сам признается что записал лишние байты... Должны же быть какие-нибудь функции контролирующие поведение WriteFile???? У меня вообще подозрение что WriteFile работает с данными, в данном случае, в текстовом формате, а не в бинарном, как положено. И еще смучает то, что программа Comm Operator шлет данные в порт без вышеописанных глюков...
... пробовал, да и веткор здесь не при чем... во враппере CSerial вот отсюда-вот http://www.codeproject.com/KB/system/serial.aspx вообще STL не используется, но тем не менее он работает так же, и записывает эти чертовы лишние байты :(
В принципе зачем реализацию драйвера, когда по протоколу RFC2217 можно будет с конвертером общаться напрямую без создания com порта, а по tcp/ip ?!
ну так я ж хз. Чего ж ты с ним тогда мучаешься?