Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

COM порт WriteFile пишет лишние байты

64K
14 декабря 2010 года
HeX0
13 / / 14.12.2010
Всем здравствуйте! Буду краток, проблема в следующем: функция WriteFile для COM порта пишет больше байт чем указано в ее параметре, если первый записываемый байт 0xFF
Собственно сам вопрос почему это происходит и как с этим бороться?
Код:
tty s0;
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
Код:
int tty::Open(const string & dev, uint32_t inQueue, uint32_t outQueue)
{
    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
Код:
int tty::Write(const vector<uint8_t> & data)
{
    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;
}
64K
14 декабря 2010 года
HeX0
13 / / 14.12.2010
В догонку, программа общается с виртульным COM портом созданным через ArlanComManager устройство Арлан-9000-1RS485 (медиа конвертор ethernet <-> RS485).
Только что проверил со стандартным COM портом программа работает нормально :confused:, без таких глюков с WriteFile. Куда рыть, где копать, вообще ХЗ, весь google.ru перерыл (((
64K
16 декабря 2010 года
HeX0
13 / / 14.12.2010
... И гробовое молчание... Ну если все же кто-нибудь решится ответить, то вот информация к размышлению:
Перерыл всю структру DCB, пробовал всякое - ничего не помогло. Пробовал сторонние реализации классов враперов типа CSerial - работают точно так же. И вот что самое интересное, программа Comm Operator нормально отправляет данных с этим байтом 0xFF.
1
16 декабря 2010 года
kot_
7.3K / / 20.01.2000
а с чего ты вообще взял, что проблема тут во WriteFile? Тем более что сам же и пишешь - что на стандартном ком-порту все работает как положено. Напиши разработчику драйвера - и уточни чем вызван косяк в реализации.
64K
16 декабря 2010 года
HeX0
13 / / 14.12.2010
Цитата: kot_
а с чего ты вообще взял, что проблема тут во WriteFile? Тем более что сам же и пишешь - что на стандартном ком-порту все работает как положено. Напиши разработчику драйвера - и уточни чем вызван косяк в реализации.



Разработчику я уже написал, вот только ответа от него все нет и нет... А вот насчет WriteFile тут вот что интересно - он сам признается что записал лишние байты... Должны же быть какие-нибудь функции контролирующие поведение WriteFile???? У меня вообще подозрение что WriteFile работает с данными, в данном случае, в текстовом формате, а не в бинарном, как положено. И еще смучает то, что программа Comm Operator шлет данные в порт без вышеописанных глюков...

1
16 декабря 2010 года
kot_
7.3K / / 20.01.2000
а если в место вектора использовать просто массив?
64K
16 декабря 2010 года
HeX0
13 / / 14.12.2010
Цитата: kot_
а если в место вектора использовать просто массив?



... пробовал, да и веткор здесь не при чем... во враппере CSerial вот отсюда-вот http://www.codeproject.com/KB/system/serial.aspx вообще STL не используется, но тем не менее он работает так же, и записывает эти чертовы лишние байты :(

1
16 декабря 2010 года
kot_
7.3K / / 20.01.2000
значит проблема в драйвере порта
64K
17 декабря 2010 года
HeX0
13 / / 14.12.2010
Я вот думаю что если пойти вообще в обход этого драйвера?! Никто не поделиться реализацией, или хотя бы подбробным описанием RFC2217???
1
17 декабря 2010 года
kot_
7.3K / / 20.01.2000
тогда тебе прийдется написать свою реализацию драйвера.
64K
17 декабря 2010 года
HeX0
13 / / 14.12.2010
Цитата: kot_
тогда тебе прийдется написать свою реализацию драйвера.



В принципе зачем реализацию драйвера, когда по протоколу RFC2217 можно будет с конвертером общаться напрямую без создания com порта, а по tcp/ip ?!

252
17 декабря 2010 года
koderAlex
1.4K / / 07.09.2005
поснифай пакетики от Comm Operator - разберёшся с протоколом .
1
17 декабря 2010 года
kot_
7.3K / / 20.01.2000
Цитата: HeX0
В принципе зачем реализацию драйвера, когда по протоколу RFC2217 можно будет с конвертером общаться напрямую без создания com порта, а по tcp/ip ?!


ну так я ж хз. Чего ж ты с ним тогда мучаешься?

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог