AlexandrY 3 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 48 minutes ago, syoma said: либо будет принято всеми активными узлами в сети, либо не будет принято ни одним из них. Здесь ошибка. Мы можем знать что принял хотя бы один, но не все. Т.е. нет никаких средств на физическом уровне чтобы убедится в приеме пакета именно всеми. Но есть бит запроса на передачу, который вызывает автоматом ответ слэйвов. Мастер пожет посылать пакеты с таким битом и должен принять все подтверждения. Вот это вызовет флуд. Т.е. в CAN-е нет широкополосных передач с гарантированной доставкой. Новизна в идеологии CAN - это независимые каналы peer-to-peer. А схема "издатель-подписчик" для CAN-а не годится поскольку на самом деле ее надо называть "издатели-подписчики", и это вызовет в CAN-е флуд. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей Васильевич 0 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 2 часа назад, HardEgor сказал: Элементарно - посылаешь запрос и получаешь ответ :) Зависит от скорости интерфейса Посылаешь 1000 запросов и получаешь один ответ через 30 секунд у лучшем случае, при условии что слейв не задерживает а просто тратит время на чтение и ответ. Теоретически CAN будет в сотни раз быстрее работать в сравнение с предложной вами схемой. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 15 minutes ago, AlexandrY said: Мы можем знать что принял хотя бы один, но не все. Т.е. нет никаких средств на физическом уровне чтобы убедится в приеме пакета именно всеми. Если хотя бы один из узлов по какой-либо причине не распознает CAN фрейм, он забивает шину активной ошибкой и тогда остальные узлы тоже отбрасывают этот фрейм, даже если для них он выглядит нормальным. То есть единственный вариант, когда какой-то узел не принял фрейм, в то время, как остальные его приняли, это если он вообще полностью не видел данный фрейм. Не? Quote Но есть бит запроса на передачу, который вызывает автоматом ответ слэйвов. Мастер пожет посылать пакеты с таким битом и должен принять все подтверждения. Вот это вызовет флуд. RTR? Не него вроде отвечают автоматом только те, у кого идентификатор совпадает с этим фреймом. Т.е. далеко не все. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей Васильевич 0 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба Доставка "всегда" даже при плохой связи через трансиверы ? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 2 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба Вот, кстати, проблема с распознаванием отсутствия слушателей на линии — большое препятствие в использовании активных CAN-шлюзов (которые внутри себя данные буферизуют и отправляют). Я так и не придумал, как по-простому эту проблему решить... Ведь наличие шлюза на шине означает, что всегда будет хотя бы один читатель. Разве что выдумывать в протоколе "широковещательные" сообщения на определенный ID, чтобы нужные слейвы отвечали… Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 83 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 22 минуты назад, Алексей Васильевич сказал: Посылаешь 1000 запросов и получаешь один ответ через 30 секунд у лучшем случае, при условии что слейв не задерживает а просто тратит время на чтение и ответ. Что-то у вас не так. 1000 запросов - это по одному запросу в один slave? Какая у вас скорость? На 9600 тысяча 2-байтовых пакетов запроса с защитным интервалом 1мс улетят за несколько секунд, но не 30-же. Но если вам надо опросить всех, то для этого делается групповая команда, которую принимают и начинают обрабатывать все слейвы. А ответы начинают последовательно поступать по факту освобождения линии. Надеетесь что в CAN другая модуляция? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 2 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 36 minutes ago, HardEgor said: Но если вам надо опросить всех, то для этого делается групповая команда, которую принимают и начинают обрабатывать все слейвы. А ответы начинают последовательно поступать по факту освобождения линии. Не факт, у меня так на STM32F042 сделать не получилось: что-то я накриворучил, и если одновременно пять "слейвов" шлют данные, то от трех-четырех запросто пакеты теряются (у меня нет подтверждения приема в протоколе - если надо, "мастер" просто еще раз "слейв" опросит). Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 9 часов назад, Алексей Васильевич сказал: Перед тем как отправить пакет в DMA создаю команду на прием пакета ЗАДАННОЙ длинны, калбек отправки переключает драйвер на прием. Если пакет ответа будет короче , калбек приема не отработает , опрос на время остановится, а сама ошибка будет обработана в отбельном потоке, таких ошибок может быть десятки в секунду падает скорость обмена. Ну вот, как я и подозревал - у Вас неправильная архитектура ПО. Во-первых: нужно завершать RX-DMA-транзакцию не только по размеру, но и по таймауту. Во-вторых: мухи - отдельно, котлеты - отдельно прикладные кадры данных - отдельно, блоки байтов принимаемые из UART - отдельно. Здесь на форуме уже не раз обсуждалась эта тема. Воспользуйтесь поиском. 9 часов назад, Алексей Васильевич сказал: - В одном потоке главного цикла невозможно параллельно подключить LAN, а работа основной программы останавливает опрос, - В нескольких потоках с равным приоритетом скорость обмена падает в 3 раза - В нескольких потоках с приоритетом обмена , не работает USB и LAN , обновление экрана и клавиатура отвечает с задержкой в несколько секунд. Это не "невозможно", это Вы не смогли. Всё это возможно. Но лучше использовать РТОС, а не суперцикл. 5 часов назад, syoma сказал: Чисто физически 1000 CAN трансиверов на одну сеть не повесить, поэтому нужны репитеры, которые бы разделяли сети на сегменты. Тогда можно и скорость повысить А как в этом случае получать подтверждения (ACK-и) от слэйвов? Через цепочку репитеров. 3 часа назад, HardEgor сказал: Да, еще приличную задержку может добавить гальваноразвязка с обеих концов. Ну кто-ж мешает использовать ADUM-ы и избежать задержки? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 83 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 31 минуту назад, Eddy_Em сказал: Не факт, у меня так на STM32F042 сделать не получилось: что-то я накриворучил, и если одновременно пять "слейвов" шлют данные, то от трех-четырех запросто пакеты теряются (у меня нет подтверждения приема в протоколе - если надо, "мастер" просто еще раз "слейв" опросит). Зачем одновременно? Есть адрес устройства ADDR , в самом простом случае, при одинаковом размере пакета Nbit, вычисляйте задержку начала передачи каждого устройства: (ADDR-1) + 1000*Nbit/speed, ms 28 минут назад, jcxz сказал: Это не "невозможно", это Вы не смогли. Всё это возможно. Но лучше использовать РТОС, а не суперцикл. Да там всё неправильно - один мастер на всех, и тот совсем слабый... Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 2 часа назад, syoma сказал: Тогда задержка будет в идеале 0.0с и зависеть только от загрузки сети. Не будет такого никогда. Так как CAN пока не работает на сверхсветовых скоростях. А так как у ТС линия ==2 км, значит нужно как минимум ~7мкс чтобы сигнал успел распространиться по линии. Это не считая ёмкости/индуктивности линии и задержек на мостах между сегментами (если такие есть). А для возможности работы механизма разрешения коллизий, нужно чтобы время распространения по всей линии (включая все межсегментные мосты) было многократно меньше длительности бита. И для того чтобы правильно выбрать точку сэмплирования бита CAN (о которой тут выше уже писали) так, чтобы в любом узле эта точка была правильной, и её положение не зависело от расстояния до передатчика - тоже нужно, чтобы длительность бита была многократно больше времени распространения сигнала по всей линии. И тогда получаем для расстояния 2км максимальную скорость около 20кбит/с. А с репитерами - ещё меньше. А у ТС сейчас RS-485 на 57600 кбод работает вроде как. И ему ещё мало. С CAN будет меньше. 2 часа назад, syoma сказал: Механизм Ack в CAN гарантирует, что конкретное сообщение либо будет принято всеми активными узлами в сети, либо не будет принято ни одним из них. Не гарантирует. ACK выставляется приёмником доминантным уровнем. А значит достаточно одному приёмнику его увидеть, он выставит доминанту, а какой-то из узлов может его не принять (из-за помехи за репитером в его сегменте) и пусть он сколько угодно выставляет рецессивный уровень - передатчик ACK всё равно получит. 1 час назад, Алексей Васильевич сказал: Посылаешь 1000 запросов и получаешь один ответ через 30 секунд у лучшем случае Значит ищите баги в своём коде. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 1 час назад, syoma сказал: Если хотя бы один из узлов по какой-либо причине не распознает CAN фрейм, он забивает шину активной ошибкой и тогда остальные узлы тоже отбрасывают этот фрейм, даже если для них он выглядит нормальным. С чего это? Читаем описание CAN на википедии: Контрольная сумма: передатчик вычисляет её и добавляет в передаваемый кадр, приёмник считает контрольную сумму принимаемого кадра в реальном времени (одновременно с передатчиком), сравнивает с суммой в самом кадре и в случае совпадения передаёт доминантный бит в промежутке подтверждения. Т.е. - если КС не совпала - просто узел не выставит ACK (оставит рецессив). А более близкий узел, который не словил эту помеху - выставит доминантный ACK. А значит передатчик получит ACK. "Активная ошибка" вообще для другого назначения используется. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 29 minutes ago, jcxz said: Не будет такого никогда. Ну запишите 0.01с. Хватит? Quote Т.е. - если КС не совпала - просто узел не выставит ACK (оставит рецессив). Это верно. Но для дальнейших действий может лучше почитаем CAN спецификацию? Quote 6.2 Error Signalling A station detecting an error condition signals this by transmitting an ERROR FLAG. For an ’error active’ node it is an ACTIVE ERROR FLAG, for an ’error passive’ node it is a PASSIVE ERROR FLAG. Whenever a BIT ERROR, a STUFF ERROR, a FORM ERROR or an ACKNOWLEDGMENT ERROR is detected by any station, transmission of an ERROR FLAG is started at the respective station at the next bit.Whenever a CRC ERROR is detected, transmission of an ERROR FLAG starts at the bit following the ACK DELIMITER, unless an ERROR FLAG for another condition has already been started. Я тоже неправильно сказал - это не часть механизма ACK, а на один бит после него. И чтобы потом не говорили, что после ACK сообщение считается принятым. Нет не считается: Quote Receivers:The message is valid for the receivers, if there is no error until the last but one bit of END OF FRAME А ACTIVE ERROR FLAG после ACK этот END OF FRAME еффективно уничтожает. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 36 минут назад, HardEgor сказал: Зачем одновременно? Есть адрес устройства ADDR , в самом простом случае, при одинаковом размере пакета Nbit, вычисляйте задержку начала передачи каждого устройства: (ADDR-1) + 1000*Nbit/speed, ms Чтобы убрать влияние времени обработки пакета, я бы сделал немного по-другому: 1. Мастер отправляет всем кадры, которые нужно (до 1000-ти кадров). Ни один слэйв не отправляет ответ, а если хочет ответить, то просто формирует ответ в своём внутреннем буфере передачи (нозовём это кадром статуса). 2. После отправки последнего кадра, мастер отправляет спец. кадр запроса кадра статуса с нужного узла. Запрашиваемый узел сразу стартует передачу заранее подготовленного кадра статуса из буфера. "Сразу" - это означает: после приёма последнего стоп-бита последнего байта кадра запроса от мастера, слэйв запускает таймер задержки переключения ПРИЁМ-ПЕРЕДАЧА. За время этой задержки мастер и слэйв переключают свои драйверы линии, первый - из передачи в приём, второй - из приёма в передачу. После завершения задержки - слэйв передаёт кадр статуса. Естественно, если в пачке кадров от мастера к слэйву, время прошедшее от момента конца кадра запроса к какому-то слэйву меньше, чем максимальное время обработки данных этим слэйвом, то мастер должен вставить дополнительную задержку перед запросом статуса этого слэйва. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 83 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 1 час назад, jcxz сказал: Чтобы убрать влияние времени обработки пакета, я бы сделал немного по-другому: Схема понятна. Автору его 1000 устройств надо бить на подсети - на каждые 50 приборов ставить свой мастер и все проблемы сразу и безоговорочно уйдут. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 14 января, 2020 Опубликовано 14 января, 2020 · Жалоба 3 hours ago, syoma said: Ну запишите 0.01с. Хватит? Это верно. Но для дальнейших действий может лучше почитаем CAN спецификацию? Эт конечно уместное замечание, про генерацию флагов ошибки на шине. Как-то я даже не обращал внимания раньше на такую фичу, больше заботили программные ошибки когда узлы не отвечают из-за своего софта. Но создатели CAN видимо не брали в расчет ошибки софта считая что в их сети работают заведомо надежные дивайсы. С этой точки зрения, да, если дивайсы не протестированы на все 100%, то CAN как бы идеологически неверный выбор. С другой стороны как флаг ошибки передать через роутер в CAN-е? Тогда значит роутеры не получатся, а надо делать то что я назвал бы доменные контроллеры или coupler-ы как это называется у производителей PLC. Я б сразу делал EtherCAT. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться