#c
#c
Вопрос:
У меня есть struct
определение ниже для содержимого фрейма, которое должно быть отправлено через uart.
Последним элементом структуры является последовательность проверки кадров (fsc), которая вычисляется как XOR всех байтов в элементах структуры (len, cmd0, cmd1 и data). У меня есть функция для вычисления fsc ниже.
Мой вопрос в том, как мне передать элементы структуры, к calcFCS()
которым вызывается in build_uart_frame()
?
Большое спасибо
typedef struct uart_frame {
uint8_t sof; /* 1 byte */
uint8_t len; /* 1 bytes */
uint8_t cmd0; /* 1 byte */
uint8_t cmd1;
char data[11]; /* 0 -250 byte */
unsigned char fcs; /* 1 byte */
} uart_frame_t;
//-------------------------------------------------------------------------
// Global uart frame
uart_frame_t rdata;
//-------------------------------------------------------------------------
unsigned char calcFCS(unsigned char *pMsg, unsigned char len) {
unsigned char result = 0;
while(len--) {
result ^= *pMsg ;
}
return(result);
}
//-------------------------------------------------------------------------
// Worker code to populate the frame
int build_uart_frame() {
uart_frame_t *rd = amp;rdata; //pointer variable 'rd' of type uart_frame
// common header codes
rd->sof = 0xFE;
rd->len = 11;
rd->cmd0 = 0x22;
rd->cmd0 = 0x05;
snprintf(rd->data, sizeof(rd->data), "%s", "Hello World");
rd->fcs = calcFCS(?)
return 0;
}
Комментарии:
1.
char data[11]
равно ровно 11 , а не 0-250.chars
Если вам нужна структура с динамическим размером, элемент с переменным размером должен быть последним.2.
calcFCS((unsigned char *)rd, sizeof(uart_frame_t;) - 1)
. Но это работает, только еслиstruct uart_frame
не дополнено (что маловероятно здесь, потому что все члены являются символами).3. Мы либо используем
rd
offsetof
, чтобы переместить указатель на соответствующий элемент и передать его, либо просто передаемrd->member
значение илиamp;rd->member
указатель на элемент … или просто передаем указатель структуры полностью4. Стандартное предупреждение: вам следует избегать (ab) использования структур для сериализации. Они негибкие и подвержены проблемам с заполнением и порядковым номером. Рассмотрите возможность использования специальных функций сериализации, которые преобразуют собственные типы в байты четко определенным образом.
5. @MichaelWalz спасибо, struct uart_frame не дополнен, я не хочу включать элемент struct
sof
в вычисление fcs. Ссылается ли-1
в вашем ответе на это?
Ответ №1:
Как вы говорите
последовательность проверки кадров (fsc), которая вычисляется как XOR всех байтов в элементах структуры (len, cmd0, cmd1 и data)
Вместо того, чтобы передавать все элементы по отдельности, лучше передать указатель на struct uart_frame
Итак, подпись вашей функции должна быть
unsigned char calcFCS(uart_frame* frame)
Комментарии:
1. Если вы передаете указатель на структуру,
calcFCS
можно также установитьfcs
элемент, хотя2. Это тоже возможно. Но зависит от программиста и человека, просматривающего код, где выполнять присваивание внутри самой функции ИЛИ возвращать значение из функции.