Передача элементов структуры для функционирования в c

#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. Это тоже возможно. Но зависит от программиста и человека, просматривающего код, где выполнять присваивание внутри самой функции ИЛИ возвращать значение из функции.