Я настраиваю протокол 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?
Может ли мастер ждать ответов на UART? Может ли он собирать и обрабатывать полученные символы достаточно быстро, чтобы избежать переполнения? Если нет, то вам нужен буфер.
Если самое длинное сообщение помещается в буфер, и вы сбрасываете его при отправке каждой команды, тогда оно не должно быть циклическим.
Я хочу использовать сериализацию для передачи структуры данных... в этом формате "variable_name:valueXXX"...
Есть ли лучший способ стандартизировать длину данных, передаваемых через UART?
Я предполагаю, что 'XXX дополняет строку до фиксированной длины. Было бы более эффективно создать строку переменной длины с разделителями из одного символа или даже отправить числа в необработанном двоичном формате, но если пропускная способность не является проблемой, то то, что вы делаете, в порядке.
Вы также можете подумать о том, что делать, если ведущий и ведомый устройства не синхронизированы. Например, если ведомое устройство отправляет структуру, а ведущее устройство ожидает ответа на другую команду, некоторые символы в сообщении структуры могут быть неверно истолкованы как допустимые ответы. Также это,
Master [Tx] -- GET_VALUE--> [Rx] Slave
Master [Rx] <-- 0x05 -------- [Tx] Slave
беспокоит. Может ли «значение» быть любым двоичным числом? Если да, то как узнать, что это не ответ на какую-то другую команду? Критические ответы, такие как I_AM_BUSY
и , ACK
должны иметь уникальные значения, которые не могут отображаться в других данных.
у вас может быть ISR, который обслуживает прерывание последовательного приема, записывая непосредственно в переменные, ему нужно будет отслеживать свое собственное состояние, чтобы он знал, куда писать.
вам может понадобиться мьютекс, так как сбои обновления могут быть проблемой.
для отправки ему нужно знать, какие вещи нужно отправить
Крис Стрэттон
Джейсен
Прида
пользователь 253751