> For the complete documentation index, see [llms.txt](https://voltbro.gitbook.io/vbcores/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://voltbro.gitbook.io/vbcores/tutorials/stm32-cube-ide/kommunikacii-fdcan.md).

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

{% hint style="warning" %}
В рамках этого раздела не будет разбираться подключение к raspberry pi по **ssh**, написание программ на raspberry (через VSCode или иначе). Предполагается, что читатель знает как это делать.

Также, не будет обсуждаться обычный (classic) CAN. Он является "подмножеством" FDCAN и при необходимости перейти на него, уже зная FDCAN, не сложно.
{% endhint %}

## FDCAN

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

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

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

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

## Настройка

### Raspberry Pi

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

<figure><img src="/files/NCAiGvTFsMFhaOzLz7NH" alt=""><figcaption><p>Соединение rpi и vbcore</p></figcaption></figure>

Обратите внимание, что переключатели над `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
```

4. Сохраните файл: `Ctrl+O, Ctrl+X`
5. `sudo reboot now`

Теперь raspberry pi готова работать с шилдом. Однако, нам все еще надо настроить *сетевые интерфейсы* `can0, can1`. Для этого, каждый раз после перезапуска rpi, нам надо выполнять следующие команды (или можете сделать systemd unit для них по аналогии с [explorer\_units/board](https://github.com/voltbro/explorer_units/tree/master/board), но если вы не знаете что такое systemd, то просто выполняйте их вручную):

<pre class="language-bash"><code class="lang-bash"><strong>ip link set can0 up txqueuelen 65535 type can bitrate 500000 dbitrate 4000000 restart-ms 1000 berr-reporting on fd on
</strong>
ip link set can1 up txqueuelen 65535 type can bitrate 500000 dbitrate 4000000 restart-ms 1000 berr-reporting on fd on
</code></pre>

Тут мы настраиваем оба интерфейса на битрейт 500кбит/4мбит. Это половина от максимального, но больше нам и не нужно.

Далее, необходимо установить пакет `can-utils`: `sudo apt install can-utils`.

Самый просто способ проверить, что теперь все работает, это подключить на шилде `CAN0 L, H <-> CAN1 L, H` и открыть два терминала на rpi. В одном - `candump can0`. Это будет печатать все приходящие сообщения. В другом - `cangen -mv can1`. Это будет генерировать случайный сообщения. Если отправленные/пришедшие сообщения совпадают, то все прошло удачно.

### STM32

Для активации FDCAN на STM32, нам необходимо включить соответствующий блок переферии:

<figure><img src="/files/7RUBkyLHmlpNI6LhXevS" alt=""><figcaption><p>Настройка ioc</p></figcaption></figure>

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

<details>

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

Тут **не будет&#x20;*****объяснения*** за что отвечает каждый сегмент (`seg`), что такое data и nominal битрейты и т.д., это читайте в **стандарте FDCAN**. Однакое даже без этого понимания есть читерский способ как узнать нужные тайминги.

Для этого, вернемся к команде настройки сетевых интерфейсов (разберем только `can0`):

<pre class="language-bash"><code class="lang-bash"><strong>ip link set can0 up txqueuelen 65535 type can bitrate 500000 dbitrate 4000000 restart-ms 1000 berr-reporting on fd on
</strong></code></pre>

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

<pre class="language-bash"><code class="lang-bash"><strong>>>> sudo ip -details link show can0
</strong><strong>
</strong>3: can0: &#x3C;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 &#x3C;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 
</code></pre>

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

* 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` - аналогично.

</details>

***

## Программирование

## RPI <-> RPI

TODO

## RPI <-> STM32

TODO


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://voltbro.gitbook.io/vbcores/tutorials/stm32-cube-ide/kommunikacii-fdcan.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
