| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Как реализовать прием пакета неопределеной длины? |
| Автор: LeonidPr 20.3.2012, 10:03 |
| В микроконтроллерах данная задача решается достаточно просто. Считается количество тиков аппаратного таймера, прошедших с момента приема последнего байта. Если это количество превысило некоторый лимит, то считаем, что принятые на этот момент байты - и есть весь пакет, далее идет его обработка, это уже дело техники. Как реализовать подобный алгоритм работы в windows? Немного объясню причину возникновения вопроса. Не раз приходилось писать простенькие программы для опроса конкретных устройств по ModBus. Обычно, в таком случае, отсылая запрос я уже знал размер ответа и считывал из порта нужное количество байт. При настроенных таймаутах, если пришло слишком мало байт (пакет оборван) обрабатывалась ошибка, если все нормально - обрабатывался ответ. Это работало, для тех программ большего было не нужно. Но это работает, если мы заранее знаем размер принимаемого пакета. А если нет? Хотелось бы сделать так: пришел пакет ответа, я его обработал. Либо, может кто-то подскажет, как реализуется опрос в подобных программах? |
| Автор: LeonidPr 20.3.2012, 10:33 |
| Понял, спасибо! |
| Автор: Dem_max 20.3.2012, 11:07 |
| Есть такое понятие как асинхронная передача(прием) данный, так вот при асинхронной передаче(прием) задается таймаут на операцию записи(чтения). При возникновении таймаута, операция считается законченной. |
| Автор: xvr 20.3.2012, 13:53 |
Отказаться от Windows и от PC В ModBUS RTU есть требования к формированию и детектированию интервалов между символами в линии с точностью до 0.5 символьного интервала. Windows этого принципиально делать не умеет, т.к. она не realtime система. Стандартный RS232 порт в PC для этого тоже не подходит, т.к. у него есть FIFO, и интервал между символами, как он их будет отдавать в софт, будет не совпадать с интервалом, как он их принимал. Единственный выход - отключить FIFO. Возможно сделать некую реализацию ModBUS RTU на PC + Windows выкрутив таймауты в 0 и запустив работу с портом в нитке с reat-time приоритетом, но это увы не будет гарантировать 100% работоспособность - ваш ModBUS может несколько суток/месяцев/лет проработать без нареканий, а потом в самый неподходящий момент потерять пакет другой |
| Автор: LeonidPr 20.3.2012, 14:32 |
| Я понимаю, что в точности контроль таймингов, заложенный в спецификации ModBus RTU на PC не сделать, да это и не требуется. GremlinProg дал возможный вариант реализации опроса. Меня просто интересует тема создания системы сбора данных (в частности по ModBus) и визуализации полученной информации (не полноценная SCADA а только визуализация). Вот и думаю, как делать опрос устройств, ведь компьютер может быть подключен через преобразователь к шине RS-485 с кучкой устройств, и со всех нужно собрать данные (для программы весь сбор ведется через один экземпляр порта). Может быть есть какая-нибудь литература по разработке такого рода программ или отдельные статьи? |
| Автор: Dem_max 20.3.2012, 16:11 |
| ModBUS - это же протокол передачи данных, причем тут физический уровень передачи данных ( RS-485, RS-232б Ethernet) ????? |
| Автор: xvr 20.3.2012, 16:39 | ||||||
Если по MudBUS'у будут идти пакеты один за другим, то вы их не сможете отделить друг от друга. В ModBUS RTU задержки между байтами входят в структуру передаваемых пакетов.
Работать будет крайне ненадежно.
Одной литературой тут не отделаешся, для этого ставят железки снаружи. И железки более интелектуальные, чем преобразователь RS485 <-> RS232
Кривой это протокол, увы. Точнее его ипостась ModBUS RTU over serial line |
| Автор: LeonidPr 20.3.2012, 19:57 | ||||||||
В общем-то я не спорю, но ModBus же работает по принципу запрос-ответ и пакеты не будут идти чаще, чем я отправляю запросы. Или я ошибаюсь?
Почему, объясните, если не сложно?
Знаю, а эти железки наверх уже отдают информацию по TCP/IP.
Опять же, хотелось бы услышать ваше мнение почему? Потому что размер пакета явно не передается? |
| Автор: xvr 21.3.2012, 10:22 | ||
Если ваша программа - мастер, и она не шлет пачки пакетов, то да. В вашем случае наверное можно сделать нечто 'для опроса устройст по ModBUS' (только не называйте это полноценным ModBUS устройством Опять же, в ваше случае скорее всего работать будет нормально. В общем случае синхронизировать управление направлением передачи по RS485 и передаваемые данные будет не так просто (из за наличия задержек неопределенной длинны и FIFO в железе). Конверторы с автоматическим определением направления передачи так же могут ошибаться (на один - два байта) В принципе достаточно было бы ModBUS ASCII Потому что временные характеристики передачи в физическом канале явно учавствуют в формировании протокола передачи. Это невозможно реализовать на любом UART порту. Необходима либо специальная выделенная железка, либо RealTime OS либо поддержка со стороны аппаратуры |
| Автор: LeonidPr 27.3.2012, 14:54 |
| Подумал тут на досуге и дошло, что вопрос какой-то пустой получился, по крайней мере в применении к ModBus. Как я уже писал, я знаю, какого размера ответ должен прийти, вот прихода стольких байт и надо ждать. А проблема какая-то надуманная получилась. Она наверное на сервере более актуальная, когда действительно не знаешь, какого размера запрос придет. Спасибо за помощь, тему закрываю. |