Определить порядок байтов uint32_t - PullRequest
0 голосов
/ 28 октября 2011

Я конвертирую приложение vxWorks в Linux.

Раньше у меня было union с word и struct, чтобы при доступе к членам struct ямог бы использовать макет word's для создания моих struct членов.

Однако я не помню, как я понял это, и это работает на коробке vxWorks.В моем экземпляре vxWorks макет выглядит так:

typedef union Status
{
    struct fields
    {
        uint32_t byteA : 1; // <31>
        uint32_t blank : 23; // <30:8>
        uint32_t bytesN : 8; // <7:0>
    } fields;

    uint32_t word;
}

Я уже столкнулся с некоторыми проблемами с порядком байтов при переносе из vxWorks в Linux.Поэтому важно выяснить расположение uint32_t в Linux.

Ответы [ 2 ]

3 голосов
/ 28 октября 2011

Вы можете определить, взяв указатель на int, содержащий значение 0x01, и приведя его к char *. Если первое значение равно нулю, то система имеет порядковый номер с прямым порядком байтов, в противном случае это порядковый номер с прямым порядком байтов.

Вот пример:

#include <inttypes.h>
#include <stdio.h>

int main(void)
{
   uint32_t   val  = 0x01;
   char     * buff = (char *)&val;

   if (buff[0] == 0)
   {
      printf("Big endian\n");
   } else {
      printf("Little endian\n");
   };

   return(0);
}

Я использовал этот метод в Linux, Solaris, OS X и FreeBSD.

1 голос
/ 28 октября 2011

От вашего комментария к другому ответу вы хотите, чтобы все, что было введено в word член union, отображалось в fields.bytesN члене.Чтобы достичь этого, вы должны либо иметь какой-то процесс предварительной сборки, который правильно распределяет битовые поля field после обнаружения машинного порядка байтов, либо создать 2 структуры, одну для старшего и другого для младшего.

typedef union Status
{
    struct fieldsBE
    {
        uint32_t byteA : 1; // <31>
        uint32_t blank : 23; // <30:8>
        uint32_t bytesN : 8; // <7:0>
    } fieldsBE;

    struct fieldsLE
    {
        uint32_t bytesN : 8; // <7:0>
        uint32_t blank : 23; // <30:8>
        uint32_t byteA : 1; // <31>
    } fieldsLE;

    uint32_t word;
};

int main()
{
  bool isBigEndian = DetectEndianness(); // returns true if big endian

  Status status;

  status.word = 40;

  if( isBigEndian ) {
    uint8_t bytesN = status.fieldsBE.bytesN;

  } else {
    uint8_t bytesN = status.fieldsLE.bytesN;

  }
}

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

...