Как я могу упаковать некоторую информацию из структуры в 2-байтовый буфер? - PullRequest
0 голосов
/ 04 мая 2019

У меня есть структура в этой форме:

struct args {
  uint16_t portnum;   /**< port number */
  const char *portstr;/**< port number as string */
  cmd_t cmd;          /**< command (GET, SET) */
  uint8_t value;      /**< set value */
  uint8_t id;         /**< device id */
};

struct args arguments =
    { DEFAULT_PORTNUM, DEFAULT_PORTNUM_STR, UNDEF, 0, 0 };

Мне нужно извлечь "id, cmd, value" из аргументов и сохранить их в 2-байтовом буфере в этой форме:

image

arguments.value имеет максимальное значение 127, поэтому 7-й бит не используется

Я пробовал это, но это не работает

uint8_t buf[2];
buf[0] = arguments.cmd | arguments.id << 2;
buf[1] = arguments.value >> 1;

if(send(sockfd, buf, 2, 0) < 0 ){
   //error
}

Ответы [ 2 ]

1 голос
/ 04 мая 2019

cmd_t - enum typedef enum {GET = 0, SET = 1, UNDEF = 2} cmd_t;
ID ∈ [0, 63],
ЗНАЧЕНИЕ ∈ [0, 127]

Только не сдвигай value вправо. >> 1 (логически) равно делению на 2 / 2.

buf[0] = arguments.cmd | arguments.id << 2;
buf[1] = arguments.value;

Бит MSB buf[1] «не используется» - будет установлен в ноль, начиная с arguments.value.

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

assert(0 <= arguments.cmd && arguments.cmd <= 2);
assert(0 <= arguments.id && arguments.id <= 63);
assert(0 <= arguments.value && arguments.value <= 127);

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

buf[0] = (arguments.cmd & 0x3) | ((arguments.id << 2) & 0xfc);
buf[1] = arguments.value & 0x7f;
0 голосов
/ 04 мая 2019

Будьте более точными с маскировкой битов, которые вы хотите сохранить или отбросить

buf[0] = (arguments.cmd & 0x03) | ((arguments.id & 0x3f) << 2);
buf[1] = (arguments.value >> 1) & 0x7f;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...