И снова ReadFile + COM порт
От: lomezych  
Дата: 17.06.04 08:29
Оценка:
Значит так

Есть такой код

bool MyFrame::Read(char* buffer, int& nr)
{
    DWORD dwBytesRead = 0,
          dwCommStatus;
    
    BYTE  bChar;
    
    OVERLAPPED osWait = {0};      
    osWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if ( osWait.hEvent == NULL )
    {
        wxMessageBox("Cannot create event. Read thread aborted");
        return true;
    }

    BOOL fWaitingForEventTimeout = FALSE;
    
    nr = 0;
    
    PurgeComm(m_hPort,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    SetCommMask (m_hPort, EV_RXCHAR);

    do 
    {
        if ( !fWaitingForEventTimeout )
        {       
            if ( !WaitCommEvent(m_hPort, &dwCommStatus, &osWait) )
            {           
                if ( GetLastError() != ERROR_IO_PENDING ) 
                {
                    wxMessageBox("Error in WaitCommEvent");
                    return true;
                }    
            }
            else wxMessageBox("Waiting for event..");
        }
        else *main << "Already waiting for event..\n";
        
        switch (WaitForSingleObject(osWait.hEvent, 10000))
        {
            case WAIT_OBJECT_0:
                {
                    *main << "Event happened.\n";
                    fWaitingForEventTimeout = FALSE;
                    ResetEvent(osWait.hEvent);
                    do 
                    {
                        if ( !ReadFile(m_hPort, &bChar, 1, &dwBytesRead, &m_OverlappedRead) )
                        {
                            if ( GetLastError() != ERROR_IO_PENDING ) 
                            {
                                wxMessageBox("Error in ReadFile");
                                return true;
                            }
                            else 
                            {
                                switch (WaitForSingleObject(m_OverlappedRead.hEvent, 300))
                                {
                                    case WAIT_OBJECT_0:
                                        {
                                            // add error checking for this func
                                            GetOverlappedResult(m_hPort, &m_OverlappedRead, &dwBytesRead, FALSE);
                                            ResetEvent(m_OverlappedRead.hEvent);
                                            if ( dwBytesRead == 1 )
                                            {
                                                buffer[nr] = bChar;
                                                nr++;
                                                *main << "Byte recieved: " << bChar << "\n";
                                                break;
                                            }
                                            *main << "Object signaled but no byte recieved, hmm\n";
                                            break;
                                        }
                                    case WAIT_TIMEOUT:
                                        {
                                            CloseHandle(osWait.hEvent);
                                            *main << "Timeout. Nothing else to read.\n";
                                            return false;
                                        }
                                    /*     
                                    default:
                                        {
                                            *main << "Mingi jama... Mollame edasi\n";
                                            ResetEvent(m_OverlappedRead.hEvent);
                                            break;
                                            // return true;
                                        }
                                    */
                                }
                            }           
                        }
                        else
                        {
                            if ( dwBytesRead == 1 )
                            {
                                *main << "ReadFile returned immidiately:";
                                buffer[nr] = bChar;
                                nr++;
                                *main << " recieved: " << nr << " byte " << bChar << "\n"; 
                            }
                            else 
                            {
                                // сюда ходить не надо
            *main << "ReadFile returned immidiately and nothing else to read.\n";
                                break;
                            }    
                        }
                    } while (dwBytesRead);
                    
                    break;
                }
            
            case WAIT_TIMEOUT:
                {
                    *main << "event never occured.. exiting\n";
                    fWaitingForEventTimeout = TRUE;
                    break;
                }
            default:
                {
                    *main << "shit happened while waiting for event\n";
                    break;
                }
        }
    } while (fWaitingForEventTimeout);

return false;



проблема в том, что бывает так, что ReadFile возвращается сразу, что говорит о том что операция успешно выполнена, те байтик почитали сразу как бы ( или хочется думать, что это должно быть так ) и тогда не надо идти в WaitForSingleObject. Но на самом деле dwBytesRead == 0. Как такое побороть??
... << Rsdn@Home 1.1.4 beta 1 >>
Re: И снова ReadFile + COM порт
От: lomezych  
Дата: 17.06.04 08:45
Оценка:
Сам спросил — сам ответил...

Можно наверно сделать и так:

Зовем ReadFile, если success и dwBytesRead == 1 то порядок, если же dwBytesRead == 0, то делаем снова ReadFile.. в какой-нть do {...} запихать.. Вопрос в том, корректно ли так делать? Те считается ли уже что операция завершена и поэтому we can issue another read operation.. Вот...
... << Rsdn@Home 1.1.4 beta 1 >>
Re: И снова ReadFile + COM порт
От: Аноним  
Дата: 17.06.04 16:42
Оценка:
Ну вот... добрался до дома... хоть тут есть русская раскладка

Значит чего мне хочется от функции чтения,так это того, что должна она вываливаться successfully только в 2 случаях по timeout'у ... либо в ожидании прихода символа, либо в ожидании чтения символа.
Но у меня вызов ReadFile проходит успешено, хотя dwBytesRead == 0 что за чушь...

Я тут поискал инфы... может следует занулять OVERLAPPED структуры перед использованием.. не знаю короче.. этот код уже раз 10 менял и переписывал... один фиг

так что вопрос открыт..
Re[2]: И снова ReadFile + COM порт
От: Protey Россия  
Дата: 18.06.04 06:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну вот... добрался до дома... хоть тут есть русская раскладка


А>Значит чего мне хочется от функции чтения,так это того, что должна она вываливаться successfully только в 2 случаях по timeout'у ... либо в ожидании прихода символа, либо в ожидании чтения символа.

А>Но у меня вызов ReadFile проходит успешено, хотя dwBytesRead == 0 что за чушь...

Это не чушь, в доках так и сказано, дескать если dwBytesRead == 0, то произошла какое-то событие в драйвере и надо читать GetCommState
SetCommMask (m_hPort, EV_RXCHAR); — не панацея от изменений DTR, DSR, CTS, RTS, сбиения синхро. Ибо ну выставил ты выход только по приёму байта, а передатчик взял и отключился(или переключил скорость передачи или ошибочно переданный байт) и программа будет доолго ждать ....

А>Я тут поискал инфы... может следует занулять OVERLAPPED структуры перед использованием.. не знаю короче.. этот код уже раз 10 менял и переписывал... один фиг


Занулять тоже надо, но это из другой оперы

А>так что вопрос открыт..
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.