|
Протокол modbus. Вопросы по интерфейсу |
|
|
|
Oct 16 2008, 10:46
|
Группа: Новичок
Сообщений: 2
Регистрация: 16-10-08
Пользователь №: 40 997

|
Здравствуйте. На работе дали задание разработать интерфейс сообщений между устройствами на основе протокола Modbus. Суть такова. Есть некоторое количество измерительных приборов, соединённых по RS-485. Нужно сделать так, чтобы с одного прибора можно было управлять другим - устанавливать режимы, принимать архивы измерений и т.д. За основу предложено взять протокол modbus. Уже месяц сижу и туплю. Вопросы: 1. Можно ли сделать так, чтобы любое устройство могло взять на себя роль главного? 2. Каким образом вообще передавать информацию главному? Через регистры, что ли? 3. С чего вообще начинать? Подскажите, пожалуйста, ткните носом во что-нибудь готовое, описание какое-нибудь. Протокол зачитал, но там, такое ощущение, всё привязано к конкретным контроллерам.
|
|
|
|
|
 |
Ответов
(1 - 93)
|
Oct 16 2008, 11:27
|
Группа: Новичок
Сообщений: 2
Регистрация: 16-10-08
Пользователь №: 40 997

|
Цитата(MrYuran @ Oct 16 2008, 14:24)  Если нужно менять мастера, то модбас не катит. Скорее ProfiBUS Т.е. совсем не катит? Нельзя так сделать?
|
|
|
|
|
Oct 17 2008, 07:56
|
Знающий
   
Группа: Свой
Сообщений: 793
Регистрация: 5-11-04
Из: Краматорск, Украина
Пользователь №: 1 057

|
Цитата(MrYuran @ Oct 16 2008, 14:24)  Если нужно менять мастера, то модбас не катит. Скорее ProfiBUS ProfiBUS (ProfiBUS/DP по кр.мере) не мультимастер. ЗЫ: А Модбас это и есть формат пакетов. Можно сделать пакет "передача мастера" плюс, на случай потерь, захват "мАстерства" по таймауту в зависимости от собственного адреса (ИД). В свое время интересовался мультимастерными сетями, некоторые решения были очень простыми.
|
|
|
|
|
Oct 17 2008, 08:27
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Andy Great @ Oct 17 2008, 11:56)  ProfiBUS (ProfiBUS/DP по кр.мере) не мультимастер. цитирую педию: Цитата PROFIBUS использует обмен данными между ведущим и ведомыми устройствами (протоколы DP и PA) или между несколькими ведущими устройствами (протоколы FDL и FMS). Требования пользователей к получению открытой, независимой от производителя системе связи, базируется на использовании стандартных протоколов PROFIBUS. Цитата Можно сделать пакет "передача мастера" плюс, на случай потерь, захват "мАстерства" по таймауту в зависимости от собственного адреса (ИД). Можно, но тогда это будет "стандарты нестандартные, системы бессистемные"
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Dec 3 2008, 22:13
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 21-11-08
Пользователь №: 41 832

|
Наверное, главной проблемой станет борьба с коллизиями. В модбасе ведомые устройства молчат, как примерные ученики, пока не спросят. Возможный вариант: гонять метку ведущего. Во всех устройствах выделить пару регистров. Первый - признак, что устройство хочет быть ведомым. Через некоторый интервал ведущий опрашивает все устройства. Если появились желающие, то пишет во второй регистр метку ведущего. Получил ответ - сам стал ведомым и тихо ждет своей очереди. Это уже было в TokenRing Однако, может оказаться два ведущих или никого.
Другой вариант. Драйвер RS485 следит за линией и самостоятельно борется с ошибками. А Ethernet, особенно коаксильный вариант.
P.S. С PROFIBUS не знаком (не требовалось).
|
|
|
|
|
Dec 4 2008, 11:10
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 21-11-08
Пользователь №: 41 832

|
Цитата(ucMike @ Dec 4 2008, 01:13)  P.S. С PROFIBUS не знаком (не требовалось). Упс. Profibus как раз.
|
|
|
|
|
Oct 17 2009, 19:30
|

Местный
  
Группа: Свой
Сообщений: 213
Регистрация: 28-02-07
Из: Киев
Пользователь №: 25 744

|
Цитата(defunct @ Jan 1 2009, 08:05)  По завершающей паузе некоторые слейвы определяют границу пакета. (не все ж считают CRC на лету). Пауза между пакетами должна быть не менее 3.5. По приему CRC слейв может сразу же приступить к формированию ответа, но слать ответ в линию он должен не ранее чем через 3.5 сивольного интервала. Довольно распространенное заблуждение насчет определения конца пакета путем подсчета CRC. Стандарт однозначно определяет конец пакетов по таймауту (не менее 3,5 байтовых интервалов для скоростей ниже 19200 и 1,75 мсек для скоростей выше 19200). Совсем не обязательно считать CRC на лету. Более того, обычно это даже вредно. Ответ в линию начинается после приема запроса, таймаута (3,5), обработки пакета (подсчета CRC + обработки), и (в случае полудуплексной линии) дополнительного времени на переключение направления, обычно делается порядка нескольких мсек
|
|
|
|
Guest_@Ark_*
|
Oct 17 2009, 21:29
|
Guests

|
Цитата Вопросы: 1. Можно ли сделать так, чтобы любое устройство могло взять на себя роль главного? 2. Каким образом вообще передавать информацию главному? Через регистры, что ли? 3. С чего вообще начинать? 3. Начинать нужно с детализации постановки задачи и выстраивания вашей системы на различных уровнях иерархии управления. 2. Начните с физического уровня. Определите, какое максимальное количество устройств может быть на линии. Какие объемы информации нужно передавать и с какой периодичностью. Тогда станет понятна необходимая скорость обмена и возможная частота опроса устройств. 1. Если за основу выбран протокол MODBUS, то я бы не советовал Вам делать систему со многими ведущими. На много проще, когда ведущий один. Желательно, что бы им было устройство с наибольшими собственными ресурсами -персональный компьютер (ПК), например. 0. На каждом уровне иерархии, ведущими могут быть различные устройства системы. Совсем не обязательно, чтобы ведущий был один и тот же на всех уровнях. Такое прямое, "лобовое" решение - не всегда самое лучшее. Например, на протокольном уровне ведущим может быть ПК, а на более высоком уровне - им может быть, к примеру, какой-нибудь выносной пульт управления. Хотя он будет подчиненным устройством с точки зрения MODBUS, но фактическое управление системой будет осуществляться с него. ПК будет периодически читать его по MODBUS, получая, таким способом, указания, что необходимо делать в данный момент. Далее, эти "указания" обрабатываются в ПК и преобразуются в последовательность протокольных команд для других подчиненных устройств... Подобным же образом можно реализовать и передачу функций ведущего устройства (высокоуровневого) другим устройствам или получить систему с многими ведущими. При этом, формально, протокол не будет нарушен, и коллизии между устройствами не будут возникать (по крайней мере на физическом уровне).
|
|
|
|
Guest_@Ark_*
|
Oct 17 2009, 21:40
|
Guests

|
Sorry, не посмотрел на дату.  Просто тема показалась интересной...
|
|
|
|
|
Oct 18 2009, 17:51
|

Местный
  
Группа: Свой
Сообщений: 213
Регистрация: 28-02-07
Из: Киев
Пользователь №: 25 744

|
Цитата(rezident @ Oct 18 2009, 00:36)  koyodza, @Ark, зачем нужно старую тему поднимать? Думаете, что топикстартер, создавший ее год назад и тогда же последний раз в ней отметившись, прочитает? Я ответил скорее не топикпастеру, а на фразу defunct по поводу того что "По приему CRC слейв может сразу же приступить к формированию ответа". Поскольку это грубое, но очень сильно распространенное нарушение стандарта, решил указать на это. Сообщения ведь попадают в "Копилку Вечности", вдруг кто-то из начинающих когда-то забредёт сюда (даже в правилах написано - новую тему создавать после того, как ничего не нашел поиском), и подумает что так и нужно делать...
|
|
|
|
|
Oct 24 2009, 06:12
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
Здравствуйте.У меня такой вопрос: Есть теплосчетчик с RS485 и Modbus RTU, есть программа для снятия архивов с него, через сом-порт и переходник 232-485 все снимается. Есть желание соединить к счетчику GSM- модем с RS-485 выходом и опрашивать архивы удаленно по CSD. Но в программе нет функции дозвона, только по сом-порту. Можно ли сделать так- соединить модем к com-порту компьютера, дозвониться гипертерминалом, отключить гипертерминал(чтобы освободить порт), запустить программу снятия архивов, после снятия, отключить связь гипертерминалом ? Если да, то какие подводные камни могут возникнуть при этом, или есть какой нибудь другой способ, кроме написания своей проги для опроса счетчика ,конечно.
|
|
|
|
|
Oct 24 2009, 07:18
|

читатель даташитов
   
Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999

|
Цитата(D&M @ Oct 24 2009, 09:12)  Можно ли сделать так- соединить модем к com-порту компьютера, дозвониться гипертерминалом, отключить гипертерминал(чтобы освободить порт), запустить программу снятия архивов, после снятия, отключить связь гипертерминалом ? Если да, то какие подводные камни могут возникнуть при этом, или есть какой нибудь другой способ, кроме написания своей проги для опроса счетчика ,конечно. Проще сделать своё устройство с виртуальным USB CDC, и устанавливать соединение перед снятием логов. Для программы это будет прозрачно. Единственное что - могут быть задержки при передаче, и это не удастся побороть.
|
|
|
|
|
Oct 24 2009, 08:13
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
устройство с виртуальным USB CDC- это как я понял железка, которая прикидывается сом-портом, а сама подключается на USB и к к ней подключается сотовый модем. А задержки могут быть из-за этой железки или на сотовом канале и могут ли они влиять modbus протоколу или только на скорость работы? Раз вы говорите "проще так сделать", значит и по моему варианту тоже можно? если так, то можно написать простенькую программу дозвона с автоматическим вызовом программы счетчика и отключением.
Сообщение отредактировал D&M - Oct 24 2009, 08:23
|
|
|
|
|
Oct 24 2009, 20:41
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
или как ? жду разных предложений.. Кстати- USB CDC-это идея..
Сообщение отредактировал D&M - Oct 24 2009, 20:42
|
|
|
|
|
Oct 25 2009, 02:15
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(D&M @ Oct 25 2009, 01:41)  или как ? жду разных предложений.. Ваша задача разбивается на два вопроса. Во-первых, вы не огласили какой именно MODBUS используется? Modbus RTU весьма плохо "ложится" на коммутируемые линии (телефоная связь). Для коммутируемых линий Mobus ASCII предназначался. Во-вторых, программы автодозвона есть готовые. Насчет бесплатности не в курсе, не исследовал этот вопрос. Задача этой программы установить связь и обеспечить "прозрачный" режим работы модема. То бишь ваша программа не будет знать, что у нее не проводная связь, а коммутируемая. А вообще такие задачи решают с помощью OPC-сервера. Программы, которая занимается установлением связи, опросом удаленных устройств и доставкой данных с конвертацией их в требуемый для другой программы (SCADA-системы) формат.
|
|
|
|
|
Oct 25 2009, 07:36
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
Тогда может посоветуете OPC-сервер,который может дозваниваться по GSM и SCADA систему.
|
|
|
|
|
Oct 26 2009, 15:46
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
Посмотрел,продумал разные варианты и пришел к выводу- MODBUS-RTU не очень подходит для GSM, и прога для снятия архивов, т.к. нужны только накопленные значения с 2-3 каналов(2-3 показания механических счетчиков) и 2 температуры. Лучше наверно сделать железку например на ATMEGA162, которая будет на стороне счетчика опрашивать по Modbus и по запросу передавать эти 5 цифр в любом виде, может быть DTMF-ом или по другому. Только железок много собирать- счетчиков штук 100.
Сообщение отредактировал D&M - Oct 26 2009, 15:49
|
|
|
|
|
Oct 26 2009, 18:23
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
ответил
|
|
|
|
|
Nov 3 2009, 19:15
|

Участник

Группа: Свой
Сообщений: 72
Регистрация: 10-02-05
Из: Краснодар
Пользователь №: 2 558

|
Цитата(D&M @ Oct 26 2009, 18:46)  Посмотрел,продумал разные варианты и пришел к выводу- MODBUS-RTU не очень подходит для GSM, и прога для снятия архивов, т.к. нужны только накопленные значения с 2-3 каналов(2-3 показания механических счетчиков) и 2 температуры. Лучше наверно сделать железку например на ATMEGA162, которая будет на стороне счетчика опрашивать по Modbus и по запросу передавать эти 5 цифр в любом виде, может быть DTMF-ом или по другому. Только железок много собирать- счетчиков штук 100. Не знаю чем RTU не подходит для GSM. что CSD что GPRS это такие же байты как и в любом другом канале. CRC если что ошибки призвана прибивать. варианты: 1. Проще делать как описал rezident. правда громоздко и некрасиво. это способ для непрограммеров. 2. Модем c RS485 что из себя представляет ? я почему спрашиваю, по дефолту обычные модемы RS232, а с RS485 это уже специальные версии. Вместо них может попробовать "GSM(GPRS)-удлинители com-порта", вроде у Аналитика нечто подобное было, да и у других контор, в сопоставимом ценовом диапазоне. 3. Либо если не напрягает сделать 100 железок, может проще сделать 1 (либо 1+100, как нравится), но которая будет сама обзванивать нижний уровень и что-нибудь ещё полезное делать, например по новым виртуальным адресам счётчики разбрасывать
|
|
|
|
|
Nov 4 2009, 18:49
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
1,3 варианты продумал,говорил про модем teleofis-rx108-r-rs485, вообще счетчики разочаровали-пробовал ОРС-модбус сервером опрашивать по адресам регистров по документации-самый нужный параметр не выдает- итоговое накопленное, тогда и смысла нет в затее..
|
|
|
|
|
Nov 5 2009, 15:04
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
Нету Modbus-TCP, есть Modbus-RTU в моем рассказе.
|
|
|
|
|
Nov 5 2009, 15:50
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(MrYuran @ Nov 5 2009, 09:17)  По ГПРС пинги по полторы секунды - не редкость. Угу. Цитата А Modbus-TCP для кого придумали? По моему скромному, самое оно для таких сетей Вот это Вы Автору, который хочет знать только RTU и видит в нем только байты, и не видит никаких проблем объясните.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Nov 6 2009, 11:21
|

Участник

Группа: Свой
Сообщений: 72
Регистрация: 10-02-05
Из: Краснодар
Пользователь №: 2 558

|
Цитата(zltigo @ Nov 4 2009, 22:17)  Ну а время, время между этими самыми байтами, как с ним дела обстоят? Огласите. Т.е. Mobus ASCII тут будет гораздо лучше ? Именно в отношении RTU vs ASCII выше было обсуждение. К тому же D&M вообще CSD пока обсуждает имхо. Цитата(MrYuran @ Nov 5 2009, 09:17)  По ГПРС пинги по полторы секунды - не редкость. и более...
|
|
|
|
|
Nov 6 2009, 12:41
|
Группа: Участник
Сообщений: 13
Регистрация: 24-10-09
Пользователь №: 53 179

|
У счетчика Modbus-RTU, а в модеме только CSD..
|
|
|
|
|
Nov 6 2009, 13:10
|

Участник

Группа: Свой
Сообщений: 72
Регистрация: 10-02-05
Из: Краснодар
Пользователь №: 2 558

|
Цитата(D&M @ Nov 6 2009, 15:41)  У счетчика Modbus-RTU, а в модеме только CSD.. Вы сначала определитесь со всей структурой системы, а затем переходите к решению отдельных пунктов. Например: 1. Что на верхнем уровне (компьютер) - какая-то готовая программа, нечто самописное, нечто на основе SCADA/OPC... Отсюда уже станет ясно, сможет ли эта программа сама всех обзванивать или иметь дополнительный функционал, и нужны ли будут нижеследующие промежуточные звенья: 2. Контроллер опроса верхнего уровня - "железка", которая сама будет обзванивать, опрашивать счетчики и преобразовывать данные в понятный формат для (п.1) программе, естественно и поддерживать обмен по протоколу который эта программа (п.1) поддерживает. 2а. модем. 3а. модем. 3. Контроллер опроса нижнего уровня - "железка" которая будет производить дополнительную обработку собранных данных до передачи в канал связи. 4. Ваши счетчик(и) В зависимости от конкретных условий - фунционала ПО п.1, канала связи и т.д., п.2 и п.3 могут отсутствовать.
|
|
|
|
|
Nov 8 2009, 00:09
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(koyodza @ Oct 18 2009, 19:51)  Я ответил скорее не топикпастеру, а на фразу defunct по поводу того что "По приему CRC слейв может сразу же приступить к формированию ответа". Поскольку это грубое, но очень сильно распространенное нарушение стандарта, решил указать на это. Стандарты порой устаревают. А сильно распространненные нарушения часто становятся частью страндарта. Грубых нарушений стандарта в упор не вижу, если CRC сошлась ложно, то пакет отбракуется по длине и прием продолжится. С другой стороны, на кой в холостую ждать 3.5 символьных интервала (это ж вагон и еще маленькая тележка времени особенно на 9600 и ниже), когда их можно потратить с пользой, например на вычитку архива из медленного eeprom'а по текущему запросу мастера. Цитата Сообщения ведь попадают в "Копилку Вечности", вдруг кто-то из начинающих когда-то забредёт сюда (даже в правилах написано - новую тему создавать после того, как ничего не нашел поиском), и подумает что так и нужно делать... Может для "Копилки Вечности" у вас найдется способ отмерить таймаут в 1.75ms под Windows?
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 01:37
|
Guests

|
Цитата ... Я ответил скорее не топикпастеру, а на фразу defunct по поводу того что "По приему CRC слейв может сразу же приступить к формированию ответа". Поскольку это грубое, но очень сильно распространенное нарушение стандарта, решил указать на это. Сообщения ведь попадают в "Копилку Вечности".... Ну, если писать с прицелом в "Копилку Вечности", то нужно быть более точными в формулировках. Прием сообщения считается завершенным, если обнаружена пауза не менее 3.5 дительностей передачи одного символа, а правильность приема определяется по значению CRC. Начинать передачу ответа можно сразу по истечении длительности интервала ожидания конца сообщения (3,5 символа), не делая каких-либо дополнительных пауз. По этой причине, для экономии времени, правильнее сразу начинать анализ сообщения и формирование ответа, уже в процессе приема сообщения, не дожидаясь конца передачи и завершающей паузы. Естественно, что делать какие-либо критичные действия (например, запись переменных) и отправлять ответ, можно только после успешного завершения приема и проверки корректности сообщения. А вот, например, проверять код номера устройства, допустимость параметров команды, вести подсчет контрольной суммы, производить чтение данных - вполне можно уже в процессе приема сообщения. И ни каким нарушением стандарта это не является.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 01:56
|
Guests

|
Цитата Из всего перечисленного какой-то практический смысл имеет только проверка адреса. Все остальное - это просто создание себе вороха проблем ради весьма сомнительной экономии. Эта "сомнительная экономия" требуется, когда необходимо сократить время ответа устройства до минимально возможного, и, тем самым, повысить быстродействие всей системы. Если для Вас это не критично - можете не экономить, никто не заставляет.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 02:21
|
Guests

|
Цитата ... значит что-то не так с выбором протоколов и интерфейсов. Конечно. Самое простое решение - взять канал побыстрее, а "камень по-больше", чего там экономить!
|
|
|
|
|
Nov 8 2009, 02:32
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Ради справедливости хотелось бы заметить, что не всегда есть возможность разбирать пакет "на лету" по причине многоуровневой организации связи. Вообще говоря, ModBus это довольно высокий уровень в сетевой модели OSI. Когда у устройства только один коммуникационный интерфейс и только один поддерживаемый протокол, то там можно конечно наоптимзировать. Но в общем случае формирование и разбор пакетов не связаны напрямую с их приемом/отправкой и тем более с отслеживанием пауз. Прием/отправка чаще всего привязаны к прерываниям UART. Но в прерывании UART не желательно еще и паузы отслеживать (в крайнем случае можно лишь каждый байт сопровождать меткой времени, интерлив этих меток анализировать не его задача) и за сетевыми адресами следить и CRC считать. Там потоковые буферы работают. А у буфера только три параметра: указатель на его начало, индекс текущего элемента и счетчик кол-ва байт. Все! Больше ничего буферу не нужно. И что там именно принимается или передается функции прерываний уже не интересует. Есть что-то в буфере передачи - передаем (если передача разрешена) пока не закончится это что-то. На приеме: если что-то пришло, без ошибок, фиксируемых аппаратурой UART, и есть место в буфере приема, то принимаем. Только такая организация физического уровня позволяет его использовать вне зависимости от вышестоящего протокола. P.S. вдогонку, а кроме UART есть (существуют) еще и другие интерфейсы  P.P.S. вообще лично я отношусь отрицательно, когда в реализации связи не предусмотрены настраиваемые задержки. Не нужны тебе задержки - занули их, но пускай они будут. Самому же потом будет проще адаптировать свою аппаратуру к чужим сетям.
|
|
|
|
|
Nov 8 2009, 02:55
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Ну, как и следовало ожидать, конкретные цифры озвучены не были. Цитата(@Ark @ Nov 8 2009, 05:21)  Конечно. Самое простое решение - взять канал побыстрее, а "камень по-больше", чего там экономить!  Считаете, простое решение менее разумно? А я вот полагаю, что куда менее разумно доводить до абсурда "оптимизацию". Цитата(defunct @ Nov 8 2009, 05:47)  Пусть сэкономим 5ms на пакет. Много это или мало... хм.. на тысяче пакетов сэкономим 5 секунд, на 10K - 50 секунд уже существенно. Ну, 5ms сэкономим разве что при скорости 9600 (два байта CRC и 3.5 паузы). И сколько секунд в этом случае займут 10К пакетов? Экономия получается на уровне единиц процентов в самом лучшем случае.
|
|
|
|
|
Nov 8 2009, 03:27
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 8 2009, 04:32)  Но в общем случае формирование и разбор пакетов не связаны напрямую с их приемом/отправкой и тем более с отслеживанием пауз. Прием/отправка чаще всего привязаны к прерываниям UART. Но в прерывании UART не желательно еще и паузы отслеживать (в крайнем случае можно лишь каждый байт сопровождать меткой времени, интерлив этих меток анализировать не его задача) и за сетевыми адресами следить и CRC считать. Насчет приемной части пожалуй позволю себе с Вами не согласиться. При использовании последовательных интерфейсов, определением границ пакета удобнее всего заниматься там, где идет посимвольный поток. А где такой поток идет нативно? - Как раз в RX прерывании UARTa. Смену протокола, не меняя (не нарушая) структуру драйвера UART'a тоже элементарно сделать - предусмотрев подмену потоковой функции-обработчика. Крайне желательно чтобы эта функция-обработчик занималась определением сетевого адреса, отбрасывая мусор нам непредназначенный, тем самым экономя и время, и память. Пусть есть сл. обработчик прерывания (упрощенно): Код __interrupt void uart_RxExtHandler(void) { U8 status = UART_STATUS_REG; U8 ch = UART_DATA_REG;
if (status != OK ) { DoHandleError(); return; }
if (rx_cb) // Есть спец-функция обработки потока? rx_cb( ch ); // пользуем ее else // нет, тогда... { ... положить в generic uart буфер или сделать что-то еще } } Смена протокола сведется к смене обработчика потока: rx_cb = MEK_RxCharHandler; rx_cb = Modbus_RxCharHandler; rx_cb = hc_RxCharHandler; rx_cb = ppp_RxCharHandler; rx_cb = slip_RxCharHandler; ... и т.д. и т.п. Пример возможного обработчика потока: Код /***************************************** * ppp_RxCharHandler() * * Attached when lower layer is UP * * using byte staffing (flag sequence) * * to extract packets * * ---> val - current char from the link * * <--- returns nothing * *****************************************/ static void ppp_RxCharHandler(U8 val) { PPACKET_BUF pInPkt = linkContext.pInPkt; #if (AUTO_ESCAPE) static U8 prevch = 0; U8 esc_val = (prevch == PPP_ESCAPE) ? val ^ 0x20 : val; #else #define esc_val val #endif
if (!pInPkt) // return if no storage return;
linkContext.pppRxOctetCnt += 1; linkContext.pppRxTimeSinceLastOctet = 0; if (val == PPP_FLAG) // new packet / end of packet { ppp_NewPacket( pInPkt ); } else { // receiving packet #if (AUTO_ESCAPE) if (!ppp_IsEscaped( linkContext.inACCM, val)) { pInPkt->payload[ pInPkt->Length++ ] = esc_val; pInPkt->fcs = ppp_fcs16( pInPkt->fcs, &esc_val, 1); if (pInPkt->fcs == PPPGOODFCS16) ppp_NewPacket( pInPkt ); } #else pInPkt->payload[ pInPkt->Length++ ] = esc_val; #endif if (pInPkt->Length >= MAX_LINK_PACKET_SIZE) { // break receving (exceed max len) linkContext.pppRxDiscardMaxLen += 1; pInPkt->Length = 0; } }
#if (AUTO_ESCAPE) prevch = val; #endif } То что в этом обработчике делается весьма просто и без лишних затрат памяти - escaped characters, нативное определение границ пакета, - делать в аппликейшине накладнее. Кроме того например Microsoft не утруждает себя посылкой закрывающего флага 0x7E в конце пакета, MS считает что достаточно одного 0x7E флага в начале пакета. Поэтому, чтобы не терять время в ожидании таймаута <хрен знает какой длины> или следующего пакета с разделительным флагом - FCS (CRC) текущего пакета считается на лету, при совпадении пакет сразу же отцепляется. Цитата На приеме: если что-то пришло, без ошибок, фиксируемых аппаратурой UART, и есть место в буфере приема, то принимаем. Только такая организация физического уровня позволяет его использовать вне зависимости от вышестоящего протокола. Ну мы говорим не про физ уровень, а про канальный уровень. Приведенная выше организация решает обратную задачу, - как сделать протокол пригодным к использованию с любым каналом и экономить память занимаемую канальным уровнем. Байт-обработчики можно использовать и для пакетных интерфесов, т.к. никто не мешает вызвать их n раз для n байт принятого пакета. Она не противоречит и Вашей организации. Можно из буфера приема (если есть память под этот отдельный буфер приема) читать символы побайтово, и скармливать байт-обработчику, только это будет двойная работа, и нет ясности как быть с таймаутами (не думаю что Вы всерьез предложили наградить каждый принятый байт довеском их одно-, двух-, трех-, четырех- байтой метки времени).
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 06:30
|
Guests

|
Цитата Ну, как и следовало ожидать, конкретные цифры озвучены не были... А какие могут быть конкретные цифры, без указания конкретной задачи? Пример могу привести. При реализации операции чтения по MODBUS (например, значений АЦП), часто требуется первичную обработку данных делать в самом устройстве (получение и усреднение нескольких значений, масштабирование результата, пересчет и приведение к нужному виду). А не гнать поток "сырой информации" мастеру, перекладывая на него их обработку, и загружая канал. В этом случае формирование ответа может занимать значительное время - сравнимое со временем приема сообщения... Цитата Считаете, простое решение менее разумно?.... Для приведенного примера - более простое решение просто не приемлемо. Считать 100 значений АЦП и передать по каналу усредненный результат, или 100 раз передать по MODBUS "сырые" значения - разницу трудно не заметить.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 15:30
|
Guests

|
Цитата ... вдруг, по команде извне, начинаем АЦПировать и накапливать 100 значений, вместо того, чтобы делать это постоянно и спокойно отдавать при необходимости готовый результат. ... Только этот "готовый результат", полученный "постоянным и спокойным АЦПированием" - ни кому не нужен, когда необходимо получить мгновенное значение с максимальной точностью и минимальной временной задержкой. Вообще, что я Вам доказываю - каждый выбирает технические решения так, как считает нужным. Вам не нравятся мои подходы, а мне - Ваши. На том и остановимся. В конечном итоге - меня лично интересует только мнение заказчика по этому поводу, и ни чье больше... Удачи!
|
|
|
|
|
Nov 8 2009, 15:46
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 8 2009, 18:30)  ... Только этот "готовый результат", полученный "постоянным и спокойным АЦПированием" - ни кому не нужен, когда необходимо получить мгновенное значение с максимальной точностью и минимальной временной задержкой. Да нет, скорее вряд ли кому нужно "мгновенное значение", полученное с "минимальной временной задержкой", обеспеченной средствами Модбаса (т.е. примерно никак не обеспеченной). Цитата(@Ark @ Nov 8 2009, 18:30)  Удачи! И Вам!
|
|
|
|
|
Nov 8 2009, 16:02
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
2 defunct, еще раз обращаю внимание, что я писал про общий случай, а не про тот, когда устройство только связью занимается. И не про канальный уровень, а про физический, когда обработка прерывания по времени должна занимать как можно меньше времени. Потому, что могут быть и другие прерывания тоже критичные ко времени. Ничего не имею против вашего мнения, но получается, что вы сами себе возражали, т.к. переиначили мое сообщение так, чтобы вам было удобно возражать
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 16:06
|
Guests

|
Цитата ... скорее вряд ли кому нужно "мгновенное значение", полученное с "минимальной временной задержкой", обеспеченной средствами Модбаса (т.е. примерно никак не обеспеченной). Вашими методами, конечно, может получится "никак не обеспеченной", а за других - не "расписывайтесь".
|
|
|
|
|
Nov 8 2009, 16:24
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 8 2009, 19:06)  Вашими методами, конечно, может получится "никак не обеспеченной", а за других - не "расписывайтесь".  А что будет с вашей "минимальной временной задержкой", случись, скажем, ошибка при передаче? Минимальным задержкам место внутри одного устройства, а не в распределенной системе, связанной протоколом сорокалетней давности. Гениально просто: слейв получил команду "считать что-то с АЦП", и не убеждаясь в достоверности оной (мы ведь спешим, пожар!), начинает накапливать мильен отсчетов. А потом - бац! - CRC не совпало. Что делать? Конечно, отработать аварийный выход (и так для любой команды чтения, ага). Красиво?
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 17:15
|
Guests

|
Ну, хорошо, давайте продолжим... Цитата А что будет с вашей "минимальной временной задержкой", случись, скажем, ошибка при передаче? Ничего страшного -"выпадет" одно из значений. Ошибки при передаче случаются при любом протоколе. При необходимости, мастер заменит выпавшее значение его аппроксимацией. Цитата Минимальным задержкам место внутри одного устройства, а не в распределенной системе, связанной протоколом сорокалетней давности. А вот это разработчику системы решать - какие устройства использовать, какими каналами их связать, какими протоколами воспользоваться и где какие допустимые задержки установить. И при этом, нужно еще помнить о стоимости системы... Цитата Гениально просто: слейв получил команду "считать что-то с АЦП", и не убеждаясь в достоверности оной (мы ведь спешим, пожар!), начинает накапливать мильен отсчетов. А потом - бац! - CRC не совпало. Что делать? Конечно, отработать аварийный выход (и так для любой команды чтения, ага). Красиво? А что Вас смущает? Вполне нормальная стратегия : обнаружили ошибку - прекратили выполнение команды и перешли обработке ошибки. А если нет ошибки, то результат готов сразу по завершению обработки команды. Например, процессор в Вашем компьютере поступает примерно так же - очень много чего считает, забегая вперед, а потом лишь выбирает нужный результат. Если бы этого не было, то, возможно, Винда на Вашем ПК ползала бы как черепаха...
|
|
|
|
|
Nov 8 2009, 17:27
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 8 2009, 20:15)  Ничего страшного -"выпадет" одно из значений. Ошибки при передаче случаются при любом протоколе. При необходимости, мастер заменит выпавшее значение его аппроксимацией. Выпадет просто, да? А таймаут ответа "сверхточную" времянку, конечно, не сместит. Цитата(@Ark @ Nov 8 2009, 20:15)  А вот это разработчику системы решать - какие устройства использовать, какими каналами их связать, какими протоколами воспользоваться и где какие допустимые задержки установить. И при этом, нужно еще помнить о стоимости системы... Ну, мне вот всегда казалось, что решение применить модбас можно принять разве что при наличии административного давления, если клиент очень того хочет. Цитата(@Ark @ Nov 8 2009, 20:15)  А что Вас смущает? Вполне нормальная стратегия : обнаружили ошибку - прекратили выполнение команды и перешли обработке ошибки. А если нет ошибки, то результат готов сразу по завершению обработки команды. Меня лично смущает принесение здравого смысла в жертву за три копейки, только и всего. Цитата(@Ark @ Nov 8 2009, 20:15)  Например, процессор в Вашем компьютере поступает примерно так же - очень много чего считает, забегая вперед, а потом лишь выбирает нужный результат. Если бы этого не было, то, возможно, Винда на Вашем ПК ползала бы как черепаха... Не считает, а считывает, и не очень много.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 17:43
|
Guests

|
Цитата Выпадет просто, да? А таймаут ответа "сверхточную" времянку, конечно, не сместит. С чего вдруг? Точность обеспечиватется, заранее известной, точной задержкой от завершения измерений до начала передачи ответа. Цитата Ну, мне вот всегда казалось, что решение применить модбас можно принять разве что при наличии административного давления, если клиент очень того хочет. Бывает и так. Мне и самому MODBUS не нравится. Но если клиент настаивает - как ему отказать? К тому же MODBUS - промышленный стандарт, все-таки. Цитата Меня лично смущает принесение здравого смысла в жертву за три копейки, только и всего. Это нужно считать отдельно, в каждом конкретном случае. Иногда стоимость "здравого смысла" - отнюдь не три копейки. Цитата Не считает, а считывает, и не очень много. И считывает, и считает (вычисляет). А потом еще "довычисляет", если нужно. И все равно, в итоге, получается быстрее...
|
|
|
|
|
Nov 8 2009, 17:48
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 8 2009, 18:02)  И не про канальный уровень, а про физический, Выше Вы привели ссылку на модель OSI, вы ее читали? Физический уровень Самый нижний уровень модели предназначен непосредственно для передачи потока данных. Осуществляет передачу электрических или оптических сигналов в кабель или в радиоэфир и, соответственно, их приём и преобразование в биты данных в соответствии с методами кодирования цифровых сигналов. Другими словами, осуществляет интерфейс между сетевым носителем и сетевым устройством.Канальный уровень Этот уровень предназначен для обеспечения взаимодействия сетей на физическом уровне и контроля за ошибками, которые могут возникнуть. Полученные с физического уровня данные он упаковывает во фреймы, проверяет на целостность, если нужно исправляет ошибки (посылает повторный запрос поврежденного кадра) и отправляет на сетевой уровень.Физический уровень это сугубо природа сигналов, трансивер и иже с ним сдвиговый регистр и схема битового кодированая (манчестер, инверсия и т.п.). А выделением из мусора битов входного потока осмысленных данных, проверкой ошибок, занимается уже канальный уровень, на ступеньку выше. Прерывание от UART "кадр принят" это не физ, а канальный уровень. Цитата когда обработка прерывания по времени должна занимать как можно меньше времени. Потому, что могут быть и другие прерывания тоже критичные ко времени. Ничего не имею против вашего мнения, но получается, что вы сами себе возражали, т.к. переиначили мое сообщение так, чтобы вам было удобно возражать  просто показал что имеет смысл собирать пакеты побайтово прямо в прерывании, а не наваливать бездумно все байты в буфер перекладывая тем самым работу канального уровня на сетевой уровень. Для примера взял PPP который в отличие от Modbus является протоколом строго канального уровня.
|
|
|
|
|
Nov 8 2009, 18:25
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 8 2009, 20:43)  С чего вдруг? Точность обеспечиватется, заранее известной, точной задержкой от завершения измерений до начала передачи ответа. То есть процесс считывания АЦП в вашей системе выглядит так: 1. Мастер через строго определенные промежутки времени дает запрос на считывание АЦП 2. Слейв считывает/накапливает, возвращает отсчет мастеру 3. Если ответ не получен, мастер восстанавливает данные интерполяцией Я правильно понял? Как вы считаете, сколько времени будет сэкономлено, если предоставить слейву минимальную самостоятельность, и забирать данные не по семплу, а блоками с гарантированной доставкой? Цитата(@Ark @ Nov 8 2009, 20:43)  Это нужно считать отдельно, в каждом конкретном случае. Иногда стоимость "здравого смысла" - отнюдь не три копейки. Стоимость потери здравого смысла здесь определяется двумя байтами CRC, время на получение которых вы так упорно хотите сэкономить, наворотив при этом кучу ненужного кода. По сравнению с тем оверхедом, который в принципе дает использование модбаса, это - ноль. Цитата(@Ark @ Nov 8 2009, 20:43)  И считывает, и считает (вычисляет). А потом еще "довычисляет", если нужно. И все равно, в итоге, получается быстрее... Ну, расскажите мне про современные процессоры, как они "очень много чего считают, забегая вперед".
|
|
|
|
|
Nov 8 2009, 18:39
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(defunct @ Nov 8 2009, 22:48)  Выше Вы привели ссылку на модель OSI, вы ее читали? Вот потому, что я ее читал (и неоднократно) и не называю его канальным. Т.к. часть характеристики Цитата Полученные с физического уровня данные он упаковывает во фреймы, проверяет на целостность, если нужно исправляет ошибки (посылает повторный запрос поврежденного кадра) и отправляет на сетевой уровень. в моем описании отсутствует. Вообще сетевая модель OSI это лишь идеал. В реальности крайне мало (стеков) протоколов которые бы полностью укладывались в эту модель. Возможно я вообще зря ее упомянул.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 19:24
|
Guests

|
Цитата Как вы считаете, сколько времени будет сэкономлено, если предоставить слейву минимальную самостоятельность, и забирать данные не по семплу, а блоками с гарантированной доставкой? То есть, как я понял, Вы настойчиво предлагаете передавать все данные мастеру, отказавшись от их обработки в устройстве? Сделать канал побыстрее, увеличить траффик, нагрузить мастера дополнительными задачами... Я это уже комментировал, повторятся не буду. Цитата Стоимость потери здравого смысла здесь определяется двумя байтами CRC, время на получение которых вы так упорно хотите сэкономить, наворотив при этом кучу ненужного кода. По сравнению с тем оверхедом, который в принципе дает использование модбаса, это - ноль. Это всего лишь Ваше мнение, основанное видимо, на Вашем личном опыте программирования А когда оно еще и не привязано к условиям конкретной задачи - его ценность, увы, нулевая. Цитата Ну, расскажите мне про современные процессоры... http://ru.wikipedia.org/wiki/%D0%9F%D1%80%...%BE%D1%80%D1%8B
|
|
|
|
|
Nov 8 2009, 19:42
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 8 2009, 22:24)  То есть, как я понял, Вы настойчиво предлагаете передавать все данные мастеру, отказавшись от их обработки в устройстве? Сделать канал побыстрее, увеличить траффик, нагрузить мастера дополнительными задачами... Я это уже комментировал, повторятся не буду. Да нет же, все с точностью до наоборот. Это вы пытаетесь нагрузить шину "реалтаймовыми" и предельно неэффективными передачами по одному семплу. Я предлагаю снабдить слейв минимальным интеллектом, и работать блоками данных (накопленных, нормализованных и т.д. и т.п.), но не в реальном времени. Цитата(@Ark @ Nov 8 2009, 22:24)  Не надо меня пугать википедией. Что я там должен был увидеть - прогнозирование ветвлений? Но в этом случае речь идет только о загрузке конвейера, а никак не о забегающих вперед вычислениях.
|
|
|
|
|
Nov 8 2009, 19:51
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 8 2009, 20:39)  Вот потому, что я ее читал (и неоднократно) и не называю его канальным. Т.к. часть характеристики в моем описании отсутствует. Не совсем, у Вас в описании просматривается часть характеристки канального уровня - проверка правильности принятых данных (по крайней мере четность). Цитата Вообще сетевая модель OSI это лишь идеал. В реальности крайне мало (стеков) протоколов которые бы полностью укладывались в эту модель. Возможно я вообще зря ее упомянул.  Согласен, однако если грань между верхними тремя уровнями (session/presentation/app) настолько мала что ее часто трудно найти особенно в embedded сфере, то границы между нижними уровнями физ, канал, транспорт - просматриваются довольно четко. И хотя бы на этих трех уровнях можно пытаться стремиться к идеалу: <физ уровень> --> сводится к драйверу железа или эмулятору железа (программый UART/ программный SPI) <канальный уровень> ---> разбиение пакетов на голые байты и передача их драйверу железа, прием голых данных от железа и укладка в пакеты <сеть> --> маршрутизация (проверка сетевого адреса). <транспорт> --> укладка и выделение пользовательских данных в/из пакетов. сетевой уровень (который лежит между транспортом и каналом) можно взависимости от конкретного протокола, объединять или с транспортным или с канальным уровнем. В случае одноранговой сети Modbus его выгоднее объединить с канальным уровнем, в случае многоранговой IP сети - с транспортным.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 20:07
|
Guests

|
Цитата Я предлагаю снабдить слейв минимальным интеллектом, и работать блоками данных (накопленных, нормализованных и т.д. и т.п.), но не в реальном времени. Ну, а как быть с реальным временем? Цитата ... прогнозирование ветвлений? Но в этом случае речь идет только о загрузке конвейера, а никак не о забегающих вперед вычислениях. Да, действительно. О том, что команды из конвейеров могут выполняться не по порядку - ничего не сказано.
|
|
|
|
|
Nov 8 2009, 20:08
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(defunct @ Nov 9 2009, 00:51)  Не совсем, у Вас в описании просматривается часть характеристки канального уровня - проверка правильности принятых данных (по крайней мере четность). В некоторых UART есть возможность отсеивать неправильно принятые байты, при этом (ошибках приема) прерывания просто не будет. И хотя это не очень правильно, но возможно. Цитата(defunct @ Nov 9 2009, 00:51)  <физ уровень> --> сводится к драйверу железа или эмулятору железа (программый UART/ программный SPI) <канальный уровень> ---> разбиение пакетов на голые байты и передача их драйверу железа, прием голых данных от железа и укладка в пакеты <сеть> --> поиск и проверка маршрутов <транспорт> --> укладка и выделение пользовательских данных в/из пакетов. ОК. Достаточно. Я вас понял. Вы канальный уровень вешаете на прерывания. Я где-то раньше так тоже делал. Но в других проектах мне показалось это нецелесообразным.
|
|
|
|
|
Nov 8 2009, 20:20
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 8 2009, 23:07)  Ну, а как быть с реальным временем? А реальное время будет спокойно жить в слейве. Цитата(@Ark @ Nov 8 2009, 23:07)  Да, действительно. О том, что команды из конвейеров могут выполняться не по порядку - ничего не сказано. Ну, это вообще не из той оперы - выполняются они не по порядку как раз для того, чтобы не получить результат, который потом придется выбросить. Так что с "потом лишь выбирает нужный результат" вы несколько переборщили.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 20:38
|
Guests

|
Цитата А реальное время будет спокойно жить в слейве. Я опять не понял. Вы не могли бы излагать яснее. То есть Вы предлагаете передавать данные блоками, снабжая их метками реального времени, и с возможной неопределенной задержкой при передаче. Какая же это работа в реальном времени? Цитата Ну, это вообще не из той оперы - выполняются они не по порядку как раз для того, чтобы не получить результат, который потом придется выбросить. Так что с "потом лишь выбирает нужный результат" вы несколько переборщили. Почему же? Если уже обработаны и выполнены команды за ветвлением, тогда если ветвление не состоялось, эти результаты используются. А если "вдруг" состоялось, то что еще делать с результатами этих команд - только выбросить.
|
|
|
|
|
Nov 8 2009, 21:04
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 8 2009, 23:38)  Я опять не понял. Вы не могли бы излагать яснее. То есть Вы предлагаете передавать данные блоками, снабжая их метками реального времени, и с возможной неопределенной задержкой при передаче. Какая же это работа в реальном времени? Наверное, я не совсем удачно выразился. Под передачей "не в реальном времени", следует понимать лишь то обстоятельство, что данные будут получены с некоторой апертурной задержкой. Понятие работы в реальном времени при этом никак не пострадает. Цитата(@Ark @ Nov 8 2009, 23:38)  Почему же? Если уже обработаны и выполнены команды за ветвлением, тогда если ветвление не состоялось, эти результаты используются. А если "вдруг" состоялось, то что еще делать с результатами этих команд - только выбросить.  OMG! Да не выполняет их никто, естественно, в конвейер только грузят.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 21:24
|
Guests

|
Цитата ... что данные будут получены с некоторой апертурной задержкой. С какой? Это критичный параметр. В реальном времени задержка должна быть минимальна, насколько это позволяет канал и используемый протокол. В чем, в данном случае, преимущество блочной передачи, при прочих равных? Я ее не вижу. Цитата ... Да не выполняет их никто, естественно, в конвейер только грузят. В пентиумах - не только грузят в конвейер, но и декодируют, и выполняют (в непонятно каком порядке), по мере возможности и наличия свободных аппаратных ресурсов...
|
|
|
|
|
Nov 8 2009, 21:36
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 9 2009, 00:24)  С какой? Это критичный параметр. В реальном времени задержка должна быть минимальна, насколько это позволяет канал и используемый протокол. В чем, в данном случае, преимущество блочной передачи, при прочих равных? Я ее не вижу. Она должна быть не "минимальна, насколько это позволяет канал и используемый протокол", а лишь удовлетворять требованиям для нормального функционирования системы. Преимущество блочной передачи вполне очевидно - меньшее количество запросов-ответов на единицу передаваемых полезных данных. Цитата(@Ark @ Nov 9 2009, 00:24)  В пентиумах - не только грузят в конвейер, но и декодируют, и выполняют (в непонятно каком порядке), по мере возможности и наличия свободных аппаратных ресурсов... Да, а потом специальный "выпиливатель" удаляет результаты выполнения ненужных операций из регистров/памяти.
|
|
|
|
Guest_@Ark_*
|
Nov 8 2009, 21:51
|
Guests

|
Цитата Преимущество блочной передачи вполне очевидно - меньшее количество запросов-ответов на единицу передаваемых полезных данных. Здесь мы с Вами расходимся принципиально. Предпочтительнее минимальная возможная задержка от момента измерения до получения данных. И естественно, точно известное, фиксированное, значение этой задержки. А не поступление значений блоками с известными задержками. Хотя, здесь уже все зависит от задачи... Цитата Да, а потом специальный "выпиливатель" удаляет результаты выполнения ненужных операций из регистров/памяти. Примерно так.
|
|
|
|
|
Nov 8 2009, 22:17
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(@Ark @ Nov 9 2009, 00:51)  Здесь мы с Вами расходимся принципиально. Да, я все же не могу понять, зачем делать задержку меньше минимально достаточной. Ну да ладно. Цитата(@Ark @ Nov 9 2009, 00:51)  Примерно так. Не совсем: выполнить и безболезненно удалить результат выполнения можно только в очень ограниченном ряду случаев. На практике, как я понимаю, используется только для некоторых команд типа загрузки регистров, так что до полноценных вычислений и уж тем более записи результатов дело все равно не доходит.
|
|
|
|
|
Nov 8 2009, 23:12
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 8 2009, 22:08)  Вы канальный уровень вешаете на прерывания. Я где-то раньше так тоже делал. Но в других проектах мне показалось это нецелесообразным. Можно полюбопытствовать - почему? - Какие объективные причины подтолкнули к такому решению? (требования к латентности прерываний, особенность ОС, особенности аппаратуры)? Цитата(aaarrr @ Nov 9 2009, 00:17)  Да, я все же не могу понять, зачем делать задержку меньше минимально достаточной. Есть две разные задачи. 1. обеспечить Real-time - см. real-time protocol который с помощью меток времени и блочной передачи, вне зависимости от задержек канала и межпакетного джиттера, гарантирует real-time воспроизведение медиа потока. 2. обеспечить максимально возможный КПД использования канала. То о чем говорите Вы решает 1), то о чем говорит @Ark решает 2).
|
|
|
|
Guest_@Ark_*
|
Nov 9 2009, 11:09
|
Guests

|
Цитата Цитата(aaarrr @ Nov 9 2009, 00:17) Да, я все же не могу понять, зачем делать задержку меньше минимально достаточной. Цитата Цитата(defunct @ Nov 9 2009, 00:51) Есть две разные задачи... Да, с этим полностью согласен. Это совершенно разные задачи. Передача потока данных с метками реального времени, для его последующего анализа или воспроизведения, и прямое управление устройствами в режиме реального времени. В первом случае задержки не так важны, в пределах допустимого. А во втором - критичны, так как они определяют время реакции системы на внешние события. И добиваться минимальной задержки нужно, в частности, для того, чтобы оставить мастеру как можно больше времени для принятия решения. Поэтому, есть прямой смысл "выжать" из канала максимальный КПД (пусть даже вопреки "здравому смыслу"). Так как альтернатива этому - только использование более быстрых каналов, что, обычно, напрямую сказывается на стоимости системы. Цитата Цитата(aaarrr @ Nov 9 2009, 00:17) ... выполнить и безболезненно удалить результат выполнения можно только в очень ограниченном ряду случаев. На практике, как я понимаю, используется только для некоторых команд типа загрузки регистров, так что до полноценных вычислений и уж тем более записи результатов дело все равно не доходит. Доходит и до вычислений, и до записи. Основная идея современных процессоров - ничто не должно простаивать. Если в конвейере есть команда, которую можно выполнить заранее, и есть ресурсы - она будет выполнена. Даже если ее результат, возможно, не потребуется. До записи результатов в память - конечно не доходит, а в регистры... современные процессоры, по моему, давно не используют пересылки типа регистр-регистр, как неэффективные. Регистры просто переназначаются.
|
|
|
|
|
Nov 9 2009, 17:17
|

Местный
  
Группа: Свой
Сообщений: 213
Регистрация: 28-02-07
Из: Киев
Пользователь №: 25 744

|
Цитата(defunct @ Nov 8 2009, 02:09)  Стандарты порой устаревают. А сильно распространненные нарушения часто становятся частью страндарта. Грубых нарушений стандарта в упор не вижу, если CRC сошлась ложно, то пакет отбракуется по длине и прием продолжится. Данное нарушение пока не стало частью стандарта. И пока это является именно грубым нарушением. Вы никогда не получали совпадение CRC внутри пакета? Значит Вы не использовали ModBus в реальных проектах. Или Вам просто пока крупно везло. Или Вы предлагаете после получения совпадения CRC продолжать принимать пакет, параллельно пересчитывая CRC и убеждаясь (по другим признакам) что пакет битый, после чего ждать нового совпадения CRC? Цитата(defunct @ Nov 8 2009, 02:09)  С другой стороны, на кой в холостую ждать 3.5 символьных интервала (это ж вагон и еще маленькая тележка времени особенно на 9600 и ниже), когда их можно потратить с пользой, например на вычитку архива из медленного eeprom'а по текущему запросу мастера. "Вычитка" архива (да пусть хоть даже и запись) никакого отношения к процедуре обмена не имеет. Даже если вычитываются запрошенные данные, лучше не начинать "вычитку" не приняв до конца запрос. Полностью поддерживаю идеи, изложенные коллегой rezident: не нужно смешивать разные уровни обмена в одну кучу. Прерывание по приему/передаче байта должно быть максимально коротким (взять или положить в буфер и всё). Как в принципе и любое другое прерывание. Цитата(defunct @ Nov 8 2009, 02:09)  Может для "Копилки Вечности" у вас найдется способ отмерить таймаут в 1.75ms под Windows? Windows вообще никакого отношения к ModBus не имеет. Ну а если в качестве мастера у Вас выступает РС - никто не запрещает сделать интервал больше, чем 1,75 мсек. Приемлемые таймауты в единицы мсек отрабатываются нормально. Цитата(defunct) Есть две разные задачи. 1. обеспечить Real-time - см. real-time protocol который с помощью меток времени и блочной передачи, вне зависимости от задержек канала и межпакетного джиттера, гарантирует real-time воспроизведение медиа потока. 2. обеспечить максимально возможный КПД использования канала.
То о чем говорите Вы решает 1), то о чем говорит @Ark решает 2). Минимальное время реакции на прерывания по разным причинам приходится обеспечивать в большинстве достаточно крупных проектов. А вот понятия modbus и "максимально возможный КПД использования канала" - не вполне совместимы. Обычно modbus применяется там, где загрузка канала не очень высока. Иначе - нужно выбирать другой протокол, а (возможно) и другую "физику" (т.е. не 485)
|
|
|
|
|
Nov 10 2009, 03:21
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(koyodza @ Nov 9 2009, 19:17)  Или Вы предлагаете после получения совпадения CRC продолжать принимать пакет, параллельно пересчитывая CRC и убеждаясь (по другим признакам) что пакет битый, после чего ждать нового совпадения CRC? Да, я предлагаю делать так. До тех пор пока не прошел требуемый таймаут есть вероятность того, что произойдет ошибка (напр символ через 1.5 символьных интервала), поэтому переходить к приему сл. пакета нельзя, а раз нельзя то продолжаем принимать текущий. Цитата Данное нарушение пока не стало частью стандарта. И пока это является именно грубым нарушением. Нет никакого нарушения стандарта, тем более грубого: Код 1. При совпадении CRC текущего пакета background task создает копию принимаемого пакета, и записывает перекресную ссылку (друг на друга) в текщий пакет и его копию, а также взводит callback c таймаутом на отправку копии пакета. 2. background task приступает к формированию ответа на запрос незамедлительно, ответ на запрос формируется в этой же копии пакета. 3. Взависимости от того что наступит раньше - вызов callback'а по таймауту или прием символа по уарту:
a. вызов callback'а наступает раньше. - удаляется перекресная ссылка из пакета и копии пакета (т.е. копия отвязывается от приемника) - приемник (оригинал пакета) обнуляется - переход к приему нового пакета - проверяется полностью ли сформирован ответ на запрос: если ответ сформирован, тогда он нативно отправляется ровно через указанный в стандарте минимальный межпакетный интервал (в 99% случаев имеет место именно этот случай). - если ответ еще не сформирован - повторно взводится callback с таймаутом в одно-символьный интервал. b. eсли раньше примется символ, прошло не более 1.5 символьного интервала от последнего принятого символа, копия помечается как бракованая (при вызове callback'a удалится автоматически), а символ добаляется к текущему пакету и подсчет CRC продолжается. с. если раньше примется символ, но 1.5 символьный таймаут уже пройден - копия пакета помечается как бракованая и оригинальный пакет обнуляется. Собсно вот так у меня реализовано, алгоритм ниоткуда не слизанный, просто устройств в сети много, и опрашиваются непрерывно. Эти 1-2% КПД канала это +1..2 устройства в сети без ухудшения характеристик всей системы. Цитата Вычитка" архива (да пусть хоть даже и запись) никакого отношения к процедуре обмена не имеет. Даже если вычитываются запрошенные данные, лучше не начинать "вычитку" не приняв до конца запрос. Расскажите это мастеру который хочет прочитать данные со слейва которые лежат в i2c eeprom'е. Если быть точнее - расскажете мастеру почему ответ на его запрос появляется не через 3.5 символьных интервала, а через 7 (4-5ms - среднее время i2c транзакции). Цитата Минимальное время реакции на прерывания по разным причинам приходится обеспечивать в большинстве достаточно крупных проектов. А вот понятия modbus и "максимально возможный КПД использования канала" - не вполне совместимы. Обычно modbus применяется там, где загрузка канала не очень высока. Иначе - нужно выбирать другой протокол, а (возможно) и другую "физику" (т.е. не 485) Я считаю, гоняться за наносекундами в обработчиках прерываний - нет смысла. Что 32 регистра в стек будет сохраняться что 1, какая разница? это вопрос микросекунды. А если что-то совсем совсем критичное ко времени реакции - проще поставить плиску или какой-нибудь мелкий МК в помощь, чем лишать себя свободы в обработчиках прерываний. Тобиш минимальное время реакции это удел мелких проектов. В крупных проектах бывает удобно уменьшать число прерываний как таковых за счет пакетной обработки нескольких прерываний от нескольких периферийных модулей за один заход. Реакция возрастает, но накладные расходы на вход-выход в обработчик снижаются пропорционально количеству обработанных за один заход прерываний. А вот там где счет идет на миллисекунды, предпочитаю их не терять. Максимальный КПД канала он к любому протоколу применим, в т.ч. и к Модбас, т.к. в нем минимальное время между пакетами оговоренно стандартом, вот к нему надо стремиться. Да и на 485-м можно иметь вполне причную скорость ~2Mbps.
|
|
|
|
|
Nov 10 2009, 05:00
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(koyodza @ Nov 9 2009, 19:17)  Полностью поддерживаю идеи, изложенные коллегой rezident: не нужно смешивать разные уровни обмена в одну кучу. Прерывание по приему/передаче байта должно быть максимально коротким (взять или положить в буфер и всё). Как в принципе и любое другое прерывание. Разные уровни обмена не нужно смешивать разумеется. Только вот идеи на которые Вы ссылаетесь примерно такого плана: а давайте чтобы сократить время реакции прерывания разобъем канальный уровень на два подуровня, первый подуровень канального уровня будем обслуживать в прерывании, а второй - постобработкой. Ничего что для этого придется обзавестись большим буфером памяти, зато реакция на прерывание будет быстрой. И ради чего? Разница ведь в нано-, микро- секундах исчисляется. Снижаем реакцию на прерывание просто ради получения минимальной реакции?! Дык с тем же успехом можете просто разрешить другие прерывания в обработчике текущего, реакция будет еще быстрее. Ethernet MAC - пример канального уровня, выдает пакеты, а не байты которые надо собирать в пакеты. И выдает прерывания "пакет" принят а не байт принят. Так вот объясните мне доходчиво если можно, почему модель программиста канального уровня Ethernet должна отличаться от модели канального уровня PPP или того же Modbus? И зачем делать двойную работу? Зачем накапливать в памяти что-то непотребное, - escaped chars, пакеты нам не адресованые, метки времени на каждый принятый символ для определения таймаутов, и прочее г. которое можно отсеяться сразу в прерывании.
|
|
|
|
|
Nov 10 2009, 07:06
|
Местный
  
Группа: Участник
Сообщений: 315
Регистрация: 5-05-08
Из: Kursk
Пользователь №: 37 282

|
Цитата(defunct @ Nov 10 2009, 08:00)  Зачем накапливать в памяти что-то непотребное, - escaped chars, пакеты нам не адресованые, метки времени на каждый принятый символ для определения таймаутов, и прочее г. которое можно отсеяться сразу в прерывании. Совершенно согласен по началу принятия пакета проверяете адрес ежли это не ваше ,то просто проверяете CRC в буфере приёма,и только если CRC не правильная или ставите флаг и обрабатываете в обработчике ошибки, либо сразу выходите из прерывания с подменой стека со смещением стека на обработчик соответствующий ошибке и соответственно надолго в прерывании не задерживаетесь. Данным образом реализовал мастер модбус на 51 ядре с буфером приёма-передачи в 128байт интервалы пакетов контролируются в прерываниях по таймеру и по UART.
--------------------
"Если я в чем-то сомневаюсь, я возвращаюсь к началу"
|
|
|
|
|
Nov 10 2009, 11:41
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(defunct @ Nov 10 2009, 10:00)  Ничего что для этого придется обзавестись большим буфером памяти, зато реакция на прерывание будет быстрой. И ради чего? Разница ведь в нано-, микро- секундах исчисляется. Снижаем реакцию на прерывание просто ради получения минимальной реакции?! Дык с тем же успехом можете просто разрешить другие прерывания в обработчике текущего, реакция будет еще быстрее. Я же написал для чего это мне нужно было. Да, для этого требуется буфер на максимальную длину пакета. Но точно такой же буфер требуется и для формирования ответа, если запрошены данные максимального размера. Так что размер буфера тут рояли не играет. Ловить микросекунды по связи у меня не было задачи. Во-первых, связь была малоприоритетным фоновым процессом. Во-вторых, в реализации протокола были сразу заложены настраиваемые задержки и таймауты ожидания выдачи ответа. Так что и сверхбыстрый ответ по связи не играл никакой роли. В-третьих, я уже ответил, что не отвергаю ваших доводов по поводу реализации канального уровня, но всякому сверчку свой шесток. Я не вижу необходимости свербыстродействующей реакции на запрос мастером журнальной записи. Для измерительных же целей целесообразность выбора modbus как протокола связи уже обсудили, повторяться не стоит.
|
|
|
|
|
Nov 15 2009, 01:53
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
На досуге я тут кое-что обдумывал и вернулся вот к этой части сообщения Цитата(defunct @ Nov 10 2009, 10:00)  Разные уровни обмена не нужно смешивать разумеется. Только вот идеи на которые Вы ссылаетесь примерно такого плана: а давайте чтобы сократить время реакции прерывания разобъем канальный уровень на два подуровня, первый подуровень канального уровня будем обслуживать в прерывании, а второй - постобработкой. Ничего что для этого придется обзавестись большим буфером памяти, зато реакция на прерывание будет быстрой. И ради чего? Разница ведь в нано-, микро- секундах исчисляется. Снижаем реакцию на прерывание просто ради получения минимальной реакции?! Дык с тем же успехом можете просто разрешить другие прерывания в обработчике текущего, реакция будет еще быстрее. defunct, поясните, пожалуйста, как вы обеспечиваете реентерабельность вашей функции канального уровня, описанной в посте #44? То бишь в каком там месте можно поставить оператор, разрешающий вложенные прерывания? Моя ИМХА почему-то упорно мне доказывает, что это прерывание (от UART) делать вложенным нельзя, если только заранее неизвестно, что сумма всех возможных вложенных прерываний не превысит величины символьного интервала для максимальной скорости передачи (т.е., например, скорость передачи достаточно низкая).
|
|
|
|
|
Nov 15 2009, 02:49
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 15 2009, 03:53)  defunct, поясните, пожалуйста, как вы обеспечиваете реентерабельность вашей функции канального уровня, описанной в посте #44? То бишь в каком там месте можно поставить оператор, разрешающий вложенные прерывания? Теоретически можно в любом месте до запуска функции-обработчика канального уровня. Конкретное положение зависит от требований к латентности в конкретной системе, для обеспечения минимальной латентности - целесообразно - в asm обертке (до сохранения всей кучи регистров в стек). Если минимальная латентность не обязательна - то сразу после вычитки данных из UART регистра. Цитата Моя ИМХА почему-то упорно мне доказывает, что это прерывание (от UART) делать вложенным нельзя, Ваша ИМХА верна, само прерывание "байт принят" просто сделать вложенным нельзя. Необходимо либо перед тем как разрешать все остальные, - замаскировать текущее, либо - см. ниже. Цитата если только заранее неизвестно, что сумма всех возможных вложенных прерываний не превысит величины символьного интервала для максимальной скорости передачи (т.е., например, скорость передачи достаточно низкая). Справедливо если UART буферизирует только 1 символ. Но если UART обладает RX FIFO (16550 и подобные) требования к интервалу снижаются в FIFO size раз. Это FIFO можно организовать и программно (и оно потребует куда меньше памяти чем толстый приемный буфер обрабатываемый в background) Код __interrupt RxHandler(void) { static int write_index = 0; static int read_index = 0; static char lock = 0; static char fifo_buf[ сумма всех прерываний / символьный интервал ];
fifo_buf[ write_index++ ] = UART_RX_REG; if (write_index >= sizeof( fifo_buf)) write_index = 0;
if (lock) return; else lock = 1; // здесь можем разрешать вложенные прерывания включая текущее __enable_interrupt(); while (read_index != write_index) { rx_cb( fifo_buf[ read_index++ ]) ... } lock = 0; }
|
|
|
|
|
Nov 15 2009, 03:22
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 15 2009, 05:19)  Считайте, что у меня реализован программный буфер FIFO. Только память, выделяемая под него, не только канальным уровнем используется, но и уровнем приложения.  Только объем буфера в десятки-сотни раз больший требуется, чем величина fifo. Цитата Для сокращения расхода RAM и потому, что ответов с микросекундной задержкой не требуется по условиям моего задания. Где ж тут сокращение расхода RAM? Когда наоборот. У меня командная консолько и та разбита на канальный уровень, на канальном уровне обслуживаются CR, LF, UP, DOWN, CTRL-H, CTRL-C, CTRL-... служебные символы. Самой консольке же идут только осмысленные команды. Требования к буферу - строго детерминированны макс длиной команды, а если просто складывать все принятое подряд какой размер буфера брать?..
|
|
|
|
|
Nov 15 2009, 04:10
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 15 2009, 05:59)  Это ваша схема выходит, а не моя. Да ну, я то как раз за то, чтобы выделять пакеты адресованные слейву в прерывании. или все-таки сетевые адреса и таймауты у вас обслуживаются в прерывании? Тогда Вы противоречите сами себе. Цитата Зачем 2*256? Если не распознавать адрес и не обслуживать таймаут в прерывании. То как Вы определяете, когда прекращать прием? Цитата Пока уровень приложения обрабатывает запрос, переданный ему с канального уровня, прием вообще запрещен. Не вопрос пусть так, но ведь в RX прерывании складываете все подряд, в т.ч. пакеты адресованные другому слейву и ответы других слейвов. Цитата По истечение времени, выделенного уровню приложения на обработку запроса, если ответ еще не готов, то автоматически формируется типовой ответ "BUSY". Для него большого буфера не нужно. Это же TX буфер, а мы вроде как про RX...
|
|
|
|
|
Nov 15 2009, 18:15
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(defunct @ Nov 15 2009, 09:10)  Да ну, я то как раз за то, чтобы выделять пакеты адресованные слейву в прерывании. или все-таки сетевые адреса и таймауты у вас обслуживаются в прерывании? Тогда Вы противоречите сами себе. В прерывании. Только не в UARTовом, а в таймерном. Например, 1мс-ном или 1-секундном. Не принципиально. Зависит от требуемой точности определения паузы. Цитата(defunct @ Nov 15 2009, 09:10)  Если не распознавать адрес и не обслуживать таймаут в прерывании. То как Вы определяете, когда прекращать прием? Если в RTU, то как только между двумя (или большим кол-вом, в зависимости от требуемой длительности паузы) 1мс-ыми прерываниями буфер перестал пополняться, то значит нужно считать CRC и при совпадении можно передавать указатель на начало фрейма в буфере на уровень приложения. Если другой формат. то ищутся маркеры начала/конца фрейма в буфере. И адресация тоже определяется нормально. Если адрес был получен не свой, то в таймерном прерывании буфер каждый раз очищается до тех пор, пока не обнаружится начало следующего фрейма. Цитата(defunct @ Nov 15 2009, 09:10)  Не вопрос пусть так, но ведь в RX прерывании складываете все подряд, в т.ч. пакеты адресованные другому слейву и ответы других слейвов. Нет. Зачем мне пакеты, адресованные другому слейву, если только у меня не организовано маркерное кольцо для доступа к шине? Цитата(defunct @ Nov 15 2009, 09:10)  Это же TX буфер, а мы вроде как про RX... При формате обмена запрос-ответ второй буфер не нужен. Слейв не будет обрабатывать второй и последующий запросы до тех пор, пока не готов ответ на первый или выделенное ему для формирования ответа время не вышло. И еще вопрос-уточнение. А как вы обеспечиваете атомарность при проверке условия Код while (read_index != write_index) ? Ведь если атомарность не будет обеспечена, то последний байт, попавший в буфер в прерывании, может быть пропущен функцией обработки канального уровня.
|
|
|
|
|
Nov 15 2009, 22:27
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 15 2009, 20:15)  Нет. Зачем мне пакеты, адресованные другому слейву, если только у меня не организовано маркерное кольцо для доступа к шине? Но вы же их принимаете и складываете их данные в буфер... Анализируете свой-чужой - уже в приложении. Цитата При формате обмена запрос-ответ второй буфер не нужен. Слейв не будет обрабатывать второй и последующий запросы до тех пор, пока не готов ответ на первый или выделенное ему для формирования ответа время не вышло. Т.е. отдельный TX буфер не нужен? А куда будем складывать отложенный ответ (тот который формируется, в момент когда уже шлется busy)? После отправки busy, не будем ждать еще одного запроса мастера, чтобы отдать сформированный ответ? Цитата И еще вопрос-уточнение. А как вы обеспечиваете атомарность при проверке условия Код while (read_index != write_index) ? Ведь если атомарность не будет обеспечена, то последний байт, попавший в буфер в прерывании, может быть пропущен функцией обработки канального уровня. Не пропушен (пропущен - это равнозначно потерян), а отложен до следующего прерывания! Да в приведенном варианте есть проблема последнего символа, но она тоже решается, например, запретом прерываний перед очередной проверкой индексов: Код while (read_index != write_index) { __enable_interrupt(); rx_cb( fifo_buf[ read_index++ ]) ... __disable_interrupt(); } ... Можно и другим путем. Вот что более интересно, а вам не кажется, что: Цитата если только заранее неизвестно, что сумма всех возможных вложенных прерываний не превысит величины символьного интервала для максимальной скорости передачи (т.е., например, скорость передачи достаточно низкая). относится и к обычному (невложенному обработчику) в точно такой же мере? Приоритет прерывания UART'а в системе как правило далеко не самый высокий, т.о. необходимо чтобы сумма всех возможных и более приоритетных прерываний не превышала символьного интервала для макс скорости передачи, что есть практически одно и тоже с суммой всех возможных вложенных прерываний.
|
|
|
|
|
Nov 15 2009, 22:50
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(defunct @ Nov 16 2009, 03:27)  Но вы же их принимаете и складываете их данные в буфер... Анализируете свой-чужой - уже в приложении. Нет. Анализ уже во втором слое канального уровня, как вы его охарактеризовали, происходит. Та функция которая в 1мс прерывании вызывается и работает с буфером UART. Цитата(defunct @ Nov 16 2009, 03:27)  Т.е. отдельный TX буфер не нужен? А куда будем складывать отложенный ответ (тот который формируется, в момент когда уже шлется busy)? Дык в тот же буфер. Или в другой. Маленький, но отдельный. Цитата(defunct @ Nov 16 2009, 03:27)  После отправки busy, не будем ждать еще одного запроса мастера, чтобы отдать сформированный ответ? В такой реализации - нет, не будем. Если предусматривать такую возможность, то нужны раздельные буферы, как вы и предлагали. Цитата(defunct @ Nov 16 2009, 03:27)  Да в приведенном варианте есть проблема последнего символа, но она тоже решается, например, запретом прерываний перед очередной проверкой индексов: Вот. Все-таки не так все просто, как вы вначале описали.  Цитата(defunct @ Nov 16 2009, 03:27)  Вот что более интересно, а вам не кажется, что:
относится и к обычному (невложенному обработчику) в точно такой же мере? К которому именно обработчику? Если к тому, который таймерный, то я там такую же фишку с обходом вызова функции применяю. Почему вам можно, а мне нельзя? И еще. У меня точно также как и у вас канальный уровень абстрагирован от железа. Но в HAL я уложил еще и буфер UART и атомарность доступа к буферу я обеспечиваю там же - в функции работы с буфером UART. При этом решается проблема как с наличием аппаратного FIFO, так и с "отложенными" байтами. P.S. на всякий случай напомню с чего началась дискуссия и ваши возражения. Цитата(rezident @ Nov 8 2009, 07:32)  Ради справедливости хотелось бы заметить, что не всегда есть возможность разбирать пакет "на лету" по причине многоуровневой организации связи.
|
|
|
|
|
Nov 15 2009, 23:08
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 16 2009, 00:50)  Нет. Анализ уже во втором слое канального уровня, как вы его охарактеризовали, происходит. Та функция которая в 1мс прерывании вызывается и работает с буфером UART. Понял. Применительно к modbus-slave я тоже так делал (выделял пакет в обработчике таймера). Но потом отказался от этого пути, потому что один уровень получается размазанным по нескольким обработчикам. И что самое печальное не все протоколы можно эффективно втиснуть в такую модель. Потом получается сложнее портировать код между МК. Цитата Вот. Все-таки не так все просто, как вы вначале описали.  Ну а в чем сложность? Сорри допустил ошибку вчера (еще забыл static переменные объявить как volatile), - каюсь  Но код же ж не стал после исправления ошибки, много сложнее? И эффективность ведь не потерялась. Цитата К которому именно обработчику? К обработчику UART'а разумеется. Цитата Если к тому, который таймерный, то я там такую же фишку с обходом вызова функции применяю. Почему вам можно, а мне нельзя? Функция в таймере которая обрабатывает весь пакет - у вас много сложнее моей, обслуживающей строго 1 символ. Поэтому если Вы выделяете целый пакет из кучи принятых байт, вам не то что можно-нельзя, а просто необходимо поступать так и только так, т.к. время выполнения функции будет диким! А вот мне можно и обойтись без вложенности вовсе. Ну а вторая причина - вы про таймер не рассказывали. Я думал у вас обработка делается в аппликейшн. Цитата P.S. на всякий случай напомню с чего началась дискуссия и ваши возражения. Да да, я помню. По прежнему стою на том, что выделять пакеты удобнее всего в обработчике посимвольного приема, т.к. это упрощает разбивку и снижает расход памяти.
|
|
|
|
|
Nov 16 2009, 00:20
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(defunct @ Nov 16 2009, 04:08)  Функция в таймере которая обрабатывает весь пакет - у вас много сложнее моей, обслуживающей строго 1 символ. Поэтому если Вы выделяете целый пакет из кучи принятых байт, вам не то что можно-нельзя, а просто необходимо поступать так и только так, т.к. время выполнения функции будет диким! А вот мне можно и обойтись без вложенности вовсе. Ничуть не сложнее. Обработка зависит от темпа поступления данных. Если темп такой же как частота вызова таймерного прерывания, то также посимвольно получится. Почему нельзя обойтись без вложенности я уже писал. Цитата(defunct @ Nov 16 2009, 04:08)  Да да, я помню. По прежнему стою на том, что выделять пакеты удобнее всего в обработчике посимвольного приема, т.к. это упрощает разбивку и снижает расход памяти. С вашего разрешения по второму кругу дискуссию пускать не буду
|
|
|
|
|
Nov 16 2009, 00:33
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Nov 16 2009, 02:20)  Ничуть не сложнее. Обработка зависит от темпа поступления данных. Если темп такой же как частота вызова таймерного прерывания, то также посимвольно получится. Почему нельзя обойтись без вложенности я уже писал. темп будет ведь не такой (для 115200 к примеру темп у вас 1:10), потому и нельзя получается. Цитата P.S. на всякий случай напомню с чего началась дискуссия и ваши возражения. Цитата (rezident @ Nov 8 2009, 07:32) Ради справедливости хотелось бы заметить, что не всегда есть возможность разбирать пакет "на лету" по причине многоуровневой организации связи. Уточно, что "на лету" я предлагаю не разбирать, а выделять пакет из in-stream'a. Разбирать пакет должен следующий уровень работающий в app thread'е.
|
|
|
|
|
Dec 9 2009, 15:43
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(defunct @ Dec 8 2009, 23:45)  В AMD вообще есть такой? Есть. Ещё на семпроне пробовал. Попробуйте сами. Код #include <windows.h> ... bool TPerformanceCounter::Init() { LARGE_INTEGER Cnt;
if (QueryPerformanceFrequency(&Cnt)) { ... return (1); } return (0); }
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|