2

There is an ATMEL library that doesn't work with my toolchain (GNU tools for ARM) and I know why, but I don't know why it works for an old YAGARTO and I guess that also for KEIL and IAR

I'm working in an ARMV5 processor (AT91SAM9) that doesn't support unaligned access to ints (4 bytes).

there is a global buffer defined as:

static unsigned char pPageBuffer[AT91C_IFLASH_PAGE_SIZE];

The buffer gets some data and afterwards the data is written to flash, but data has to be taken to flash 4 bytes at a time, thus there is an int pointer called pAlignedSource to take the data 4 bytes at a time.

pAlignedSource = (unsigned int*)pPageBuffer;

But pPAgeBuffer is not necessarily 4 bytes aligned as it is a char array, and pAlignedSource doesn't point to an aligned address. How is it possible that this code is working always in the other toolchain but not in mine?, I already defined the proper CPU to the compiler other than that both compilers get the same code flags.

My problem is that when data gets copied from the buffer to the flash

*pAlignedDestination++ = *pAlignedSource++;

I end with a scrambled version of the data :/, however I fixed this by defining the buffer as

static unsigned int pPageBuffer[AT91C_IFLASH_PAGE_SIZE/4];

And it did the trick, But I am still very curious about this. Why it worked in the other toolchain?

LuisF
  • 33
  • 5
  • How does it "Not Work"? pPageBuffer probably starts on a byte aligned address, and then writing the words should be fine. Things that I'd look out for is violating strict aliasing and endianess problems with what you're doing, but we hav eno way of knowing what your problem is. – IdeaHat Jan 30 '15 at 14:51
  • In case you ask you can get the library [here](http://www.atmel.com/images/at91lib_20100901_softpack_1_5_svn_v8476.zip) in file flashd_eefc.c function FLSHD_Write – LuisF Jan 30 '15 at 14:53
  • It gets the data from the unaligned address but it ends somehow scrambled – LuisF Jan 30 '15 at 14:55
  • I added the cpu flag -mcpu=arm926ej-s also tried -march=armv5te and even -mno-unaligned-access without success, Thanks for the ideas! – LuisF Jan 30 '15 at 15:00
  • 2
    See [stackoverflow list of ARM alignment questions](http://stackoverflow.com/search?q=%5Barm%5D+alignment+is%3Aquestion). I guess this is a public shaming of Atmel. I think this question has value as bad code sometimes works. People often believe that if something works, it is fine. Ie, I often have issue with QA and other developer who don't get this poster's point. Some pointy haired type might conclude the compiler has bugs as it seems to have introduced the problem. – artless noise Jan 30 '15 at 15:41

1 Answers1

2

Writing to unaligned addresses is defined on an ARMv5. You may have CP15 behaviour to alter this. For instance, it may trap or do something unpredicatable for thumb mode. In ARM mode, with STR the lower bits are dropped without trapping. With LDR, the lower bits are masked to form the address, but the data is then rotated depending on the lower bits.

Edit: Also, it is completely possible for one compiler/toolset to use a different alignment for the start of a character buffer. One tool may align everything and another may not. With gcc, you could annotate the buffer with attribute((aligned,4)) or something like that.

Whatever you are doing, it is non-portable (and is undefined for 'C') and you just shouldn't do it; which seems to be the conclusion you came to.

artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Thank you!, I will read about the CP15. It is actually reading from an unaligned address in RAM but I guess it is the same or very similar. The problem is that this is the library as ATMEL supply it you can get the library [here](http://www.atmel.com/images/at91lib_20100901_softpack_1_5_svn_v8476.zip) in file flashd_eefc.c function FLSHD_Write – LuisF Jan 30 '15 at 15:18
  • 1
    Well, there are several questions. What is the state of CP15 and the 'A' bit of the cr1 (bit 1)? Either it may trap or not. Then are you using *thumb* or *ARM* code? If it is *thumb* code, then the result is completely *undefined/undocumented*. However, a vendor like Atmel may know their specific behaviour and rely on it. Also see my edit for a **pure** 'C' type explanation. – artless noise Jan 30 '15 at 15:30