1. Тема дня

CAN/FDCAN/TWAI: bit timing, sample point, arbitration, termination, transceiver, filters, error counters, bus-off recovery. Главная мысль: CAN - не UART, а многомастерная шина с арбитражем, ошибками, приоритетами ID и строгой физикой.

2. Зачем это нужно в проектах

CAN полезен для обмена между контроллерами, промышленных модулей, HIL fault-сценариев, связи ESP32/STM32/Jetson, диагностики и коротких событий phase_event, fault_event, heartbeat.

3. Теория

CAN-узел:

text
MCU CAN/FDCAN/TWAI controller
  TX/RX logic-level
  -> CAN transceiver
  -> CAN_H / CAN_L differential bus

CAN_TX/RX нельзя напрямую подключать к CAN_H/CAN_L. ID - это приоритет: чем меньше ID, тем выше приоритет арбитража.

text
0x080..0x0FF - fault/safety
0x100..0x1FF - phase/sync
0x200..0x2FF - commands
0x300..0x4FF - telemetry
0x600..0x6FF - diagnostics
0x700..0x70F - heartbeat

Bit timing требует: CAN kernel clock, prescaler, time quanta, TimeSeg1/2, SJW, sample point. Loopback не проверяет трансивер, кабель, termination, ground и sample point в реальных условиях. Termination: две 120 Ом на концах. При выключенном питании между CAN_H и CAN_L ожидается около 60 Ом. Bus-off recovery:

text
bus-off detected
  -> stop non-critical TX
  -> save diagnostics
  -> backoff
  -> restart CAN controller
  -> repeated bus-off -> degraded mode

Filters нужны, чтобы application не обрабатывал весь трафик шины. Архитектура:

text
can_driver -> can_service -> can_protocol -> application events

4. Типичные ошибки

  1. CAN_TX/RX напрямую к CAN_H/L.
  2. Проверить только loopback и решить, что всё готово.
  3. Использовать неточный clock для реальной CAN-сети.
  4. Termination на каждом модуле.
  5. Не проектировать ID как приоритеты.
  6. Не включать filters.
  7. Делать MCU reboot при bus-off вместо controlled recovery.

5. Практическое задание

Создай CAN_FDCAN_POLICY.md:

markdown
# CAN / FDCAN policy
Role:
CAN is used as industrial event and diagnostics bus.
Physical layer:
- external CAN transceiver is mandatory;
- 120 Ohm termination only at both ends;
- expected bus resistance off-power: ~60 Ohm;
- TVS near connector;
- ground/reference or isolation is defined;
- stub length is minimized.

Диагностика:

c
typedef enum {
    CAN_BUS_STATE_STOPPED = 0,
    CAN_BUS_STATE_ACTIVE,
    CAN_BUS_STATE_ERROR_PASSIVE,
    CAN_BUS_STATE_BUS_OFF,
    CAN_BUS_STATE_RECOVERING,
    CAN_BUS_STATE_DEGRADED,
} can_bus_state_t;
typedef struct {
    can_bus_state_t state;
    uint32_t tx_ok, tx_fail, rx_ok, rx_dropped;
    uint32_t rx_fifo_overrun, tx_queue_full;
    uint32_t bus_error_count, error_passive_count;
    uint32_t bus_off_count, recovery_count;
    int64_t last_rx_us, last_tx_us, last_bus_off_us;
} can_diag_t;

6. Что почитать или попробовать дальше

STM32 HAL FDCAN, ST AN5348, ST AN5878, Vector CAN physical layer notes, ESP-IDF TWAI.

Что доказывает внутренний CAN loopback?

Задание

На выключенной простой CAN-шине стоят две termination по 120 Ohm, других сопротивлений между CAN_H/CAN_L нет. Что покажет омметр? Как изменится результат при третьей termination 120 Ohm?

Критерии самопроверки: Покажите параллельное соединение, значения 60/40 Ohm и ограничение статической проверки.

Показать ответ автора

Два параллельных 120 Ohm дают 60 Ohm. Три дают 40 Ohm. Это модель идеальных резисторов; реальная схема может добавлять пути измерения. Проверка делается при снятом питании и не доказывает правильность sample point или динамики шины.