Использование событий в компоненте последовательного порта TComPort (v4) из потока в Delphi? - PullRequest
2 голосов
/ 19 декабря 2011

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

Это было в BDS2006, с более старой версией (примерно 3.x?) Это было сделано с помощью кода, подобного этому, в tthread.execute:

    while ...
          begin
          events:=[evRxChar];
          { Prepare a stop event for killing a waiting communication wait. }
           try
             comport1.WaitForEvent(events,stopevent.handle,500);
             if evRxChar in events then
               ComPort1RxChar(comport1,comport1.InputCount); // method of thread.
           on e: exception do {only logs} ;
           end;

Инициализация была как

procedure TSerThread.initcomport(comportname:string='COM1');
begin
 comport1:=tcomport.create(nil);
 ComPort1.BaudRate:=br115200;
 ComPort1.DataBits:=dbEight;
 ComPort1.Port:=comportname;

 ComPort1.StopBits:=sbOneStopBit;
 ComPort1.Events:=[];
 ComPort1.Connected:=true;

 StopEvent := TEvent.Create(nil,{ManualReset}false,{InitialState}false,'StopEvent');
end;

Метод rxchar читает используя comport1.readstr ()

Недавно мне пришлось это откопать, и я заметил, что это не сработало в моем Delphi XE с tcomport4. Глядя в источник, я увидел замечания, которые comport4 изменил способ работы со своими внутренними потоками (свойство "overlapped"), но по умолчанию кажется, что "true" имеет комментарий "classic", и я

Предполагается, что это означает совместимость со старыми версиями.

Обратите внимание, что протоколы являются двоичными, и все строковые, char <-> ansistring, ansichar изменения были сделаны, как я делал в обычной версии mainthread

Теперь реальные вопросы:

  1. У кого-нибудь есть tcomport4, работающий в потоке?
  2. Есть ли очевидные ошибки в вышеприведенном?
  3. или мне нужно перейти на другой компонент?

Я все еще отлаживаю то, что происходит, но спешу, пока я публикую это в надежде быстро получить указатели.

Обновление

Я переустановил старую копию Turbo Delphi и убедился, что она работает там с v3. Я исправил небольшую ошибку в пути кода, которая немного отличалась от той, что я думал (не в приведенном выше коде)

Это позволяет мне лучше описать поведение между dxe / comportv4 и bds2006 / comportv3; код v4 генерирует гораздо больше событий чтения (сотни / секунду). Похоже, что чтение не удаляет символы чтения из входящей очереди или около того.

Обновление 2

Я провел быстрое тестирование с новейшей версией и произвел необходимую перестановку (функция уничтожения строк используется для двоичного протокола). Я застрял на некоторое время, потому что приложение зависало при запуске, но это потому, что я использую gnugettext, а Comport упаковывает другую (не unicode даже?) Версию. Но после этого работает .

К сожалению, изменения немного рискованны для распространения обратно в рабочую версию (полностью написанное декодирование протокола), поэтому мне придется протестировать промежуточные версии (между 4.0 и 4.11f). Я сделаю это в свое время, какие-нибудь предложения, какая версия была последней readstr (ansistring)?

Обновление 3

В конце я просто переименовал блоки 4.11f и использую их параллельно старой версии, используя 4.11f для многопоточных кодовых баз и старую для поддержки существующего кода.

В долгосрочной перспективе я мог бы просто взять код ожидания и сделать собственную версию. Основная проблема заключается в том, что на самом деле невозможно увидеть, закончилось ли ожидание по тайм-ауту, остановке или тому подобному. Это означает, что вам нужен еще один таймер, если вы хотите, например, отправлять с регулярными интервалами.

1 Ответ

1 голос
/ 20 декабря 2011

Необходимо обновить до последней стабильной версии 4.11 здесь .

...