Коммуникации - FDCAN

Использование FDCAN для общения между STM32 и Raspberry PI

FDCAN

Протокол коммуникации FDCAN позволяет связать множество устройств в одну сеть. В сети нет фиксированного "мастера" или роутера, назначающего адреса устройств. Все сообщения отправляются "широковещательно" (broadcast) и видны каждому узлу сети. Фильтрацию сообщений можно настроить на приемники по id сообщения - какого вида сообщения принимать, а какие отбрасывать. Это быстрый, одноранговый (а значит устойчивый к отказу некоторых узлов) и надежный (при корректной настройке) протокол.

Меры предосторожности

При использовании FDCAN важно одинаково настроить время передачи одного бита (bit timing) и длину всех сегментов сообщения на каждом устройстве в сети. Если одно из устройств переиодически (или, в худшем случае, постоянно) посылает в сеть сообщения с неверными таймингами, это может привети к нестабильности отправки/ получения сообщений или вообще "распаду" всей сети.

Во-первых, такое устройство может "перехватить" всю сеть, игнорируя попытки других узлов отправлять сообщения (т.к. не может нормально читать их биты). Во-вторых, если некорректные сообщения посылаются регулярно, это переполнит счетчик ошибок других узлов и переведет к их "выходу" из сети. Одним словом, некорректные тайминги - ахилесова пята и одновременно самая запутанная часть работы с FDCAN. Но после того как удалось один раз настроить все правильно, дальнейшая работа значительно облегчается.

Настройка

Raspberry Pi

Для использования FDCAN на raspberry pi, нам понадобится rpi с can-shield, подключенным к соответствующим пинам на контроллере (CAN H, CAN L). Выглядит это так (вариантов подключения масса, это самый общий пример):

Соединение rpi и vbcore

Обратите внимание, что переключатели над CAN0, CAN1 в положении ON.

Далее, нам необходимо настроить ОС на работу с новой переферией:

  1. Откройте config.txt: sudo nano /boot/config.txt

  2. Добавьте слеедующие строки в конец файла:

  1. Сохраните файл: Ctrl+O, Ctrl+X

  2. sudo 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, нам необходимо включить соответствующий блок переферии:

Настройка ioc

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

Для страждущих - как узнать тайминги самому

Тут не будет объяснения за что отвечает каждый сегмент (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