Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: [lpc2100] Problem with word / dword - access...

2004-02-10 by David Willmore

> i have a problem with word / dword - access when the address is not even / devideable through 4. When i let run the below pr
> ogram i get the following output:
> 
>  00 01 02 03 04 05 06 07 08 09
> 
>  0100 0001 0302 0003 0504 0005 0706 0007 0908 0009
> 
>  03020100 00030201 01000302 02010003 07060504 04070605 05040706 06050407 0B0A090
> 8 080B0A09
> 
> First line is fine, because it is byte access, filled the array with increasing numbers.
> 
> Second line: On word access all accesses on even addresses are wrong. Why is the ARM hardware not correcting this or at leas
> t detecting it (throwing an exception), so you know there is something wrong ?
> 
> Third line: dword (4 Bytes) seems to ignore below 2 bits, only rotating... is it really as it should be ? 

On the ARM as defined by DDI0100E_ARM_ARM.pdf in section 1.2.1 of Part B, page 482, it
says:
1.2.1 memory systems, write buffers and caches
ARM processors and software are designed to be connected to byte-addressed memory.  Word and
halfword accesses to the memory ignore the alignment of the address and access the naturally-aligned value
that is addressed (so a memory access ignores address bits 0 and 1 for word accesses, and ignores bit 0 for
halfword accesses).  The endianness of the ARM processor should normally match that of the memory
system, or be configured to match it before any non-word accesses occur (when the endianness is
configurable and CP15 is implemented, bit[] of CP15 register 1 controls the endianness).

(misspelling and other errors are likely mine)

The LPC210x does not have a CP15, the system control processor, so there is no inbuilt ability to
generate unaligned exceptions.

So, what you're seeing is:
 ((bytearray[ptr & 0xfffffffc + 3] << 24) |
  (bytearray[ptr & 0xfffffffc + 2] << 16) |
  (bytearray[ptr & 0xfffffffc + 1] <<  8) |
   bytearray[ptr & 0xfffffffc + 0]       ) >> ((ptr & 0x3) * 8)  
and then masked to give the element size you're asking for.

I have to ask, what were you expecting to see here?
 ((bytearray[ptr + 3] << 24) |
  (bytearray[ptr + 2] << 16) |
  (bytearray[ptr + 1] <<  8) |
   bytearray[ptr + 0]       )   

This is a microcontroller, so things that aren't absolutely necessary have been stripped off
to save die space and to lower power consumption.  I'm afraid it's not a VAX.

You can always make a macro to wrap around word and half-word accesses to make things look
the way you expect them to.

So, in short, what you're seeing is what is defined, expected, and which ARM processors
have been doing for decades.  And, no, it's not the most programmer friendly thing in
the world.

Does C even define this behavior?  People seem to assume it, but I tend to assume all bets
are off when you cast one type of pointer to another.  Maybe I'm just a pessimist.

Cheers,
David

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.