Forum Discussion
structure alignement problem ?
I had declared a buffer to read the contents of a flash block as following
BYTE buffer[0x10000]; this buffer should content an array of a structure defined as following # define BYTE alt_u8# define WORD alt_u16# define DWORD alt_u32 typedef struct s_partition_record { DWORD magig; WORD boot; WORD type; char name[33]; char version[9]; DWORD startblock; DWORD endblock; DWORD cts; WORD crc; WORD record_crc; BYTE pad[62]; } PARTITIONRECORD; to get a pointer to the first structure I used the following int recordstartadd; PARTITIONRECORD *pr_temp; recordstartadd=recno*sizeof(PARTITIONRECORD); pr_temp=(PARTITIONRECORD*)(buffer+recordstartadd); I made a printf for value pr_temp->magig, which should be 0x5a0F5A0F but it returned only 0x5A0F0000 ! this seems to be some alignement problem, I checked the buffer pointer and it was aligned to 16 bit. I changed the buffer declaration to BYTE __attribute__((aligned(4))) buffer1[0x10000]; and from now on, printf returned the correct value 0x5a0F5A0F My question is, is the user responsible to pay attention of the alignement or is this normally a job of the compiler. Why is the buffer not automatically aligned at 32bit.3 Replies
- Altera_Forum
Honored Contributor
Your variable 'buffer' is an array of bytes (alt_u8), so when you declare it, you are not guaranteed it will be aligned on word boundaries, only byte boundaries since that's it's type. You then assign your structure pointer an address based on where 'buffer' was put. Therefore, you can only expect that your structure pointer is going to be aligned on a byte boundary. If you declare your buffer as an array of words (alt_u32), not bytes, I imagine it's starting address will be on a word boundary, and you'll be in good shape.
- Altera_Forum
Honored Contributor
As I experienced, the nios processor is ONLY able to read 16 Bit Words from 2 byte aligned memory and 32 Bit words from 4 byte aligned memory.
So one needs to be very carefull with doing memcpy on structures. For example, if your structure contains any INT or FLOAT and you copy it to an unaligned address, all reads and write will automatically cut address bit 0 or bit 0 and 1 on read and write access. try this simple testprogramm, to see what the proccessor is doing...
I received this output:#include <stdio.h> int main() { short bufs= {0x1122,0x3344,0x5566,0x7788}; int bufi= {0x11223344,0x55667788}; int *pi; short *ps; // Test Byte Displacement on 4byte load instruction pi=bufi; printf("pi : %x: %x\n",pi,*pi); pi=(void*) ((int)pi+1); printf("pi+1 : %x: %x\n",pi,*pi); pi=(void*) ((int)pi+1); printf("pi+2 : %x: %x\n",pi,*pi); pi=(void*) ((int)pi+1); printf("pi+3 : %x: %x\n",pi,*pi); pi=(void*) ((int)pi+1); printf("pi+4 : %x: %x\n",pi,*pi); // Test Byte Displacement on 2byte load instruction ps=bufs; printf("ps : %x: %x\n",ps,(int)*ps); ps=(void*) ((int)ps+1); printf("ps+1 : %x: %x\n",ps,(int)*ps); ps=(void*) ((int)ps+1); printf("ps+2 : %x: %x\n",ps,(int)*ps); ps=(void*) ((int)ps+1); printf("ps+3 : %x: %x\n",ps,(int)*ps); ps=(void*) ((int)ps+1); printf("ps+4 : %x: %x\n",ps,(int)*ps); return 0; }
Wonderfull, isn't it? http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/mad.gif This took me HOURS to find out...pi : 7ffffcc: 11223344 pi+1 : 7ffffcd: 11223344 pi+2 : 7ffffce: 11223344 pi+3 : 7ffffcf: 11223344 pi+4 : 7ffffd0: 55667788 ps : 7ffffc4: 1122 ps+1 : 7ffffc5: 1122 ps+2 : 7ffffc6: 3344 ps+3 : 7ffffc7: 3344 ps+4 : 7ffffc8: 5566 - Altera_Forum
Honored Contributor
Yes, that's bad, but it is common to many microcontrollers :-8 ... For example, also ARM has the same problem, whereas x86 do not...
PJ