Hi,
How to tell CW compiler to pack structs?
#pragma pack(1) gives an "Illegal pragma" warning and does not pack variables.
The compiler generates dummy byte between variables:
typedef struct {
uint_8 channel;
uint_16 value;
}ADC_Value_t;
When communicating with other systems the struct need to be packed.
~Mark
Solved! Go to Solution.
Hello,
You can use the following approach to align the struct:
typedef struct
{
unsigned long ChunkID __attribute__((aligned (4)));//4 bytes = "RIFF" 0x52494646 big-endian form
unsigned long ChunkSize __attribute__((aligned (4)));//4 bytes
unsigned long Format __attribute__((aligned (4))); //4 bytes = "WAVE" 0x57415645 big-endian form
unsigned long Subchunk1ID __attribute__((aligned (4))); //4 bytes = "fmt" 0x666d7420 big-endian form
unsigned long Subchunk1Size __attribute__((aligned (4))); //4 bytes
unsigned short AudioFormat __attribute__((aligned (2)));//2 bytes: 0 =???; 1 = Linear quantization; Others = compression
unsigned short NumChannels __attribute__((aligned (2)));//2 bytes: Mono = 1; Stereo = 2; etc.
unsigned long SampleRate __attribute__((aligned (4)));//4 bytes: 8000, 44100, etc.
unsigned long ByteRate __attribute__((aligned (4)));//4 bytes: SampleRate * NumChannels * BitsPerSample/8
unsigned short BlockAlign __attribute__((aligned (2)));//2 bytes: NumChannels * BitsPerSample/8
unsigned short BitsPerSamples __attribute__((aligned (2)));//2 bytes: 8 = 8 bits; 16 = 16 bits; etc.
unsigned long Subchunk2ID __attribute__((aligned (4)));//4 bytes = "data" 0x64617461 big-endian form
unsigned long Subchunk2Size __attribute__((aligned (4)));//4 bytes: NumSamples * NumChannels * BitsPerSample/8
unsigned char x __attribute__((aligned (1)));
// unsigned long Data;//(ChunkSize) bytes
} WAVE_FILE;
Best Regards,
Luis
Hi Mark,
I found out how to do two things: turn on checking for structures being padded and how to ensure the structure parameters are packed. I haven't found out how to globally set the packing option.
The below #if has comments to explain.
#if
1 //DES test for customer MarkP from forums
#pragma
warn_padding on //turns on warning but have to visually check if you get a warning...other settings [off | reset].
typedef
struct{
volatileuint_8channel__attribute__((aligned (1))); //DES changing 1 to a 4 and recompile to see warning
volatileuint_16value__attribute__((aligned (1))); //DES not really needed but if you were to add to struct handy to already have in code
}
ADC_Value_t;
#endif
Warning in console when aligned(4):
(C:\Freescale\FreescaleMQX3.7\mqx\examples\adc\adc_demo.c|158|1|11|6463|11)
=}ADC_Value_t;
>1 pad byte(s) inserted after data member 'value'
Alternatively you could turn on the Pad Bytes Added (full) option in the ARM compiler Warnings settings and you will see a number of struct warnings about bytes being padded.
Hope this helps.
Regards,
David
Its been a while but I thought CW used
#pragma options align=packed
#pragma options align=reset
pairs?
Hello,
You can use the following approach to align the struct:
typedef struct
{
unsigned long ChunkID __attribute__((aligned (4)));//4 bytes = "RIFF" 0x52494646 big-endian form
unsigned long ChunkSize __attribute__((aligned (4)));//4 bytes
unsigned long Format __attribute__((aligned (4))); //4 bytes = "WAVE" 0x57415645 big-endian form
unsigned long Subchunk1ID __attribute__((aligned (4))); //4 bytes = "fmt" 0x666d7420 big-endian form
unsigned long Subchunk1Size __attribute__((aligned (4))); //4 bytes
unsigned short AudioFormat __attribute__((aligned (2)));//2 bytes: 0 =???; 1 = Linear quantization; Others = compression
unsigned short NumChannels __attribute__((aligned (2)));//2 bytes: Mono = 1; Stereo = 2; etc.
unsigned long SampleRate __attribute__((aligned (4)));//4 bytes: 8000, 44100, etc.
unsigned long ByteRate __attribute__((aligned (4)));//4 bytes: SampleRate * NumChannels * BitsPerSample/8
unsigned short BlockAlign __attribute__((aligned (2)));//2 bytes: NumChannels * BitsPerSample/8
unsigned short BitsPerSamples __attribute__((aligned (2)));//2 bytes: 8 = 8 bits; 16 = 16 bits; etc.
unsigned long Subchunk2ID __attribute__((aligned (4)));//4 bytes = "data" 0x64617461 big-endian form
unsigned long Subchunk2Size __attribute__((aligned (4)));//4 bytes: NumSamples * NumChannels * BitsPerSample/8
unsigned char x __attribute__((aligned (1)));
// unsigned long Data;//(ChunkSize) bytes
} WAVE_FILE;
Best Regards,
Luis
Thank you for your answers.
There is also another potential problem, is the uint_16 variable big or little endian.
Is it compatible with another system?
Solved like this:
typedef struct {
uint_8 channel;
uint_8 valueHi;
uint_8 valueLo;
}ADC_Value_t;
~Mark
Hi,
I have aligned structure members something like this:
struct USB_SysInfoResponse
{
uint_16 version;// __attribute__((aligned (2)));
uint_8 configuration __attribute__((aligned (1)));
};
After doing this i can still get the size of struct as 4bytes, the result should have been 3bytes.
To have effect fo __attribute what needs to added in the code?
Regards,
Raghu