В электронике есть множество проводных полудуплексных асинхронных последовательных интерфейсов типа общая шина. Это 1-Wire, RS485, 10BASE2(thin Ethernet), LIN, K-Line , CAN, I2C, MIL-STD-1553, ARINC 429.
Во всех этих shared-bus интерфейсах так или иначе возникает задача сканирования шины.
Всем кто работал с i2c известна процедура сканирования шины. Там можно просто методом перебора просканировать шину. Так как длина адреса всего 7 бит, то можно просканировать шину просто за пару секунд.
В CAN задачи сканирования вообще не стоит так как там коллизии разруливаются на аппаратном уровне физических трансиверов или вовсе MAC периферии. В CAN достаточно подключится в любом месте и через мгновение в утилите CAN-Hacker будет понятно кто там живет на шине CAN. В CAN все ноды постоянно flood(дят) «Hello!» пакетами.
В Lin сеть узлов обычно полностью 100% статическая и прошивается во время производства. Это и понятно, ведь в автомобильной двери во время езды не появится новая кнопка. В салоне автобуса по маршруту не вырастет новый поручень с кнопкой остановки.
Как обстоят дела со сканированием в остальных проводных интерфейсах: 1-Wire, 10BASE2(thin Ethernet), K-Line, MIL-STD-1553, ARINC 429 я, честно, не знаю. Если кто в теме, то напишите, пожалуйста, в комментариях.
Как обычно выглядит сеть RS485?
В чем трудность сканирования шины RS485?
1—Трудность в том что адреса устройств RS485 имеют существенно более высокую разрядность, как правило это 32 бита (4байта) или MAC адреса по 48бит (6 байт). Предположим узлы на шине RS485 имеют 32битный адрес и если сканировать шину RS485 как в I2C то китайский калькулятор покажет что надо «подождать и потерпеть» 14 лет!
2—В шине RS485 нет механизма разрешения коллизий подобно CAN(у). Если 2 ноды начнут передавать одновременно, то данные в витой паре исказятся и мастер прочитает мусорный пакет с поврежденной контрольной суммой.
3—Все устройства на шине RS485 могут вообще работать на разных битовых скоростях 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600 бит/c. Я работал в трех конторах и у каждой была своя стандартная битовая скорость шины RS485. И у всех разная! Если устройство работает на битовой скорости 460800 бит/c то оно не будет отвечать на пакеты которые ей посылают на битовой скорости 115200 бит/c.
Как же просканировать шину RS485?
Перед тем как приступить к объяснению сути алгоритма сканирования шины RS485 хочется привести аналогию из жизни. Аналогия эта про то как медвежатники отмычками взламывают навесные замки. Первой отмычкой создается момент силы, который фиксирует положение одного из пинов. Затем второй отмычкой находят пин, который движется туго и медленно и аккуратно подбирают положение упирающегося пина пока не услышат тихенький щелчок. Первая отмычка дрогнет. Затем начинает упираться другой пин. Аналогично двигают следующий пин до такого же щелчка. И так до тех пор пока все пины точно не встанут на нужные положения. Тогда замок откроется.
Тут ситуация аналогичная. Вместо пинов — биты, вместо щелчка — сигнал подтверждения.
Прежде чем двигаться дальше надо договориться о терминологии.
Терминология
—Адрес устройства — это либо MAC адрес, серийный номер (SN), либо аналог IP адреса или любой другой ID(шник) уникальный для каждого экземпляра устройства на шине RS485. Важен тот момент, что адрес широкий много битный. Пусть это, например, 32х битный адрес.
—Маска адреса — это часть адреса устройства, которая начинается с наименьшего значащего бита LSB и увеличивается в сторону старшего бита. Имеет смысл расширять маску от младших битов ибо младшие есть у всех адресов, а вот старших единичных битов может и не быть. Вот пример нескольких реальных масок:
№ |
Пример маски для адреса |
Длина маски, [бит] |
1 |
xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx |
0 |
2 |
xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0 |
1 |
3 |
xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx00 |
2 |
4 |
xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx01 |
2 |
5 |
1000_0100_0000_1111_1111_0001_1101_0011 |
32 |
6 |
xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx10 |
2 |
7 |
xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx10_1110 |
6 |
—Сигнал подтверждения— это когда ведомое устройство на RS485 берет пин UART_TX, переводит его в режим GPIO PUSH-PULL, устанавливает 0V, ждет T_ack секунд (например 10ms) и после этого снова подключает к пину UART_TX контроллер. Всё это и называется сигналом подтверждения. По сути устройство на время прижимает шину в ноль вольт. При этом совершенно не опасно, если несколько устройств одновременно прижмут шину в ноль. Эффект будет как от одного. То есть получается логическое ИЛИ. У мастера на UART_RX будет 0V.
—Пакет mute — это такой бинарный пакет получив который ведомое устройство перестает что- либо отправлять в общую шину RS485 и не будет даже испускать сигналы. Устройство будет только слушать шину. Mute пакет может содержать параметр включить или отключить Mute режим.
Словесное описание алгоритма сканирования шины RS485
1—Мастер устройство объявляет что сейчас все ведомые устройства переходят в режим сканирования.
2—мастер отправляет маску адреса, например Mx=xx…xx0 или Mx1=xx…xx1 и просит, чтобы откликнулись те устройства чей адрес совпадает с маской. То есть у кого нулевой бит равен нулю.
3—мастер переводит пин UART_RX в GPIO input, устанавливает подтяжку к питанию и непрерывно смотрит за напряжением на проводе UART_RX. Тут есть два исхода.
a) У мастера на проводе UART_RX появился 0.0 V. Значит, что на шине RS485 присутствует как минимум одно ведомое устройство у кого адрес совпадает с маской Mx.
b) У мастера на проводе UART_RX остался 3,3V. Значат что на шине RS485 нет ни одного устройства у кого бы адрес совпадал с маской Mx. Это значит, что дальше мы с этой маской Mx не работаем и просто отбрасываем её в сторону как заранее неправильный путь. Причем мастер ожидает не бесконечно, а строго определённой время таймаута, которое общее для всех устройств, например 20ms.
4—В случае 3.a) маска расширяется на 1 бит влево. Тут тоже есть два варианта. Либо мы к маске обнаруженного устройства приписываем префикс 0 либо 1. Надо идти по обоим путям: 1 и 2.
№ |
Маска |
Пояснение |
Пример |
1 |
xx…x0[PREV_ACK_MASK] |
увеличили на 0 |
x…x00 |
2 |
xx…x1[PREV_ACK_MASK] |
увеличили на 1 |
x…x10 |
Тут прослеживается рекурсия или элементы динамического программирование. Каждый шаг порождает 2 шага: c префиксом 0 и с префиксом 1.
Далее шаги 2-3-4 можно повторять снова и снова пока маска не достигнет длинны 32 бита. Как только это произойдет это станет означать что найдено одно устройство на шине. Но как найти остальные N-1 устройство?
5—Как только маска будет совпадать с 32 битами то мастер устройство отправляет команду заглушить устройство по определённому адресу. Master отправляет mute пакет.
Шаги 2-3-4-5 это по сути одна итерация. На следующей итерации мастер обнаружит другое устройство. И так до тех пор пока все маски перестанут выдавать сигнал подтверждения. После этого шина RS485 будет полностью просканирована.
К слову, на маску длинной ноль (xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx) отвечают установкой сигнала подтверждения все не заглушенные узлы RS485 сети. Поэтому данный пакет установки маски может служить критерием окончания сканирования сети.
Справедливости ради можно добавить что надо проделать все то же самое для всех возможных битовых скоростей RS485: 9600, 115200, и проч. Однако как правило RS485 сеть собирают из устройств у которых уже прописана битовая скорость по умолчанию.
Время сканирования на одной битовой скорости займет
Вариант |
Время |
Пояснение |
лучший случай |
32*N*dt |
подтверждение при первом увеличении маски |
Худший случай |
32*N*2*dt |
подтверждение при втором увеличении маски |
где dt — это время отклика на адресную маску
Алгоритм сканирования общей шины можно изобразить в виде вот этой диаграммы обмена пакетами
Плюсы этого метода
1++Простота.
2++эффективность
3++Быстрота работы в сравнении с перебором.
4++нет нужды в дополнительных проводах. Всё что надо это одна витая пара интерфейса RS485.
Минусы
1—Master устройство должно быть микроконтроллером с полноценным драйвером GPIO и UART. Не получится просто взять первый попавшийся китайский переходник USB-RS485, подключить его к PC и написать консольное Windows приложение, которое выполнит сканирование RS485 шины. Надо чтобы была не просто возможность читать\писать байты в RS485, но и переключать функции пинов с GPIO на UART и обратно. Причем надо переключать функции пинов быстро чтобы успеть принять сигналы от Slave nodes.
2—Нужна программная поддержка этого простенького протокола сканирования RS485 как на стороне master так и на стороне slave устройств.
Вывод
Этот простой алгоритм сканирования адресов на общей шине подойдет не только для RS485. Его можно реализовать для любого другого интерфейса с топологией общая шина. Это может быть и 1Wire, LIN или даже вовсе беспроводные интерфейсы типа LoRa или UWB.
Словарь
Акроним |
Расшифровка |
RS485 |
Recommended Standard 485 |
LSB |
Least Significant Bit |
MAC |
medium access control |
Links
ссылка на оригинал статьи https://habr.com/ru/articles/752292/
Добавить комментарий