Коммуникации - 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.

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

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

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

dtparam=spi=on
dtoverlay=spi1-3cs
dtoverlay=mcp251xfd,spi0-0,interrupt=25
dtoverlay=mcp251xfd,spi0-1,interrupt=24
  1. Сохраните файл: Ctrl+O, Ctrl+X

  2. sudo reboot now

Теперь raspberry pi готова работать с шилдом. Однако, нам все еще надо настроить сетевые интерфейсы can0, can1. Для этого, каждый раз после перезапуска rpi, нам надо выполнять следующие команды (или можете сделать systemd unit для них по аналогии с explorer_units/board, но если вы не знаете что такое systemd, то просто выполняйте их вручную):

ip link set can0 up txqueuelen 65535 type can bitrate 500000 dbitrate 4000000 restart-ms 1000 berr-reporting on fd on

ip link set can1 up txqueuelen 65535 type can bitrate 500000 dbitrate 4000000 restart-ms 1000 berr-reporting on fd on

Тут мы настраиваем оба интерфейса на битрейт 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):

ip link set can0 up txqueuelen 65535 type can bitrate 500000 dbitrate 4000000 restart-ms 1000 berr-reporting on fd on

Тут есть два битрейта - 500000 и 4000000. Их можно поменять, проще всего их оба умножать/делить на одно и то же число. Рассмотрим однако данный битрейт. После найстроки, мы можем посмотреть параметры интерфейса:

>>> sudo ip -details link show can0

3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UP mode DEFAULT group default qlen 65535
    link/can  promiscuity 0 minmtu 0 maxmtu 0 
    can <BERR-REPORTING,FD> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 1000 
	  bitrate 500000 sample-point 0.875 
	  tq 25 prop-seg 34 phase-seg1 35 phase-seg2 10 sjw 1
	  mcp251xfd: tseg1 2..256 tseg2 1..128 sjw 1..128 brp 1..256 brp-inc 1
	  dbitrate 4000000 dsample-point 0.700 
	  dtq 25 dprop-seg 3 dphase-seg1 3 dphase-seg2 3 dsjw 1
	  mcp251xfd: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..256 dbrp-inc 1
	  clock 40000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 

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

  • 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