Использование кольцевого буфера через UART

Я настраиваю протокол UART, который позволяет обмениваться данными между двумя платами; Мастер-плата и ведомая плата. Связь между ними будет такой:
Пример 1:
Мастер [Tx] -- GET_VALUE--> [Rx] Slave
Master [Rx] <-- 0x05 -------- [Tx] Slave

Пример 2:
Master [Tx] -- GET_STATUS -----------> [Rx] Slave
Master [Rx] <-- I_AM_BUSY ------------ [Tx] Slave

Пример 3:
Master [Tx] -- START_OPERATION --> [Rx] Slave
Master [Rx] <----------ACK------------[Tx] Slave

Размер данных составляет 1 байт для большей части потока данных между двумя картами. Вот почему я собираюсь использовать макросы для определения этих команд:

Пример:

  #define GET_VALUE 0x05
  #define START_OPERATION 0x06
  etc ...

В дополнение к этим 1-байтовым данным, между двумя платами должен передаваться только один элемент, размер которого не равен 1 байту. На самом деле я готов использовать сериализацию для передачи структуры данных по UART с использованием кольцевого буфера FIFO.

Пример:
Master [Tx] -- GET_STRUCTURE ------------> [Rx] Slave
Master [Rx] <----------STRUCTURE-------- ----[Tx] Ведомый

typedef struct{
uint8_t var1;
uint8_t var2;
uint8_t var3;
}MyStructTypeDef;

Передается по UART в формате «имя_переменной:значениеXXX»:

переменная1:123XXXпеременная2:456XXXпеременная3:789XXX

ХХХ — разделитель

Мой вопрос: если 99% потока данных имеет размер 1 байт и только 1% потока данных не имеет размер 1 байт, следует ли использовать циклический буфер только для получения структуры? Есть ли лучший способ стандартизировать длину данных, передаваемых через UART?

У вас есть две различные трудности здесь. Во-первых, это разработка 1-байтового протокола, который также может без путаницы перемещать произвольные значения. Если вам не нужна скорость, вы можете рассмотреть буквы и цифры; или используя 7-битный числовой формат с 8-м битом, зарезервированным для ваших специальных кодов состояния. С точки зрения буферизации, это, как правило, не о значении , а о том, сможете ли вы обрабатывать данные по мере их поступления. Если это так, у вас может быть просто буфер «собираемая структура», а не круговой. Если нет, вы, вероятно, захотите передать все через буфер между ISR и потребителем.
это шаг блокировки или асинхронный, когда MASTER отправляет более одной команды перед проверкой ответов?
@Jasen Это асинхронно
Было бы намного проще отправить вашу структуру в виде 4 байтов: один байт говорит о том, что происходит (назовите его THIS_IS_MY_STRUCTURE или как-то еще), а затем 3 байта структуры. Это однобайтовые переменные, просто отправьте байт вместо преобразования его в десятичное число.

Ответы (2)

Может ли мастер ждать ответов на UART? Может ли он собирать и обрабатывать полученные символы достаточно быстро, чтобы избежать переполнения? Если нет, то вам нужен буфер.

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

Я хочу использовать сериализацию для передачи структуры данных... в этом формате "variable_name:valueXXX"...

Есть ли лучший способ стандартизировать длину данных, передаваемых через UART?

Я предполагаю, что 'XXX дополняет строку до фиксированной длины. Было бы более эффективно создать строку переменной длины с разделителями из одного символа или даже отправить числа в необработанном двоичном формате, но если пропускная способность не является проблемой, то то, что вы делаете, в порядке.

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

Master [Tx] -- GET_VALUE--> [Rx] Slave
Master [Rx] <-- 0x05 -------- [Tx] Slave 

беспокоит. Может ли «значение» быть любым двоичным числом? Если да, то как узнать, что это не ответ на какую-то другую команду? Критические ответы, такие как I_AM_BUSYи , ACKдолжны иметь уникальные значения, которые не могут отображаться в других данных.

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

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

для отправки ему нужно знать, какие вещи нужно отправить