Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.02.2017, 08:41   #1
Mefil
Новичок
Джуниор
 
Регистрация: 14.12.2016
Сообщений: 2
По умолчанию Com port (rs232) асинхронные чтение. Использование таймаута во время ожидания события прихода данных из порта

Есть поток чтения, где мы ожидаем событие из порта по маске (EV_RXCHAR).

функция ожидание выглядит так:

DWORD signal = WaitForMultipleObjects(2, phevnt_rx, false, timeout_ms);

где

phevnt_rx - содержит предварительно созданное событие из TOverlapped и событие для остановки потока;

timeout_ms - время таймаута для подсчета времени отсутствия информации на прием.


Использование timeout_ms (равного у меня 10 мс) вместо INFINITE привело к тому, что

поток чтения не всегда считывает последний пришедший байт.

Событие порта о пришедшем последнем байте не происходит после таймаута.

Как сделать так чтобы после таймаута получить это байт?

//открытие порта:

Код:
bool TRS232::open(t_rs232_cfg &cfg) {
    TDCB dcb;
    TCommTimeouts TimeOuts;
    if(_bIsEnable)
        return _bIsEnable;

    _bIsEnable = false;
    AnsiString CommPort;
    CommPort.sprintf("\\\\.\\%s",cfg.sz_name);

    do {
        _hPort = CreateFile(CommPort.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
            OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
        if (_hPort == INVALID_HANDLE_VALUE)
            break;

            if (!SetCommMask(_hPort, EV_RXCHAR) && !SetupComm(_hPort, _nBuffSize,
                _nBuffSize) && !PurgeComm(_hPort,
                PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) {
                CloseHandle(_hPort);
            break;
        }


        GetCommState(_hPort, &dcb);
        dcb.DCBlength = sizeof(TDCB);
        dcb.fBinary = 1;
        dcb.BaudRate = (DWORD)(cfg.ebaud);
        dcb.ByteSize = (BYTE)(cfg.edbits);
        dcb.StopBits = (BYTE)(cfg.esbits);
        dcb.Parity = (BYTE)(cfg.eprt);

        if (!SetCommState(_hPort, &dcb))
        {
            CloseHandle(_hPort);
            long err=GetLastError();
            STRING err_string="init_err:";
            err_string+=IntToStr(err);
            break;
        }

        TimeOuts.ReadIntervalTimeout = MAXDWORD;
        TimeOuts.ReadTotalTimeoutConstant = 0;
        TimeOuts.ReadTotalTimeoutMultiplier = 0;
        TimeOuts.WriteTotalTimeoutMultiplier = 0;
        TimeOuts.WriteTotalTimeoutConstant = 0;
        if (!SetCommTimeouts(_hPort, &TimeOuts)) {
            CloseHandle(_hPort);
            break;
        }

        _bIsEnable = true;
    }
    while (0);

    return _bIsEnable;
}
//поток чтения
Код:
void t_stream_rs232::_thread()
{
    int ret;
    _rs232.set_mask(EV_RXCHAR);//устанавливаем маску для порта
    do
    {
        ret=_read(); //cм. ниже
    }while (ret!=N_EVNT_TERM);
}
//

Код:
void TRS232::set_mask(DWORD mask)
{
    _mask = mask;
    SetCommMask(_hPort, mask);
    _ovr_read.hEvent = CreateEvent(NULL, true, true, NULL);
}
//функция read

Код:
int __fastcall t_stream_rs232::_read(void)
{
try
{
    int nread, toread;
    toread = _rs232.wait_read_event(_hevnt_term_l, N_MS);//см. ниже
    switch(toread)
    {
        case RS232_EVENT_TIMEOUT:
            if (_on_timeout != NULL)
                _on_timeout(N_MS);
            return 0;

        case RS232_EVENT_TERMINATE:
            return N_EVNT_TERM;

        default:
            while(toread > 0)
            {
                nread =  _rs232.read( _buf, sizeof(_buf) );
                toread -= nread;
                if (_on_read != NULL)
                     _on_read(_buf, nread);  
            }
            return 0;
    }
}
catch(Exception *ex)
{
    MessageBox(NULL,ex->Message.c_str(),"t_stream_rs232::_read",MB_OK);
}
 
    return 0;
}
//Ожидание прихода байтов данных:
Код:
int  TRS232::wait_read_event(HANDLE event_terminate, DWORD timeout_ms)
{
    DWORD   mask, temp, signal;
    COMSTAT comstat;
    HANDLE phevnt_rx[2] = {_ovr_read.hEvent , event_terminate};

    _ovr_read.Internal = 0;
    _ovr_read.InternalHigh = 0;
    _ovr_read.Offset = 0;
    _ovr_read.OffsetHigh = 0;

    //ClearCommError(_hPort, &temp, &comstat);
    SetEvent(_ovr_read.hEvent);
    WaitCommEvent(_hPort, &mask, &_ovr_read);
    signal  = WaitForMultipleObjects(2, phevnt_rx, false, timeout_ms);
    int ret;
    switch(signal)
    {
        case WAIT_OBJECT_0:
        {
            if( !GetOverlappedResult(_hPort, &_ovr_read, &temp, false) )
            {
                ret = EIO;
                break;
            }
            ClearCommError(_hPort, &temp, &comstat);
            ret = comstat.cbInQue;
            break;
        }
        case WAIT_TIMEOUT:
            ret = RS232_EVENT_TIMEOUT;
            break;

        case WAIT_OBJECT_0+1:
            ret = RS232_EVENT_TERMINATE;
            break;
        default:
            ret = 0;
            break;
    }

    return ret;
}
//чтение из порта:
//-------------------------------------------------------------------------
Код:
int TRS232::read(BYTE* pbuf, DWORD nlen) {
    DWORD nread;

    if (!_bIsEnable)
        return -1;

    if (pbuf == NULL)
        return -1;

    if (nlen <= 0)
        return 0;

    if (!ReadFile(_hPort, pbuf, nlen, &nread, &_ovr_read))
        return -1;

    return nread;
}
Mefil вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение данных с COM-порта и вывод их в memo CHEburaschka Общие вопросы Delphi 12 21.05.2015 09:24
Com port (RS232) Pavlov_yu C++ Builder 14 18.06.2014 19:12
Дикий тупняк - чтение данных с com порта. GMX Компоненты Delphi 8 26.03.2014 15:39
Истекло время ожидания (Timeout). Время ожидания истекло до завершения операции или сервер не отвечает. kgs_forum C# (си шарп) 1 20.08.2013 20:14
Чтение данных с COM порта 232 Dimitr_88 Общие вопросы C/C++ 10 03.09.2010 10:39