Yahoo Groups archive

Lpc2000

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

Thread

LPC2148 and words on odd addresses.

LPC2148 and words on odd addresses.

2006-04-29 by struer_trace

Hey,

I started messing around with an LPC2148 this week, and until now
everything has just been great. The CPU is just amazing compared to
what I have been working with before. I'm porting a project I did for
the HCS12 series of CPU's to this ARM.

But one thing is very different from what I'm used to. This LPC2148
can only access 16bit and 32bits words within even addresses. (As far
as I understand from the manual).

And that has become a problem for me when porting my code. Because I
have a struct like this:

typedef struct {
    uint8       ucJBC[3];                         // Jump to bootstrap
code
    uint8       cOEMid[8];                        // OEM ID Name of
the formatting OS
    uint16      uiBytesPrSector;
    uint8       ucSectorsPrCluster;               //
... etc.
}

When I compile this it's not possible to get the correct result from
the uiBytesBeSector because it's placed on a odd address. So my
question is... How do I get the correct result from words aligned odd?

And is it really impossible to make a struct like this? Do I really
have to make all my structs byte even or make it purely by 16 and 32
bit words?

I'm using CrossStudio for ARM 1.5 Evaluation and the MAM is set to mode 2.

Thanks in advance!

Best regards
  Jan Thogersen

Re: LPC2148 and words on odd addresses.

2006-04-29 by brendanmurphy37

Hi,

When you say "it's not possible to get the correct result from
the uiBytesBeSector" is this something you've seen in practice, or 
just an assumption you're making?

The language definition allows compilers to place fields within 
structures wherever they want. Typically, padding fields are added 
to ensure the allignment rules of the target processor are met. This 
is why it is dangerous to make any assumptions about how fields are 
actually stored in memory.

If you're using such a struct to help define the structure of fields 
in memory (e.g. in data recived in a particular format on a 
communications link), it is non-portable. You can try and use some 
form of "packed" type modifier to try and sort this out, but this is 
also non-portable. The safest way around this is to read the data a 
byte at a time into your structure. 

In summary: if you declare the structure shown below, you shold have 
no problems, unless you're doing something that makes assumptions 
about how the fields are stored (e.g. type-casting a pointer to such 
a structure to a pointer to some other type or memory buffer).

Brendan

--- In lpc2000@yahoogroups.com, "struer_trace" <jan@...> wrote:
>
> Hey,
> 
> I started messing around with an LPC2148 this week, and until now
> everything has just been great. The CPU is just amazing compared to
> what I have been working with before. I'm porting a project I did 
for
> the HCS12 series of CPU's to this ARM.
> 
> But one thing is very different from what I'm used to. This LPC2148
> can only access 16bit and 32bits words within even addresses. (As 
far
> as I understand from the manual).
> 
> And that has become a problem for me when porting my code. Because 
I
> have a struct like this:
> 
> typedef struct {
>     uint8       ucJBC[3];                         // Jump to 
bootstrap
> code
>     uint8       cOEMid[8];                        // OEM ID Name of
> the formatting OS
>     uint16      uiBytesPrSector;
>     uint8       ucSectorsPrCluster;               //
> ... etc.
> }
> 
> When I compile this it's not possible to get the correct result 
from
> the uiBytesBeSector because it's placed on a odd address. So my
> question is... How do I get the correct result from words aligned 
odd?
> 
> And is it really impossible to make a struct like this? Do I really
> have to make all my structs byte even or make it purely by 16 and 
32
> bit words?
> 
> I'm using CrossStudio for ARM 1.5 Evaluation and the MAM is set to 
mode 2.
Show quoted textHide quoted text
> 
> Thanks in advance!
> 
> Best regards
>   Jan Thogersen
>

Re: [lpc2000] Re: LPC2148 and words on odd addresses.

2006-04-29 by Jan Thogersen

Hi,

It makes a lot of sense what you are saying. What I was trying to do was 
moving bytes from a SD card into the structure.
The structure was made to follow the format of which the bytes was 
aligned on the SD card. I thought that this was a very beautiful way of 
doing it. I have seen code grabbing the struct byte by byte. However, 
when I ran this code on a HCS12 CPU then I could just make a memcpy into 
the struct and that was it. It was way more code size effective and much 
nicer to look at.

But I get your point about the portability! So there is two ways I can 
solve this problem... Right? Either give the compiler a pragma to pack 
the struct and live with the portability problems or rewrite my code to 
grab the protocol byte by byte.

Best regards
   Jan

brendanmurphy37 wrote:
Show quoted textHide quoted text
>
> Hi,
>
> When you say "it's not possible to get the correct result from
> the uiBytesBeSector" is this something you've seen in practice, or
> just an assumption you're making?
>
> The language definition allows compilers to place fields within
> structures wherever they want. Typically, padding fields are added
> to ensure the allignment rules of the target processor are met. This
> is why it is dangerous to make any assumptions about how fields are
> actually stored in memory.
>
> If you're using such a struct to help define the structure of fields
> in memory (e.g. in data recived in a particular format on a
> communications link), it is non-portable. You can try and use some
> form of "packed" type modifier to try and sort this out, but this is
> also non-portable. The safest way around this is to read the data a
> byte at a time into your structure.
>
> In summary: if you declare the structure shown below, you shold have
> no problems, unless you're doing something that makes assumptions
> about how the fields are stored (e.g. type-casting a pointer to such
> a structure to a pointer to some other type or memory buffer).
>
> Brendan
>

Re: [lpc2000] Re: LPC2148 and words on odd addresses.

2006-04-29 by Robert Adsett

At 06:18 PM 4/29/06 +0200, Jan Thogersen wrote:
>It makes a lot of sense what you are saying. What I was trying to do was
>moving bytes from a SD card into the structure.
>The structure was made to follow the format of which the bytes was
>aligned on the SD card. I thought that this was a very beautiful way of
>doing it. I have seen code grabbing the struct byte by byte. However,
>when I ran this code on a HCS12 CPU then I could just make a memcpy into
>the struct and that was it. It was way more code size effective and much
>nicer to look at.
>
>But I get your point about the portability! So there is two ways I can
>solve this problem... Right? Either give the compiler a pragma to pack
>the struct and live with the portability problems or rewrite my code to
>grab the protocol byte by byte.

That's about the size of it.  You take a performance hit either way.  With 
the pragma you get lower performance and larger code when you access the 
structure elements later in the code.  When you use  cracking routines to 
load and unload the structure in place of a memcpy you get the obvious 
time/size hit at the interface.

"You pays your money and you takes your choice."

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: LPC2148 and words on odd addresses.

2006-04-29 by rtstofer

I had the same problem when I ported the FAT code from AVRLib to my
LPC2106 project.  I went with the non-portable approach:

struct bootsector710 {
    unsigned int     bsJump:24;
    unsigned char    bsOEMName[8]; 
    unsigned char    bsBPB[53];
    unsigned char    bsExt[26];
    unsigned char    bsBootCode[418];
    unsigned char    bsBootSectSig2;
    unsigned char    bsBootSectSig3;
    unsigned char    bsBootSectSig0;
    unsigned char    bsBootSectSig1;
#define BOOTSIG0        0x55
#define BOOTSIG1        0xaa
#define BOOTSIG2        0
#define BOOTSIG3        0
} __attribute__ ((packed));  <=== non-portable

I didn't have the ability to change the structure - that's the way the
data is set out on the disk.

These structs are defined and accessed in a single source file.  I can
live with it.

Richard

Re: [lpc2000] Re: LPC2148 and words on odd addresses.

2006-04-29 by Robert Adsett

At 04:40 PM 4/29/06 +0000, rtstofer wrote:
>I had the same problem when I ported the FAT code from AVRLib to my
>LPC2106 project.  I went with the non-portable approach:
>
>struct bootsector710 {
>     unsigned int     bsJump:24;
>     unsigned char    bsOEMName[8];
>     unsigned char    bsBPB[53];
>     unsigned char    bsExt[26];
>     unsigned char    bsBootCode[418];
>     unsigned char    bsBootSectSig2;
>     unsigned char    bsBootSectSig3;
>     unsigned char    bsBootSectSig0;
>     unsigned char    bsBootSectSig1;
>#define BOOTSIG0        0x55
>#define BOOTSIG1        0xaa
>#define BOOTSIG2        0
>#define BOOTSIG3        0
>} __attribute__ ((packed));  <=== non-portable
>
>I didn't have the ability to change the structure - that's the way the
>data is set out on the disk.
>
>These structs are defined and accessed in a single source file.  I can
>live with it.

Which leads to a third semi-portable possibility

struct bootsectorport {
     unsigned int     bsJump:24;
     unsigned char    bsOEMName[8];
     unsigned char    bsBPB[53];
     unsigned char    bsExt[26];
     unsigned char    bsBootCode[418];
     unsigned char    bsBootSectSig2;
     unsigned char    bsBootSectSig3;
     unsigned char    bsBootSectSig0;
     unsigned char    bsBootSectSig1;
};


struct bootsector710 a;
struct bootsectorport b;

And to convert from a to b

b.bsJump = a.bsJump;
memcpy( b.bsOEMName, a.bsOEMName, sizeof(b.bsOEMName));

etc..

A little cleaner looking than massaging byte by byte.  You have to change 
how you define the packed structure when porting but that can be confined 
to a small area.  Not truly portable but it covers a lot of cases.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: [lpc2000] Re: LPC2148 and words on odd addresses.

2006-04-29 by Jan Thogersen

Robert Adsett wrote:
> At 06:18 PM 4/29/06 +0200, Jan Thogersen wrote:
> >It makes a lot of sense what you are saying. What I was trying to do was
> >moving bytes from a SD card into the structure.
> >The structure was made to follow the format of which the bytes was
> >aligned on the SD card. I thought that this was a very beautiful way of
> >doing it. I have seen code grabbing the struct byte by byte. However,
> >when I ran this code on a HCS12 CPU then I could just make a memcpy into
> >the struct and that was it. It was way more code size effective and much
> >nicer to look at.
> >
> >But I get your point about the portability! So there is two ways I can
> >solve this problem... Right? Either give the compiler a pragma to pack
> >the struct and live with the portability problems or rewrite my code to
> >grab the protocol byte by byte.
>
> That's about the size of it.  You take a performance hit either way.  
> With
> the pragma you get lower performance and larger code when you access the
> structure elements later in the code.  When you use  cracking routines to
> load and unload the structure in place of a memcpy you get the obvious
> time/size hit at the interface.
Ok. Tanks everyone!

I went for the quick fix... The pragma packed worked just fine!

Have a nice day.

Best regards
   Jan

Re: LPC2148 and words on odd addresses.

2006-04-29 by brendanmurphy37

--- In lpc2000@yahoogroups.com, Jan Thogersen <jan@...> wrote:
> 
> I went for the quick fix... The pragma packed worked just fine!
> 

Glad to have been of help, and that you have it working. 

It really comes down to the extent, size and structure of the 
software which is the "best" approach (if such a thing ever exists). 
For example, if you have a lot of code that uses the data structure, 
and only one or two places where it has to be copied to an external 
system (flash card, comms link etc.) than it's probably worth going 
through the pain of producing byte stream encoding/decoding 
functions. That way the code will work reasonably efficiently, and 
more importantly will work on any target with any compiler (works 
with any "endian" system, too, which packing can't sort out).

If on the other hand the structure is very localised to a piece of 
code that does the actual copy to/from the external device/system, 
you may as well take the simple approach, using "packed" pragma or 
modifier, testing to make sure all is well on each system. 

Brendan

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.