Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];

Вниз

Проблемы по работе с COM-портом   Найти похожие ветки 

 
plotn   (2006-11-23 08:06) [0]

Здравствуйте все!
У меня есть один достаточно сложный вопрос. Дело вот в чем. У меня есть софт, который общается по COM-порту. Т.е. 2 программа, одна "мастер", другая "слейв". Диалог происходит так: мастер посылает периодически запрос, слейв на него отвечает. Если слейв не отвечает, мастер посылает снова. Данных передается достаточно много - 500-1000 байт за передачу (от слейва мастеру, сам запрос мастера короткий).
Проблема. Почему то вся эта связка (тестируются обе программы на одном компьютере) чувствительна к загрузке системы. Т.е. если допустим запустить что нибудь тяжелое - архивирование файлов или кино, то начинают возникать ошибки в передаче - не все данные проходят (у меня в пакете пишется его длина, так вот она с реальной не совпадает). Ошибок немного 0,5 - 10 % в зависимости от загрузки.
Вопрос -как это объяснить? Это нормально? Или что то можно сделать? А то заказчик не хочет понять.
Технологически все выполнено так. Запросы посылаются по TTimer"у. Для приема и передачи используется компонент (один из самых популярных на мой взгляд) TComPort. Он создает тред, мониторящий компорт, все описания в инете рекомендуют делать именно так. Кстати ошибок меньше, если установить этому треду реалтайм приоритет. Основной поток занимается помимо передачи еще много чем - чтение данных из OPC-сервера, запись данных в базу... Но ошибки то почему? Как это внятно объяснить, особенно заказчику? Выставление таймаутов в компоненте не помогло - ставил там от миллисекунд до минут и все равно.
Спасибо заранее, буду раз любым комментариям.


 
MBo ©   (2006-11-23 08:14) [1]

> ошибки в передаче - не все данные проходят
Ты принимаешь несколько посылок и собираешь их вместе?
Какой размер входного буфера установлен у ComPort?


 
plotn   (2006-11-23 08:53) [2]

Нет, я сразу обрабатываю их. Т.е. я принимаю "пакет" - пакет ограничен у меня специальными байтами-маркерами в теле пакета никогда не встречающимися. Буфер по дефолту был килобайт, я ставил потом 4 кила, потом 32 - разницы особой не вижу... Но я вижу четкую зависимость от "загруженности" системы - как и сказал выше.


 
MBo ©   (2006-11-23 09:04) [3]

Никто не гарантирует, что вся посылка примется портом за один раз, поэтому стоит использовать свой накопительный буфер, например, по схеме:
OnRxChar:
прочитать Count байт
добавить в конец буфера
проверить, есть ли в буфере полный пакет
выделить пакет, остаток буфера сдвинуть
обработать пакет


 
Сергей М. ©   (2006-11-23 09:18) [4]


> plotn


Мастер посылает синхронный или асинхронный запрос ?


> Он создает тред, мониторящий компорт, все описания в инете
> рекомендуют делать именно так


Что значит "советуют" ? И кому ?
Разработчики TComPort поступили именно так, это их безусловное решение, хочешь ты того или не хочешь.


 
plotn   (2006-11-23 09:46) [5]

MBo: там есть компонент ДатаПакет, у которого есть событие - он дата пакет, я думаю все там так и делается (склеиваются RxChar"ы). К слову, когда я в запале души решил все "взять и поделить" - я заменил ткомпорт на асинкпро. У него этих свойств не было (датапакетов) и я эмулировал их примерно таким же способом как ты и описал. У меня общее ощущение что данные иногда доходят не все - то полпакета (байт 400), то вообще пару десятков байт.
Причем если машина сидит себе спокойно и пересылает данные (без лишних задач в смысле или умеренноспящие задачи), процент ошибочных пакетов всего полпроцента. А вот если грузить... то может и до 3-5-10 дойти.

Сергей М. : Просто мониторинг задачи (в инете) передачи данных по компорту говорит о том, что "все так делают", ну, или почти все. И примеры к книжке про порты (название не помню, мне примеры эти из нее присылали просто) и другие реализации (да асинкпро тот же).

Да, анализ сорцев показал что запросы асинхронные.

Вообще, возможна ли ситуация (а скорее всего да), что мастер не додавшись ответа клиента посылает ему снова запрос, а в этот момент клиент ему отвечает. Что тогда? Коллизия какая нибудь случается?


 
Сергей М. ©   (2006-11-23 10:10) [6]


> анализ сорцев показал что запросы асинхронные


Я не про внутреннюю организацию транспорта, а про твою прикладную логику.

Метод Write[Str] - синхронный.
Метод Write[Str]Async - асинхронный.

Вот я и спрашиваю - ты каким методом пользуешься ?


> Просто мониторинг задачи (в инете) передачи данных по компорту
> говорит о том, что "все так делают", ну, или почти все


Тебя это не должно заботить никоим образом.


 
plotn   (2006-11-23 12:22) [7]

вот, вызываю этот метод:

// perform synchronous write operation
function TCustomComPort.WriteStr(const Str: string): Integer;
var
 AsyncPtr: PAsync;
begin
 InitAsync(AsyncPtr);
 try
   WriteStrAsync(Str, AsyncPtr);
   Result := WaitForAsync(AsyncPtr);
 finally
   DoneAsync(AsyncPtr);
 end;
end;

А как надо? Асинхронно? Вообще, суть задачи я объяснил - может посоветуете как тут лучше.

>Тебя это не должно заботить никоим образом.

нет, я понимаю, но нельзя же не взирать на коллективный опыт...

Пришли результаты испытания с объекта:

Время тестирования - 18 часов
Процент ошибок - 1,05 %

в принципе это приемлемо, но мне суть вещей интересна


 
Сергей М. ©   (2006-11-23 12:40) [8]


> вот, вызываю этот метод


Т.е. используешь синхронный метод.


> нельзя же не взирать на коллективный опыт


Дело не в этом.
Как сделали разработчики TComPort, так и сделали - с потоком, значит с потоком.
От тебя лишь требуется принять это как факт и осознанно подходить к выбору режима обработки сообщений - вызов обработчиков в контексте либо потока-монитора, либо осн.потока, либо потока-создателя объекта TComPort


 
plotn   (2006-11-23 13:08) [9]

я стал думать (уже потом) насчет потока-монитора, но вот объясни плюсы и минусы подходов.

Сейчас все делается в осноном потоке (он же создатель ткомпорт). Да он занимается и писаниной в базу и чтением (с одного конца ОПЦ) и публикацией себя в качестве ОПЦ (с другого конца), но чем это плохо? Я согласен, допустим, если винде очень плохо эти события принимать не сразу, а после времени, я готов завести большой буфер, если потребуется.
а тут вот, ошибки...


 
Сергей М. ©   (2006-11-23 13:18) [10]


> ОПЦ


Это что ?


 
plotn   (2006-11-23 13:19) [11]

OPC, OLE for proccess control


 
Сергей М. ©   (2006-11-23 13:23) [12]


> чем это плохо?


Если осн.поток не отвечает за интерактивное взаимодействие с пользователем, то ничем не плохо.

Код бы привел ...


 
Сергей М. ©   (2006-11-23 13:24) [13]


> публикацией себя в качестве ОПЦ


ОРС-сервера, имеется ввиду ?


 
plotn   (2006-11-23 14:34) [14]

Основной поток как раз этим и занимается!
Там немного конечно в режиме работы (т.е. когда все сконфигурировано), но есть.
К чему это может привести?

насчет последнего - да, так оно и есть


 
Сергей М. ©   (2006-11-23 14:36) [15]


> Основной поток как раз этим и занимается!


чем ? GUI ?

Засада)


 
plotn   (2006-11-23 14:46) [16]

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


 
Сергей М. ©   (2006-11-23 14:52) [17]


> тот то, читающий то ведь нет!


Тот, "читающий", извещает основной о необходимости обращения "внимания на мои старания". И без подтверждения реакции на "извещение"  тот самый "читающий" с места не двинется.
А основной в это время занят черт те чем.  И довольно долго занят.

?


 
plotn   (2006-11-23 14:56) [18]

все понял, спасибо за разъяснения. попробую переделать, возоможно и поможет.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.983 c
6-1161374305
DillerXX
2006-10-20 23:58
2007.04.08
Помогите с WinINet ом... :(


3-1169105130
Dmitriy_info
2007-01-18 10:25
2007.04.08
Синтаксис SQL


2-1174310576
Степан
2007-03-19 16:22
2007.04.08
nil после Destroy


15-1173796015
eXPell
2007-03-13 17:26
2007.04.08
Исходящие...


15-1173703598
DSKalugin
2007-03-12 15:46
2007.04.08
помогите перевести на VBA





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский