Шина CAN наиболее широко применяется в автоиндустрии. Она удачно сочетает высокую скорость передачи данных, высокую надёжность и лёгкость применения, а некоторые решения лежащие в её основе, здорово облегчают жизнь. Рассмотрим её подробнее.

Физический уровень

Среда передачи — гальванически развязанная неэкранированная витая дифпара, часто её объединяют в одном кабеле с шиной питания. Стандартами оговорена также возможность применения оптоволокна, но мне неизвестны реальные примеры его использования (возможно, это подошло бы для энергосетей и подстанций).

Для передачи данных используются дифференциальные сигналы с амплитудой 5 вольт. Важная часть стандарта: приёмопередатчик линии CAN обязан иметь возможность настройки длительности фронтов. Благодаря этому мы можем искать компромисс между скоростью связи и электромагнитной совместимостью: на низких скоростях можно затянуть фронты, и получить минимальный шум от линии; быстрые же фронты безусловно увеличат радиошум, но дадут возможность ускорить связь. Более того, управлять длиной фронтов можно динамически.

Также стандарт говорит о внутреннем устройстве и логике работы приёмопередатчика CAN. Вкратце, он постулирует способность трансивера продолжать корректно работать при обрыве одного из проводов дифпары, а также при замыкании любого из проводов пары на землю или питание. Однако по опыту сеть работает даже при перевёрнутой полярности проводов, при сбоях некоторых устройств в сети, при замыкании обоих проводов, при применении длинного несогласованного кабеля (ссылка), а также при разрыве линии посередине.

Скорость передачи

Скорость передачи зависит от длины линии, и достигает 1МБод на линиях длиной до 40м. На полукилометре можно рассчитывать максимум на 125 кбод, из-за конечного времени распространения сигнала — так же, как в Ethernet.

Битовая скорость будет немного меньше, из-за служебных битов и особенностей кодирования. Есть также стандартная скорость 1.6Мбит/с, и появляются решения вроде TurboCAN. В любом случае, скорость ограничена технологией арбитража (сигнал должен успеть покрыть всю сеть), и можно немного повысить её, увеличив временные интервалы tSEG — но это повлияет на надёжность.

Формат сообщения и кодирование

Существует два типа сообщений CAN — стандартный (standard) и расширенный (extended). Они различаются только длиной номера сообщения. Про signaling нужно написать подробнее, потому что оно является основой многих особенностей шины. Важно отметить, что контроль целостности сообщений сделан на уровне архитектуры — в конце сообщения обязательно содержится CRC, вычисленный передатчиком, а потом проверяемый приёмником. При использовании CAN MAC все операции с CRC производятся аппаратно.

С целью недопущения срыва синхронизации в сети запрещено появление при обмене сообщениями какого-либо уровня дольше чем на 5 тактов. Для этого при передаче сплошной нулевой или единичной посылки каждые 5 тактов посылается 1-тактовый сигнал инверсной полярности.

Общение по шине (Signaling)

Все устройства объединены шиной по схеме «И», а выходные каскады трансиверов сделаны по схеме с общим эмиттером — то есть если какое-то устройство передаёт «0», а другое — «1» — на шине установится уровень «1». Таким образом, на шине нет сигналов «0» и «1», есть рецессивный и доминантный сигналы.

Когда трансивер получает от процессора данные на передачу, он начинает слушать эфир, и как только он понимает, что эфир освободился — начинает передачу побитово. Параллельно он продолжает слушать эфир.

Но ведь хотеть что-то передать могут одновременно два устройства. Как решается эта коллизия? Передатчик слушает каждый отправленный бит — сравнивает, что он пытался передать, и что реально произошло на шине. Если был передан рецессивный бит (0), а на шине установился доминантный уровень (1) — значит, его установил кто-то другой, а мы прекращаем передачу. Таким образом, даже если передачу начинают несколько устройств — постепенно они проигрывают арбитраж, и остаётся только один выигравший передатчик. Конечно, все проигравшие передатчики не сдаются и не забывают сообщения, которые не удалось передать. Они повторяют попытки в следующих окнах передачи. Из этого следует разный приоритет устройств.

Приоритет

Мы видим, что некоторые сообщения проигрывают арбитраж при передаче, а некоторые — выигрывают. Какие это сообщения? Это те, которые при передаче своими доминантными уровнями заглушили рецессивные уровни других. Пускай у нас есть два разных сообщения, 10011 и 10100.

Передаём первый бит, «1»: оба трансивера устанавливают доминантный уровень, никаких эксцессов нет (напоминаю — ОБА трансивера одновременно ведут передачу!).

Второй бит, «0» — опять оба трансивера устанавливают рецессивный уровень, и продолжают передачу. Каждый трансивер до сих пор уверен, что он единственный передаёт на линии.

Третий бит. Трансивер А установил рецессивный уровень, трансивер Б — доминантный уровень. На линии появился доминантный уровень. Трансивер А видит несоответствие и в этот момент понимает, что на линии передаёт кто-то ещё; видит что проиграл арбитраж и перестаёт передавать. Трансивер Б не видит несоответствия (он передавал «1», и на линии и получилась «1»), и продолжает передачу, считая что он единственный передаёт.

Таким образом, выигрывает тот, кто передаёт больше доминантных уровней в начале. А поскольку в начале сообщения передаётся его номер — значит, сообщение с более высоким номером будет иметь бОльший приоритет. Получается, что это число — это скорее не номер сообщения, а его приоритет. Также его можно рассматривать как адрес приёмника, потому что вы можете настроить любой трансивер на приём только сообщений с определёнными номерами.

Конечно, при плотной передаче и постоянно занятой среде может получиться, что низкоприоритетные сообщения вообще никогда не смогут уйти. С этим нужно бороться на архитектурном уровне.

Небольшой хак — в поля адреса в расширенном формате можно вставить до 3 дополнительных байт информации. Конечно, это здорово сужает диапазон адресов (до 32 штук), но увеличивает payload сети.

Все сообщения на шине — либо unicast, либо multicast. Строго говоря, вы сами управляете получением сообщений, и можете реализовать сколь угодно сложную адресацию.

Любое устройство имеет номера принимаемых сообщений, они же — адреса. Таким образом, вы можете назначить в группе устройств уникальный адрес для каждого из них, плюс общий адрес группы — так вы сможете посылать сообщения как какому-то конкретному устройству, так и всей группе в целом.

Это очень удобно для опроса устройств: посылаете одно сообщение всей группе, каждое устройство группы принимает его и отправляет свой отклик. Если бы такого механизма не было, пришлось бы рассылать запрос на каждое устройство.

Более высокие уровни стека

На самом деле, CAN — это только транспортный протокол. Он может инкапсулировать в себе любой информационный протокол, и уровнем выше передавать, например, TCP. Или 1-wire. Поэтому любые попытки разобрать структуру сообщений и передаваемые данные почти всегда обречены на провал, если только не используется очень простой протокол. А если вы ещё и зашифруете сообщения любым, даже самым простеньким методом и маленьким ключом — реверс-инжиниринг станет пыткой. К тому же, зачем шифровать слабо, если в составе STM32F4 есть аппаратный криптопроцессор.

Однако, протокол хорош своей простотой, и (на невысоких скоростях) с его разбором справится даже какой-нибудь PIC12. Для более высоких скоростей можно использовать готовые MAC — они сами совершат всю работу с CAN, принимая и получая данные по интерфейсу SPI.

Что передавать

Высокая скорость передачи и хорошая приоретизация трафика дают возможность передавать по этой шине всё, что угодно — начиная реалтайм-сигналами немедленных действий, заканчивая lossless-звуком и даже видео в каком-нибудь кодеке. Причём звук/видео и сигналы управления можно передавать одновременно благодаря приоретизации. Можно даже устроить простенькую QoS.

Некоторые используют использовать эту линию для связи различных блоков внутри стойки с оборудованием. Также она подходит для подключения различных удалённых датчиков и исполнительных устройств — то есть, идеально для умного дома.

На самом деле, эта шина крайне гибка и пригодна для многих применений. Её используют в тяжёлых и ответственных применениях: самолёты, тепловозы, ядерные реакторы, ускорители частиц, управление телескопами и лифтами, банковские терминалы, медицинские приборы и целые операционные. Есть пример использования её даже на микроспутнике!. Можно работать на огромных расстояниях, нисколько не потеряв в надёжности.

Среда передачи

CAN неприхотлив. Вы можете использовать даже телефонную лапшу, и всё равно у вас будет связь. Однако конечно, для достижения высоких скоростей лучше использовать более качественные кабели — например, Ethernet (по нему же можно ещё и питание посылать), либо КМВЭВ и подобные. Ещё хорош кабель USB — там два толстых провода питания и экранированная витая пара с информацией.

Однако, на тестовом стенде у меня успешно работает одна неэкранированная тонкая витая пара, выдранная из Ethernet-кабеля длиной 20 метров на скорости 1МБит/с. С ней никогда не было проблем, даже при включённых станках, стоящих рядом.

Нежелательны длинные отводы. Если вы соединяете несколько устройств — то лучше сделать максимально короткий отвод (до 10см), а лучше — сделать у устройства два порта CAN, соединить их вместе, и включать устройство в разрыв цепи.

Конечно, нужно терминировать концы линии резистором в 120 Ом. Я проводил эксперименты по подбору этого резистора.

Приёмопередатчик

Я использую микросхему PCA82C250. Она надёжна, устойчива к КЗ на линии передачи, удобна в подключении и имеет маленькие размеры (SO-8). Сделанные мной две платы трансиверов удалось довести до габаритов 13*13*13.

На входе в трансивер стоит терминатор — резистор в 120 Ом. Также нужно установить цепи защиты от помех — сапрессоры PESD1CAN или PESD2CAN, зашунтированные резистором и конденсатором малой ёмкости на землю. После них — дроссель, после него входим в трансивер. (Ссылка) Трансивер CAN будет гальванически связан с сетью передачи — запитаем его с помощью изолированного DC-DC преобразователя P10AU-1205ELF, а после него поставим две оптопары 6N137.

Разъёмы для CAN не стандартизированы. Я использую разъёмы 300-021-12 или USB.

Управляющий микроконтроллер

Существует довольно много микроконтроллеров с встроенной поддержкой CAN. STM32F407 имеет два отдельных порта CAN, что позволяет делать из него сетевой мост (разделяющий два сегмента сети), либо вставать в разрыв между сетью и исследуемым устройством и очень удобно записывать его трафик для анализа.

Ссылки

CIA — Консорциум по внедрению CAN + много примеров применения;Wiki — Википедия про CAN;

Electronix.ru — форум про CAN, много полезной информации от разработчиков.

Самодельный драйвер шины CAN, работа с шиной CAN на микроконтроллере STM32.