Yahoo Groups archive

Lpc2000

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

Thread

Problem with word / dword - access...

Problem with word / dword - access...

2004-02-10 by lpc2100@web.de

Hello,

i have a problem with word / dword - access when the address is not even / devideable through 4. When i let run the below program 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 least 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 ? 

I found it during porting a software to LPC2106, and it costs me hours to find the wrong values. And i am still not sure if i have catched all the problems.

Have a look at the following example: 
(Pay attention, i have cut out not relevant parts, but i hope you can still see my problem)

int main(void)
{
    unsigned char   bytearray[256];
    unsigned char  *charptr;
    unsigned short *wordptr;
    unsigned long  *dwordptr;
    int i;

    // Init cut out here...

    for(i = 0;i < 256; i++) bytearray[i] = i;
    
    for(i = 0;i < 10; i++)
    {
        charptr = (unsigned char *)&bytearray[i];
        DebugPutString(" ");
        DebugPutBYTE(*charptr);
    }

    DebugPutString("\r\n\r\n");
    
    for(i = 0;i < 10; i++)
    {
        wordptr = (unsigned short *)&bytearray[i];
        DebugPutString(" ");
        DebugPutWORD(*wordptr);
    }
    
    DebugPutString("\r\n\r\n");
    
    for(i = 0;i < 10; i++)
    {
        dwordptr = (unsigned long *)&bytearray[i];
        DebugPutString(" ");
        DebugPutDWORD(*dwordptr);
    }
    
    while(1);
    
}


______________________________________________________________________________
Erdbeben im Iran: Zehntausende Kinder brauchen Hilfe. UNICEF hilft den
Kindern - helfen Sie mit! https://www.unicef.de/spe/spe_03.php

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

2004-02-10 by Jan Szymanski

Try the following instead:
 
union 
 {
 char c[256];
 short i[128];
 long l[64];
 }mydata;
otherwise you have to align 4
Show quoted textHide quoted text
-----Original Message-----
From: lpc2100@... [mailto:lpc2100@...] 
Sent: Wednesday, February 11, 2004 06:58
To: lpc2100@yahoogroups.com
Subject: [lpc2100] Problem with word / dword - access...


Hello,

i have a problem with word / dword - access when the address is not even
/ devideable through 4. When i let run the below program 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 least 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 ? 

I found it during porting a software to LPC2106, and it costs me hours
to find the wrong values. And i am still not sure if i have catched all
the problems.

Have a look at the following example: 
(Pay attention, i have cut out not relevant parts, but i hope you can
still see my problem)

int main(void)
{
    unsigned char   bytearray[256];
    unsigned char  *charptr;
    unsigned short *wordptr;
    unsigned long  *dwordptr;
    int i;

    // Init cut out here...

    for(i = 0;i < 256; i++) bytearray[i] = i;
    
    for(i = 0;i < 10; i++)
    {
        charptr = (unsigned char *)&bytearray[i];
        DebugPutString(" ");
        DebugPutBYTE(*charptr);
    }

    DebugPutString("\r\n\r\n");
    
    for(i = 0;i < 10; i++)
    {
        wordptr = (unsigned short *)&bytearray[i];
        DebugPutString(" ");
        DebugPutWORD(*wordptr);
    }
    
    DebugPutString("\r\n\r\n");
    
    for(i = 0;i < 10; i++)
    {
        dwordptr = (unsigned long *)&bytearray[i];
        DebugPutString(" ");
        DebugPutDWORD(*dwordptr);
    }
    
    while(1);
    
}


________________________________________________________________________
______
Erdbeben im Iran: Zehntausende Kinder brauchen Hilfe. UNICEF hilft den
Kindern - helfen Sie mit! https://www.unicef.de/spe/spe_03.php



  _____  

Yahoo! Groups Links


*	To visit your group on the web, go to:
http://groups.yahoo.com/group/lpc2100/
  

*	To unsubscribe from this group, send an email to:
lpc2100-unsubscribe@yahoogroups.com
<mailto:lpc2100-unsubscribe@yahoogroups.com?subject=Unsubscribe> 
  

*	Your use of Yahoo! Groups is subject to the Yahoo! Terms of
Service <http://docs.yahoo.com/info/terms/> .

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

Re: Problem with word / dword - access...

2004-02-10 by robertadsett

--- In lpc2100@yahoogroups.com, David Willmore <willmore@o...> wrote:
> 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.
AFAIR the only guarantee C give is if you assign any given pointer to
a void pointer and back again you will not lose any information.  Some
implementations have trouble meeting even that.

Robert

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.