Всем привет. В данной статье я вам расскажу про CAN шину. Мы разберемся с тем, как она работает на низком уровне.
Отмазки.
Картинки я "надёргал" из англоязычных ресурсов. Переводить не стал, так как тут все термины общепринятые и в переводе не нуждаются.
На примере автомобиля мы видим что было до введения шины CAN. имелось множество разрозненных устройств, которые каким-то образом должны были взаимодействовать между собой. В результате автомобиль окутала куча сигнальных проводов по которым шло взаимодействие между разными устройствами.
С введением шины CAN функциональная схема приобрела примерно такой вид. Стало значительно проще управлять различными агрегатами автомобиля.
Физический уровень.
Как вы видите транзисторы включены по схеме с открытым коллектором. Вот это означает то что если на шине хотя бы одно устройство транслируют логический ноль, то вся шина прижимается к земле. При этом если, остальные узлы передают логическую единицу, то это не является аварийным состоянием, так как транзисторы, в этот момент, попросту закрыты. На таблице истинности это отчетливо видно. На линии будет лог. единица тогда и только тогда, когда все устройства передают логическую единицу.
И это следует иметь в виду. Следует вести на данном этапе понятия - рецессивные и доминантные биты. Доминантным битом будет является 0, рецессивным единица. Нуль всегда сильнее единицы. В дальнейшем мы будем оперировать именно этими понятиями.
Если мы дифференциально посмотрим осциллографом линию CAN, то увидим следующее.
При подаче доминантного бита линия прижимается к земле.
Логическая составляющая.
Устройства сети CAN общаются т.н. кадрами. Всего в can протоколе имеются четыре типа кадра. Мы с вами подробно рассмотрим кадр данных (data frame). Рассматривать начнем мы конкретно его, потому что этот кадр наиболее часто гуляет по сети CAN и, как правило, когда говорят о CAN, имеют ввиду именно этот кадр.
Состав кадра изображен на рисунке ниже
Кадр данных включает себя следующие элементы.
Bus idle - линия не занята. Признак того, что линия свободно и можно начинать передачу.
Start of frame (SOF) - бит, который определяет начало кадра.
Далее идет поле арбитража, которое занимает 11 бит. Кстати мы рассмотрим стандартный формат. Существует еще расширенный, но его рассматривать не будем.
После поле арбитража идет так называемый control field, а за ним поле данных. В этом поле имеется от 0 до 64 бит данных. Собственно говоря все данные которые мы хотим передать находятся именно в этом поле.
Затем следует поле контрольной суммы, которое состоит из 15 бит, а следом идёт поле подтверждение. Кадр заканчивается признаком and of frame (EOF) и interframe space (IFS). IFS нужно для того, что бы внутренняя логика приёмо-передатчика успела отработать, данные были защелкнуты... в общем, это время для завершения всех внутренних процессов в микросхеме.
Так. Крупными мазками пробежались, теперь в детали.
SOF
- Сообщает устройствам что сейчас будет начало передачи.
- Всегда доминантный (т.е. лог. 0)
- Этот бит формирует срез (некоторые любят говорить "задний фронт") для аппаратной синхронизации приемников и передатчика.
Arbitration field
- Содержит идентификатор устройства, который используется для арбитража.
- В поле данных, бит Remote Transmission Request (RTR) всегда доминантный.
Пара слов про арбитраж.
В терминологии CAN шины, арбитраж - это процесс, который определяет, какое CAN устройство сейчас займет линию для передачи данных. Я об этом подробно расскажу чуть ниже, сейчас только упомяну, что после SOF все устройства начинают свои кадры (все, которым есть что "сказать"). И какое именно устройство захватит шину и пропихнёт в неё свои данные определяется именно процессом арбитража на аппаратном уровне. Чем меньшее значение имеет ID, тем приоритетнее этот кадр. Например, ID = 0x00 самый приоритетный.
Поехали дальше.
Control field
- IDE (IDentifier Extension) - идентификатор расширенного формата. В нашем случае формат стандартный, по этому бит в доминантном состоянии.
- r0 - резерв, не используется.
- DLC3...DLC0 (Data Length Code) - показывает количество байт данных, которые находятся в поле DATA. Может принимать значение от 0 до 8. Остальные значения не используются.
Data field
Непосредственно данные, которые мы ходит передать. т.н payload (люблю это слово) :)
Сейчас возбудятся люди, которые не любят англицизмы и выступают за то, что бы не только термины придумывать свои, но и язык программирования на родном, русском. Я же выступаю за то, что не надо изобретать велосипед.
- Может содержать от 0 до 8 байт
- Количество байт, соответствует заявленному в поле DLC
- Данные передаются в формате MSB. На рисунке не видно, но данные в поле расположены так: [DB7 DB6 ... DB1 DB0]
CRC field
В целом, всё понятно, содержит 15 бит CRC. Аналогично, в формате MSB.
Поле заканчивается рецессивным битом-разделителем, указывающим что поле CRC закончилось.
ACK field
Состоит из двух бит: непосредственно бит ACK и рецессивный разделитель.
Бит ACK может принимать либо 0, либо 1.
Логика такая.
Передатчик в линию транслирует ACK=1. Если всё хорошо, то в это время приёмник (-ки) передают доминантный бит. Так как доминантный бит сильнее рецессивного, то вся линия (в этот момент времени) "падает в нуль". Передатчик это видит и делает вывод о том, что на линии есть, по меньшей мере, одно рабочее устройство, которое его "слышит".
Если ACK остаётся в рецессиве, то передатчик считает что на линии нет устройств и может начать (скорее всего и начнет) наваливать данные в линию, пока его не услышат.
EOF
- Содержит 7 рецессивных бит
- Является маркером окончания поля данных.
IFS
- Имеет длину минимум в три рецессивных бита
- В течении этого времени запрещена любая передача в линию другими устройствами
- Необходимо, что бы контроллеры успели переместить данные из своих RX буферов и обработать их.
- В конечном итоге, кадр заканчивается ACK + EOF + ISF = 11 рецессивными битами.
Арбитраж
Арбитраж проходит достаточно просто. У нас есть поле арбитража (по совместительству поле с ID устройством). После фиксации состояния Bus idle, все устройства начинают выдавать свои кадры. Проваливают линию в нуль (SOF) и выталкивают свои ID. При этом, устройство передаёт бит и слушает линию. В результате, если устройство выставило на линию рецессивный бит, а считало доминантный, то делается вывод, что в линию "долбится" более приоритетное устройство. В результате линию надо освободить до лучших обстоятельств. Рисунок ниже показывает процесс арбитража.
Битстафинг
В CAN сети, 6 доминантных бит является маркером ошибки (эт уже к теме разбора другого кадра). Но бывает такое, что поле данных может содержать в себе шесть доминантных бит и это не ошибка, а полезные данных. Так вот, что бы разделить ситуацию, когда передается сигнал ошибки, а когда полезные данные, используют технологию битстафинга. Суть в том, что после пяти идущих подряд "нулей" обязательно вставляется "1".
Как только приёмник видит, что пять нулей прервались одной единицей, то логика приемника понимает, что: это не ошибка, а полезные данные, сработал механизм битстафинг и надо эту "лишнюю" единицу просто проигнорировать.
Осциллограмма линии
Ну вроде всё. Надеюсь нанёс вам полезность. Как видите, линия CAN очень интересна в своей реализации. Я очень люблю этот интерфейс именно по тому, что он категорически надёжен (диф. линия защищает от синфазной помехи на уровни физики процесса) и не заморачиваюсь по поводу разграничения, когда какое устройство должно передавать. Всё "разруливается" на уровне физики и локиги контроллера шины CAN.