Page 1 of 1

packed structure macros for different ports

Posted: Mon Jul 02, 2012 6:32 pm
by Badger
I'm working on a USB Mass Storage driver, and this involves handling lots of structured SCSI data packets. It would make everything much nicer if we could reliably use packed structures in a platform (compiler) independent way.

Here's an example of a struct from the LUFA usb library:

Code: Select all

      typedef struct
      {
         uint32_t Signature; /**< Command block signature, must be \ref MS_CBW_SIGNATURE to indicate a valid Command Block. */
         uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */
         uint32_t DataTransferLength; /**< Length of the optional data portion of the issued command, in bytes. */
         uint8_t  Flags; /**< Command block flags, indicating command data direction. */
         uint8_t  LUN; /**< Logical Unit number this command is issued to. */
         uint8_t  SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array. */
         uint8_t  SCSICommandData[16]; /**< Issued SCSI command in the Command Block. */
      } ATTR_PACKED MS_CommandBlockWrapper_t;


As you can see they have a macro ATTR_PACKED which is defined for each compiler. for gcc:

Code: Select all

#define ATTR_PACKED                     __attribute__ ((packed))


I don't know anything about the other compilers that chibios supports, having never used them, but if they have similar directives for forcing a structure to be packed, could chibios include similar macros?

Re: packed structure macros for different ports

Posted: Mon Jul 02, 2012 6:36 pm
by Giovanni
Probably that is an error, other compilers do not support __attribute__. I have to verify this.

That macros were taken from lwIP but it is possible a better solution could be find, please feel free to propose and discuss.

Giovanni

Re: packed structure macros for different ports

Posted: Mon Jul 02, 2012 6:38 pm
by Badger
The macro I posted there is valid for GCC, I'm assuming it probably isn't valid for other compilers but I am hopeful that they might have a similar mechanism we could exploit / somehow wrap the struct. Otherwise I guess it will have to be done via macros!

Re: packed structure macros for different ports

Posted: Wed Jul 04, 2012 12:04 am
by Badger
I've done a little research into the compilers support for 'packed structs'.

RVCT:
Packed structures

A packed structure is one where the alignment of the structure, and of the fields within it, is always 1.

You can pack specific structures with the __packed qualifier. Alternatively, you can use #pragma pack(n) to make sure that any structures with unaligned data are packed. There is no command-line option to change the default packing of structures.


an example:

Code: Select all

__packed struct foo
{
    char one;
    short two;
    char three;
    int four;
} c;


It looks like RVCT also supports __attribute__:

Code: Select all

struct
{
    char a;
    int b __attribute__ ((packed));
} Variable_Attributes_packed_0;


IAR
Using packed data structures

Code: Select all

__packed struct Packed_Info {  
  u8  Var8a;
  u16 Var16a;
  u8  Text[4];
};


I just searched for packed struct support in Cosmic and came across some packed support in chibios: PACK_STRUCT_STRUCT PACK_STRUCT_BEGIN PACK_STRUCT_END. is this achieving the same thing as I am proposing?

Re: packed structure macros for different ports

Posted: Wed Jul 04, 2012 7:47 am
by Giovanni
Hi,

Thanks for the info, I have to find a solution for IAR now. I wouldn't bother about STM8 compilers, being an 8 bits architecture the structures are naturally packed.

Giovanni

Re: packed structure macros for different ports

Posted: Fri Aug 24, 2012 1:04 pm
by lawrenceais
I find complie problem in lwip. in ip_addr.h

Code: Select all

PACK_STRUCT_BEGIN
struct ip_addr_packed {
  PACK_STRUCT_FIELD(u32_t addr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END


In Chibios, chtypes.h, it defined as

Code: Select all

#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__((packed))
#define PACK_STRUCT_END

For IAR, it becomes:

Code: Select all

struct Packed_Info {  
  u8  Var8a;
  u16 Var16a;
  u8  Text[4];
}__attribute__((packed));
It do not work.


It need to define as below.

Code: Select all

[color=#FF0000]__packed[/color] struct Packed_Info {  
  u8  Var8a;
  u16 Var16a;
  u8  Text[4];
};



Change the definition below:

Code: Select all

#define PACK_STRUCT_BEGIN   __packed
#define PACK_STRUCT_STRUCT   
#define PACK_STRUCT_END

Re: packed structure macros for different ports

Posted: Fri Aug 24, 2012 1:29 pm
by Giovanni
I had totally forgotten this...

Thanks for reminding, I committed the change in the repository (bug 3561279).

Giovanni