Реализовать контроллер кадров UART

Я программирую на плате STM32, и я не понимаю, как использовать мои периферийные устройства: опрос, прерывание, DMA, прерывание DMA...

На самом деле, я кодировал модуль UART, который отправляет базовые данные, и он работает в режиме опроса, прерывания и DMA.

Но я хотел бы иметь возможность отправлять и получать конкретные кадры с переменной длиной, например:


[НАЧАЛО | LGTH | CMD_ID | ДАННЫЕ (LGTH) | CRC ]


У меня также есть датчики, и я хотел бы взаимодействовать полученные данные в этих кадрах UART с датчиками.

Итак, я не понимаю:

  • как запрограммировать модуль UART для работы в режиме "кадр"? (буфер? круговой DMA? прерывание? где, когда..)

  • когда я могу отправить или получить кадр с помощью моего UART, каков наилучший способ взаимодействия с датчиками? (внутри прерывания таймера "в автомате" с переменной extern? ...)

Вот мое дерево библиотек

В будущем, идея заключается в том, чтобы нести это приложение в свободном доступе.

Спасибо!

2 ответа

Абсолютно в DMA, когда это доступно.

У вас есть один большой (хорошее решение циклическое) буфер, и вы просто пишете данные с одной стороны. Если DMA еще не работает, вы запускаете DMA с вашим буфером.

Если DMA работает, вы просто записываете свои данные в буфер и ждете полного прерывания передачи DMA.

Позже в этом прерывании вы увеличиваете указатель чтения буфера (поскольку вы уже отправили некоторые данные) и проверяете, доступны ли какие-либо данные для отправки через DMA. Установите адрес памяти в DMA и количество байтов в буфере для отправки.

Опять же, когда происходит DQ TC IRQ, повторите процесс.

FRAME не поддерживается, но только в виде простых байтов. Это означает, что вы должны "изобрести" свой собственный протокол фрейма и использовать его в приложении.

Позже, когда вы захотите отправить эту FRAME через UART, вы должны:

  • Записать начальный байт в буфер
  • Напишите другие байты заголовка
  • Напишите фактические данные
  • Запишите стоп-байты /CRC/ что угодно
  • Проверьте, не работает ли DMA, если нет, запустите его.

Обычно я использую эту концепцию фрейма:


[СТАРТ, АДРЕС, CMD, LEN, ДАННЫЕ, CRC, СТОП]

  • START: начальный байт, указывающий начало кадра
  • АДРЕС: адрес устройства, когда на шине используется несколько устройств
  • CMD: идентификатор команды
  • LEN: 2 байта для длины данных
  • ДАННЫЕ: фактические данные в байтах переменной длины
  • CRC: 2 байта для CRC, включая: адрес, cmd, len, данные
  • STOP: стоп-байт, указывающий конец кадра

Вот как я делаю это в каждом проекте, где это необходимо. Это не использует процессор для отправки данных, просто устанавливает DMA и начинает передачу.

С точки зрения приложения, вам просто нужно создать send_send(data, len) функция, которая создаст кадр и поместит его в буфер для передачи.

Размер буфера должен быть достаточно большим, чтобы соответствовать вашим требованиям:

  • Сколько данных в определенное время (это продолжается или много данных за небольшое время)
  • UART скорость передачи

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

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

Только когда будет получен полный, действительный кадр, необходимо сигнализировать о каком-то семафоре / событии и запрашивать запуск планировщика, в противном случае вы можете обработать любую ошибку протокола, как вам требуется - возможно, передать какое-нибудь сообщение "error-repeat" и сбросить состояние -машина, чтобы дождаться начала байта Nexx.

Если вы используете DMA для этого, то переменная длина кадра будет неудобной, и вам все равно придется повторять полученные данные для проверки вашего протокола:(

Мне кажется, что DMA не подходит для этого...

РЕДАКТИРОВАТЬ: если нет вытесняющей многозадачности, тогда забудьте обо всех вышеупомянутых семафорах:) Тем не менее, легче проверить логический флаг 'validFrameRx', чем анализировать данные блока DMA.

Другие вопросы по тегам