Коммуникации - FDCAN
Использование FDCAN для общения между STM32 и Raspberry PI
В рамках этого раздела не будет разбираться подключение к raspberry pi по ssh, написание программ на raspberry (через VSCode или иначе). Предполагается, что читатель знает как это делать.
Также, не будет обсуждаться обычный (classic) CAN. Он является "подмножеством" FDCAN и при необходимости перейти на него, уже зная FDCAN, не сложно.
FDCAN
Протокол коммуникации FDCAN позволяет связать множество устройств в одну сеть. В сети нет фиксированного "мастера" или роутера, назначающего адреса устройств. Все сообщения отправляются "широковещательно" (broadcast) и видны каждому узлу сети. Фильтрацию сообщений можно настроить на приемники по id сообщения - какого вида сообщения принимать, а какие отбрасывать. Это быстрый, одноранговый (а значит устойчивый к отказу некоторых узлов) и надежный (при корректной настройке) протокол.
Меры предосторожности
При использовании FDCAN важно одинаково настроить время передачи одного бита (bit timing) и длину всех сегментов сообщения на каждом устройстве в сети. Если одно из устройств переиодически (или, в худшем случае, постоянно) посылает в сеть сообщения с неверными таймингами, это может привети к нестабильности отправки/ получения сообщений или вообще "распаду" всей сети.
Во-первых, такое устройство может "перехватить" всю сеть, игнорируя попытки других узлов отправлять сообщения (т.к. не может нормально читать их биты). Во-вторых, если некорректные сообщения посылаются регулярно, это переполнит счетчик ошибок других узлов и переведет к их "выходу" из сети. Одним словом, некорректные тайминги - ахилесова пята и одновременно самая запутанная часть работы с FDCAN. Но после того как удалось один раз настроить все правильно, дальнейшая работа значительно облегчается.
Настройка
Raspberry Pi
Для использования FDCAN на raspberry pi, нам понадобится rpi с can-shield, подключенным к соответствующим пинам на контроллере (CAN H, CAN L). Выглядит это так (вариантов подключения масса, это самый общий пример):

Обратите внимание, что переключатели над CAN0, CAN1 в положении ON.
Далее, нам необходимо настроить ОС на работу с новой переферией:
Откройте
config.txt:sudo nano /boot/config.txtДобавьте слеедующие строки в конец файла:
Сохраните файл:
Ctrl+O, Ctrl+Xsudo reboot now
Теперь raspberry pi готова работать с шилдом. Однако, нам все еще надо настроить сетевые интерфейсы can0, can1. Для этого, каждый раз после перезапуска rpi, нам надо выполнять следующие команды (или можете сделать systemd unit для них по аналогии с explorer_units/board, но если вы не знаете что такое systemd, то просто выполняйте их вручную):
Тут мы настраиваем оба интерфейса на битрейт 500кбит/4мбит. Это половина от максимального, но больше нам и не нужно.
Далее, необходимо установить пакет can-utils: sudo apt install can-utils.
Самый просто способ проверить, что теперь все работает, это подключить на шилде CAN0 L, H <-> CAN1 L, H и открыть два терминала на rpi. В одном - candump can0. Это будет печатать все приходящие сообщения. В другом - cangen -mv can1. Это будет генерировать случайный сообщения. Если отправленные/пришедшие сообщения совпадают, то все прошло удачно.
STM32
Для активации FDCAN на STM32, нам необходимо включить соответствующий блок переферии:

Тут уже даны все правильные параметры таймингов. Для целей обучения достаточно просто переписать их, не вникая, откуда они взялись.
Для страждущих - как узнать тайминги самому
Тут не будет объяснения за что отвечает каждый сегмент (seg), что такое data и nominal битрейты и т.д., это читайте в стандарте FDCAN. Однакое даже без этого понимания есть читерский способ как узнать нужные тайминги.
Для этого, вернемся к команде настройки сетевых интерфейсов (разберем только can0):
Тут есть два битрейта - 500000 и 4000000. Их можно поменять, проще всего их оба умножать/делить на одно и то же число. Рассмотрим однако данный битрейт. После найстроки, мы можем посмотреть параметры интерфейса:
Тут мы видим всю информацию о конфигурации интерфейса. Дальше можно произвести следующие чисто механические действия:
dprop-seg + dphase-seg1 = data time seg1
dphase-seg2 = data time seg2
dsjw * dphase-seg1 = data sync jump width
prop-seg + phase-seg1 = nominal time seg1
phase-seg2 = nominal time seg2
sjw * phase-seg1 = nominal sync jump width
tq - по сути, "период" fdcan в наносекундах. Частоту fdcan на стороне stm можно найти в clock configuration справа внизу. Соответственно, с помощью clock divider и nominal prescaler надо добиться, чтобы частота была равна 1/tq. Для dtq и data prescaler - аналогично.
Программирование
RPI <-> RPI
TODO
RPI <-> STM32
TODO
Last updated