как организовать лучше работу с COM портом по средствам ACE
От: Аноним  
Дата: 20.08.08 07:11
Оценка:
День добрый!
Столкнулся с небольшой проблемой:
Использую ACE для работы с комп портом и тп.


.....
class CSerialHandler : public ACE_Event_Handler
{
public:
    int handle_input(ACE_HANDLE fd)
    {
    g_soResponse.clear();
    for (char ch = 0; oTTY.recv(&ch, 1) == 1; g_soResponse += ch ) {;}
    ACE_HEX_DUMP ( ( LM_DEBUG, g_soResponse.c_str(), g_soResponse.length(), ACE_TEXT("Response: ")) );
        return 0;
    }
};
.........
ACE_TTY_IO oTTY;
ACE_DEV_Connector oConnector;
oConnector.connect(oTTY, ACE_DEV_Addr(ACE_TEXT("/dev/ttyS1")));

ACE_TTY_IO::Serial_Params oParams;
oParams.baudrate = 9600;
oParams.readtimeoutmsec = 1000;
oParams.paritymode = "NONE";
oParams.databits = 8;
oParams.stopbits = 1;
oTTY.control(ACE_TTY_IO::SETPARAMS, &oParams);
.......


Проблема следующего плана: когда "приходит" handle_input я пытаюсь за раз все вычитать — вроде все ок. но когда я все вычитал(я об этом же не знаю) на следующей итерации пытаюсь вычитать и попадаю на тайматут чтения и потом уже только понимаю что все вычитано.

Вопрос: как можно организовать работу что бы не попадать на таймаут чтения
Re: как организовать лучше работу с COM портом по средствам
От: imironchik  
Дата: 20.08.08 10:29
Оценка:
А>Вопрос: как можно организовать работу что бы не попадать на таймаут чтения

Я использую примерно такую схему:


std::string response;

ACE_Time_Value delta( 0, 100 );
ACE_Time_Value sleeptm( 5 );

for( ACE_Countdown_Time time_left( &sleeptm );
  sleeptm > ACE_Time_Value::zero; time_left.update() )
{
  read( response, 1 );
    if( is_full_message( response ) )
      break;
}


Реализация метода read( std::string &, size_t ) думаю не нужно писать.

Ну а что касается is_full_message( const std::string & ),
то здесь уже нужно смотреть с каким устройством общаешься, но найти что-нибудь можно всегда...

Попутный вопрос: насколько я понял из кода, то все это дело работает под *nix-ами, а под Windows
кому-нибудь удавалось заставить реактор перехватывать уведомления о поступивших данных в COM порте
( ACE_TTY_IO => ACE_Reactor => ACE_Event_Handler::handle_input( ACE_HANDLE ) )?
Если да, то поделитесь опытом. У меня ничего не вышло ни на ACE_Select_Reactor, ни на ACE_WFMO_Reactor.
Что и не удивительно-то
Re[2]: как организовать лучше работу с COM портом по средств
От: Аноним  
Дата: 20.08.08 11:15
Оценка:
I>Попутный вопрос: насколько я понял из кода, то все это дело работает под *nix-ами, а под Windows
I>кому-нибудь удавалось заставить реактор перехватывать уведомления о поступивших данных в COM порте
I>( ACE_TTY_IO => ACE_Reactor => ACE_Event_Handler::handle_input( ACE_HANDLE ) )?
I>Если да, то поделитесь опытом. У меня ничего не вышло ни на ACE_Select_Reactor, ни на ACE_WFMO_Reactor.
I>Что и не удивительно-то

ACE_Select_Reactor использует функцию select для демультиплексирования событий. под виндами эта функция не работает с
компортом, только с сокетами.
что касается ACE_WFMO_Reactor. помоему тоже не помошник, тк на сколько я знаю, что бы ждать события на компорту нужно вызывать WaitCommEvent что ли(точно не помню, мсдн под рукой нет) а в исходниках я не нашел такой функции, те ее вызов.
на http://groups.google.ru/group/comp.soft-sys.ace вроде говорили тчо может помочь прорактор, но я не смог разобраться что и как. чую что тоже облом.

вообще мысль написать свою имплеминтацию реактора которая бы задействовала WaitCommEvent, но пока увы не хватает времени.
Re[3]: как организовать лучше работу с COM портом по средств
От: imironchik  
Дата: 20.08.08 19:33
Оценка:
А>вообще мысль написать свою имплеминтацию реактора которая бы задействовала WaitCommEvent, но пока увы не хватает времени.

Есть решение с использованием WFMO реактора.

По следам: http://groups.google.ru/group/comp.soft-sys.ace/browse_thread/thread/993f73d86c415387/22b1fbb0811cdc17?lnk=gst&q=WaitCommEvent#22b1fbb0811cdc17

Цитирую: "I had to open the serial port in overlapped mode, then create an event, then
do a WaitCommEvent with the newly created manual-reset event. Register a
handler with the wfmo reactor using the created event, and handle_signal
will be called. I got that far, but I think within the handler, the event
has to be reset, and I'm not sure if another WaitCommEvent is necessary"

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