Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Повтороное открытие COM-порта 
:(
    Опции темы
xvr
Дата 29.3.2010, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(programmaker @  29.3.2010,  17:10 Найти цитируемый пост)

А если я избавлюсь от wait..., то как мне отследить приход по readfile? 
В данной программе - никак  smile 
Запусти ВСЕ общение с портом в отдельном потоке (не в разных, а в одном и том же). Пусть там сначала ждет ответа от модема в блокирующем ReadFile, а потом переключается на OVERLAPPED чтения


PM MAIL   Вверх
programmaker
Дата 1.4.2010, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 30.10.2008

Репутация: нет
Всего: нет



Еще раз переделал все и решил остаться на одном открытии порта с оверлаппедом.
Появилась проблема.
Код, который был:
Код

void CCommDevice::S1Event_Func(WRITE_DEVICE_EVENT)
{
    int timestamp=GetTimestamp();


// запись байта (или нескольких байтов) из буфера в порт
//    int pause;
    if(!m_hChan)
    {
        return;
    }
    if(m_ByteToWrite)
    {
        for(int i=0; i<m_ByteToWrite;i++)
        {
            m_WriteBuf[i]=m_hChan->m_WriteBuf[i];
//            afxDump<<m_WriteBuf[i]<<"out"<<"\n";
        }
        if (m_ByteToWrite > 0)
        {
// Установка линии DTR в 1 для разрешения передачи в RS-485
            if(m_Flg485)
            {
//#ifdef  SYSTEL_RS485
                m_dcb.fDtrControl = DTR_CONTROL_ENABLE ;
                m_dcb.fRtsControl = RTS_CONTROL_ENABLE ;
                SetCommState (m_hCom, &m_dcb);                // Инициируем Comm с новым DCB
//                Sleep(1);
//#endif
            }
#ifdef _DEBUG
            afxDump<<"WriteFile:  "<<m_ByteToWrite<<"  "<<timestamp<<"\n";
#endif
            if( ::WriteFile( m_hCom, m_WriteBuf, m_ByteToWrite, &m_dwNumberWrite, &m_osWrite ) == NULL )
            {
                DWORD dw=GetLastError();
                return;        
            } // !!! Временно    
        }
    }
}




После моего вмешательства стало:
Код

void CCommModemDevice::S1Event_Func(WRITE_DEVICE_EVENT)
{
    int timestamp=GetTimestamp();
    
//    char sReceivedChar[128];
    DWORD err = NULL;
    DWORD dwnumber_to_read_bytes = 200;
    DWORD dwnumber_read_bytes = 1;
    int itotal_read_bytes = 0;
    DWORD iSize;
    char EOL = toascii(13);
    char* TXbuff = new TCHAR;

// запись байта (или нескольких байтов) из буфера в порт
//    int pause;
    if(!m_hChan)
    {
        return;
    }

    if (portstat->modCon==false && portstat->modTerm==false)
    {
        sprintf(TXbuff, "%s", "atd 89151711565");
        m_ByteToWrite=strlen(TXbuff);
        for(int i=0; i<m_ByteToWrite;i++)
        {
            m_WriteBuf[i]=TXbuff[i];
        }
// Установка линии DTR в 1 для разрешения передачи в RS-485
        if(m_Flg485)
        {
//#ifdef  SYSTEL_RS485
            m_dcb.fDtrControl = DTR_CONTROL_ENABLE ;
            m_dcb.fRtsControl = RTS_CONTROL_ENABLE ;
            SetCommState (m_hCom, &m_dcb);                // Инициируем Comm с новым DCB
//            Sleep(1);
//#endif
        }
#ifdef _DEBUG
        afxDump<<"WriteFile:  "<<m_ByteToWrite<<"  "<<timestamp<<"\n";
#endif
        if( ::WriteFile( m_hCom, m_WriteBuf, m_ByteToWrite, &m_dwNumberWrite, &m_osWrite ) == NULL )
                {
                    DWORD dw=GetLastError();
                    return;        
                } // !!! Временно    
    }
}


При выполнении моего кода возникает ошибка 997 (Протекает наложенное событие ввода/вывода.) и запись не происходит.
Как это побороть???
PM MAIL   Вверх
xvr
Дата 1.4.2010, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(programmaker @  1.4.2010,  15:33 Найти цитируемый пост)
При выполнении моего кода возникает ошибка 997 (Протекает наложенное событие ввода/вывода.) и запись не происходит.
Предыдущий запрос WriteFile еще не отработал
Цитата

Как это побороть??? 
Разруливай события записи - в данном случае нужно ждать пока WriteFile отработает (выставит событие в m_osWrite) прежде чем вызывать его снова.
Кстати, перед вызовом WriteFile рекомендуется событие сбросить вручную, WriteFile этого не делает

PM MAIL   Вверх
programmaker
Дата 8.4.2010, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 30.10.2008

Репутация: нет
Всего: нет



Несмотря на ошибку 997 - запись и чтение проходит нормально...
Странно конечно, но проходит...

есть вопрос по таймеру (чтоб уж не создавать новую тему - в существующих не нашел :( )

Код

void CALLBACK OnTimer1(HWND, UINT, UINT, DWORD)
{
    CCommModemDevice::PORTSTATUS* portst = new CCommModemDevice::PORTSTATUS;
    portst->modTerm=true;
    delete portst;
}

void CCommModemDevice::OnTimer()
{
    timer = SetTimer( NULL, (UINT_PTR)this, 6000, (TIMERPROC)OnTimer1);
    if (!timer)
        DWORD e = GetLastError();
//    TerminateThread(ComThread, NULL);
}


в OnTimer1 - не заходит
PM MAIL   Вверх
GremlinProg
Дата 8.4.2010, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



если SetTimer вызывается в потоке, то в нем должен быть реализован в каком-нить виде цикл обработки сообщений, ну и соответственно сама очередь, чтобы OnTimer1 мог быть вызван

SetTimer просто привязан к очереди сообщений,
как вариант - использовать Waitable Timer, или просто другой поток


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
programmaker
Дата 8.4.2010, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 30.10.2008

Репутация: нет
Всего: нет



Цитата(GremlinProg @ 8.4.2010,  11:52)
если SetTimer вызывается в потоке, то в нем должен быть реализован в каком-нить виде цикл обработки сообщений, ну и соответственно сама очередь, чтобы OnTimer1 мог быть вызван

SetTimer просто привязан к очереди сообщений,
как вариант - использовать Waitable Timer, или просто другой поток

SetTimer вызывается в основной программе (основной поток),  CALLBACK  - просто глобальная ф-ция
PM MAIL   Вверх
programmaker
Дата 10.4.2010, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 30.10.2008

Репутация: нет
Всего: нет



заменил SetTimer на timeSetEvent
теперь когда я пытаюсь поменять переменную в CallBack функции выдает ошибку
error C2597: illegal reference to non-static member 'CCommModemDevice::modTerm'

вот код
Код

void CALLBACK CCommModemDevice::OnTimer1(UINT uTimerID, UINT uMsg,
                       DWORD_PTR dwUser, DWORD_PTR dw1,
                       DWORD_PTR dw2)
{
    modTerm =true;
}
#include <Mmsystem.h>

void CCommModemDevice::OnTimer()
{
    timeSetEvent(6000, 1, &OnTimer1, modTerm,0);
    if (!timer)
        DWORD e = GetLastError();

}

как ее побороть?
PM MAIL   Вверх
xvr
Дата 10.4.2010, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(programmaker @  10.4.2010,  14:34 Найти цитируемый пост)
теперь когда я пытаюсь поменять переменную в CallBack функции выдает ошибку
error C2597: illegal reference to non-static member 'CCommModemDevice::modTerm'
RTFM по поводу отличий указателя на функцию от указателя на метод класса. Hint - это не одно и то же  smile 

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0650 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.