FDCAN, это аббревиатура от Flexible Data-Rate Controlled Area Network (гибкая сеть с контролируемой скоростью передачи данных). Как следует из названия, это существенное усовершенствование по сравнению с обычным CAN, особенно в тех областях, где CAN был очень ограничен, например, в объеме данных и пропускной способности. FDCAN преодолевает эти недостатки, что делает его пригодным для современных приложений.Рассмотрим настройку FDCAN, а также простой тест, выполненный в режиме

обратной связи.

Формат FDCAN

Ниже приведено изображение, демонстрирующее формат FDCAN.

  • Первый этап арбитража — это сообщение, содержащее:
    • начало кадра ( SOF )
    • Идентификационный номер и другие биты, указывающие на назначение сообщения (предоставление или запрос данных), а также конфигурацию скорости и формата (CAN или CAN-FD).
  • Этап передачи данных состоит из:
    • Код длины данных ( DLC ) указывает, сколько байтов данных содержит сообщение.
    • данные , которые пользователь желает отправить
    • контрольная циклическая избыточность ( CRC )
    • доминирующий фрагмент
  • Второй этап арбитражного разбирательства включает в себя:
    • получатель подтверждения ( ACK ), передаваемого другими узлами в шине.
    • конец кадра ( EOF )

В процессе IFS никакие сообщения не передаются : цель состоит в том, чтобы отделить текущий кадр от следующего.

Давайте сравним архитектуру Frame между CAN-FD и CAN 2.0.

  • CAN 2.0 отправляет бит RTR для уточнения типа кадра: кадр данных (RTR является доминирующим) или удаленный кадр (RTR является рецессивным), тогда как CAN-FD всегда отправляет доминирующий бит RRS (зарезервированный), поскольку поддерживает только кадры данных.
  • В формате CAN-FD в поле управления добавлены три новых бита по сравнению с CAN 2.0:
    • Бит расширения длины данных ( EDL ): является рецессивным и указывает на то, что кадр относится к типу CAN-FD; в противном случае этот бит является доминирующим (называемым R0) в кадре CAN 2.0.
    • Переключение битовой скорости ( BRS ): указывает, включены ли две битовые скорости (например, когда фаза данных передается с другой битовой скоростью, чем фаза арбитража).
    • Индикатор состояния ошибки ( ESI ): указывает, находится ли узел в активном или пассивном режиме обработки ошибок.

Основные различия между CAN-FD и CAN 2.0 показаны ниже:

Настройка

Этот раздел будет очень обширным, поскольку мы рассмотрим настройку cubeMX, а также огромное количество параметров и причины, по которым они имеют такие значения.

В этом руководстве я выбираю внутреннюю тактовую частоту 64 МГц . Причина этого будет объяснена чуть позже. Также обратите внимание, что тактовая частота FDCAN составляет 50 МГц. Она будет использоваться в последующей части руководства.

Здесь я включил FDCAN для Cortex M7. Обратите внимание, что контакты PH13 — это контакт TX, а PH14 — контакт RX.

В используемом мной контроллере H745 Discovery трансивер расположен непосредственно на плате. Микросхема MCP2562FDT подключена к контактам PH13 и PH14. Разъемы на плате предназначены для CANH и CANL. Это показано на рисунке ниже.

В модуле CAN-FD много параметров для настройки, поэтому мы рассмотрим лишь некоторые из них за раз.

  • Здесь я использую формат FD Mode без переключения битрейта.
    • На самом деле, FD CAN может передавать поле арбитража и поле данных с разной скоростью передачи. Но я хочу использовать одинаковую скорость передачи для обоих устройств.
  • В режиме установлен режим внешней обратной связи (External LoopBack Mode). Вы также можете использовать режим внутренней обратной связи (Internal LoopBack), поскольку они в основном идентичны.
  • Я включил автоматическую повторную передачу в случае ошибок и отключил остальные несущественные параметры.

В режиме обратной связи (LoopBack Mode) FDCAN обрабатывает передаваемые им сообщения как принятые и сохраняет их, если они проходят фильтрацию на соответствие требованиям. Фактически, вывод TX внутренне соединен с выводом RX, как показано ниже.

Для расчета этого набора параметров нам потребуется использовать внешний калькулятор, который можно найти по адресу https://www.kvaser.com/support/calculators/can-fd-bit-timing-calculator/

Первые 3 параметра, которые нам необходимо ввести, это частота тактового сигнала FDCAN, допуск входного тактового сигнала и задержка приемопередающего узла.

Тактовая частота FDCAN составляет 50 МГц , и мы уже рассматривали это в начале данного раздела.

Далее следует допуск тактовой частоты . В начале я упоминал, что в этом руководстве использую внутреннюю тактовую частоту, потому что так проще определить допуск тактовой частоты для входного сигнала. На рисунке ниже это наглядно показано:

Наконец, у нас есть задержка узла или задержка распространения. Ее можно найти в характеристиках переменного тока используемого вами трансивера.

Как я уже упоминал, на используемой мной плате установлен встроенный трансивер MCP2562FD. Выше приведены его характеристики переменного тока, и я использую задержку 180 нс.

После ввода всех значений необходимо добавить CAN-устройство.

Далее нам необходимо ввести битрейт , который мы хотим установить для CAN-шины.

Как я уже упоминал, FD CAN может передавать поле арбитража и данные с разной скоростью передачи. Но я хочу использовать одинаковую скорость передачи для обоих полей, а именно 500 Кбит/с. После ввода скорости передачи нажмите «Пересчитать», чтобы получить значения.

После нажатия кнопки «Пересчитать» мы получим значения параметров. Это показано на рисунке ниже.

Эти значения можно ввести в параметры FDCAN.

Теперь рассмотрим остальные параметры. Стрелками отмечены параметры, которые были изменены.

  • На изображении выше смещение оперативной памяти (Ram offset) установлено на 0. Это используется в нескольких экземплярах FDCAN и будет рассмотрено в следующем уроке.
  • Std Filters Nbr— это количество используемых нами стандартных (ID) фильтров.
    • Мы можем использовать до 128 различных фильтров, настроенных для приема или отклонения сообщений с разными идентификаторами.
    • Я использую только один фильтр.
  • Ext Filters NbrЗначение установлено на 0, поскольку в этом руководстве мы не используем расширенные идентификаторы.
  • Для приема сообщения мы будем использовать RX FIFO 0. Всего мы можем использовать до 64 элементов FIFO, и каждый элемент может хранить до 64 байт данных.
  • Здесь я использую всего один элемент для приема 12 байт данных.
  • Я не использую буферы приема и передачи, поэтому все эти параметры установлены на 0.
  • Блок TX Fifo будет использоваться для отправки данных на шину CAN. Таким образом, здесь я использую один элемент блока TX Fifo для отправки 12 байт данных.

И последнее, что нам нужно сделать, это включитьПрерывание RX Fifo 0Это прерывание будет срабатывать всякий раз, когда мы получим новое сообщение в буфере приема RX Fifo 0.

На этом настройка FDCAN завершена. Теперь давайте рассмотрим код.

Конфигурация фильтра

Как и в обычном CAN-шине, в FDCAN тоже есть фильтры. Здесь всё немного сложнее, поскольку существует множество типов фильтров. Давайте рассмотрим их подробнее.

В FDCAN доступны 4 типа фильтров:

  • Фильтр диапазона (RANGE Filter ) фильтрует сообщения, поступающие от идентификаторов, находящихся в диапазоне от ID1 до ID2.
  • Фильтр DUAL , который фильтрует сообщения, относящиеся исключительно к двум идентификаторам: ID1 и ID2.
  • Фильтр MASK , который фильтрует сообщения на основе идентификатора (ID1) и маски (ID2). Это похоже на то, что мы делали в уроке по CAN, и сегодня мы будем следовать этому принципу.
  • Фильтр диапазона без внешних идентификаторов , который фильтрует данные так же, как и обычный фильтр диапазона, но внешние идентификаторы в этом случае фильтроваться не будут.

Помимо типов фильтров, у нас также есть раздел «Конфигурация фильтров». В этом поле определяется, что следует делать с отфильтрованными сообщениями. Например, следует ли отправлять сообщения в FIFO, отклонять их, помечать как сообщения с высоким приоритетом и т. д.

По сути, вы можете настроить несколько фильтров одновременно, и конфигурация каждого фильтра будет храниться в отдельном индексе фильтров.

В этом уроке я буду использовать фильтр «Маска», и отфильтрованные сообщения будут отправляться в FIFO. Ниже приведена конфигурация для этого.

FDCAN_FilterTypeDef sFilterConfig; sFilterConfig.IdType = FDCAN_STANDARD_ID; sFilterConfig.FilterIndex = 0; sFilterConfig.FilterType = FDCAN_FILTER_MASK; sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; sFilterConfig.FilterID1 = 0x11; sFilterConfig.FilterID2 = 0x11; sFilterConfig.RxBufferIndex = 0; if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK) { /* Filter configuration Error */ Error_Handler(); }

  • Параметр IdType определяет, используем ли мы стандартные или расширенные идентификаторы.
  • Filterindex используется при настройке нескольких фильтров. Поскольку я использую только один фильтр, он установлен на 0.
  • FilterType — это тип используемого нами фильтра. Как я уже упоминал, я использую фильтр MASK.
    • В этом фильтре MASK ID1 (0x11) будет выступать в качестве идентификатора, а ID2 (0x11) — в качестве битов маски.
    • Если вы хотите узнать больше о том, как это работает, я бы посоветовал вам посмотреть видео по ссылке https://youtu.be/JfWlIY0zAIc
  • FilterConfig определяет, что следует делать с сообщениями, проходящими через фильтр. Он настроен на отправку в RX FIFO 0.
  • Параметр RxBufferIndex используется, если вы используете буфер приема (RX Buffer) вместо FIFO, поэтому здесь он установлен на 0.

В заключение функция ConfigFilter настроит указанный выше фильтр.

Кодекс

Начнём с нескольких определений.

FDCAN_TxHeaderTypeDef TxHeader; FDCAN_RxHeaderTypeDef RxHeader; uint8_t TxData[12]; uint8_t RxData[12]; int indx = 0;

  • Здесь я определил заголовки и буферы для передачи и приема.
  • Индексная переменная будет увеличена позже в коде.

В основной функции мы запустим FDCAN и настроим уведомление о новом сообщении в буфере RX Fifo 0.

if(HAL_FDCAN_Start(&hfdcan1)!= HAL_OK) { Error_Handler(); } if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK) { /* Notification Error */ Error_Handler(); }

Здесь FDCAN_IT_RX_FIFO0_NEW_MESSAGE — это флаг прерывания. Он, по сути, включает прерывание для нового сообщения в RX FIFO 0.

Когда в буфер приема RX FIFO 0 поступает новое сообщение, вызывается обработчик прерывания. Мы будем обрабатывать полученные данные внутри этого обработчика прерывания.

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) { if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET) { /* Retreive Rx messages from RX FIFO0 */ if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK) { /* Reception Error */ Error_Handler(); } if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK) { /* Notification Error */ Error_Handler(); } } }

  • Здесь мы скопируем заголовок сообщения в RXHeader , а данные сообщения — в RxData .
  • Мы снова активируем уведомление, поскольку прерывание отключается после каждого вызова.

В основной функции мы настроим заголовок TX перед отправкой сообщения на шину CAN.

TxHeader.Identifier = 0x11; TxHeader.IdType = FDCAN_STANDARD_ID; TxHeader.TxFrameType = FDCAN_DATA_FRAME; TxHeader.DataLength = FDCAN_DLC_BYTES_12; TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; TxHeader.BitRateSwitch = FDCAN_BRS_OFF; TxHeader.FDFormat = FDCAN_FD_CAN; TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; TxHeader.MessageMarker = 0;

  • Идентификатор — это идентификатор передатчика, который будет равен 0x11.
  • В этом руководстве для параметра IdType установлено значение Standard ID, поскольку мы не используем Extended ID.
  • Параметр TxFrameType указывает, отправляем ли мы кадр данных или удаленный кадр. В этом случае он устанавливается в значение Data Frame.
  • Параметр DataLength установлен на 12 байт. Это длина фактических данных, которые мы собираемся отправить.
  • Индикатор ErrorStateIndicator активен и уведомит нас в случае возникновения ошибок при передаче данных.
  • Функция BitrateSwitch отключена, как я уже упоминал, мы будем использовать один и тот же битрейт как для поля арбитража, так и для поля данных.
  • Параметр FDFormat указывает, хотите ли вы использовать стандартный CAN или FD CAN. В данном случае он установлен на FD CAN.
  • Мы не используем TxEvent или MessageMarker.

В цикле while мы будем отправлять данные с интервалом в 1 секунду.

while (1) { for (int i=0; i<12; i++) { TxData[i] = indx++; } if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData)!= HAL_OK) { Error_Handler(); } HAL_Delay (1000); }

  • Здесь мы сначала заполним массив TxData целочисленными значениями.
  • Затем функция HAL_FDCAN_AddMessageToTxFifoQдобавит сообщение в очередь FIFO.
  • После добавления сообщения в очередь FIFO, оно будет передано в шину CAN.
  • Наконец, задержка в 1000 мс обеспечит повторение цикла каждую секунду.

Результат

Ниже представлены изображения, полученные из функции Live Expression в отладчике. Вы можете видеть, что значения TxData и RxData совпадают.

Мы обновляем данные в транзакции TxData, которые затем поступают в буфер FIFO и передаются в транзакцию RxData.