/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Probelm med struktur alignment i Borland C~
Fra : Thomas Lykkeberg


Dato : 19-05-01 07:24

Hej med jer.

Jeg er i gang med at lave en .DLL som skal sende/modtage datapakker
serielt til/fra en embedded ARM7 micro. Koden i ARM7 MCU'en er
kompileret med DWord strucktur alignment, hvilket betyder at uanset
hvor "stort" det første medlem af strukturen er, vil den altid blive
placeret på en modolus 4 adresse. Dette er fordi ARM7 MCU'en er en 32
bit RISC processor.

Jeg har defineret strukturene på alle de datapakker jeg kan
kommunikerer mellem PC'en og ARM7 MCU'en i en header fil. Nogle af
strukturene kunne se ud som følger:

typedef unsigned char Int8;
typedef unsigned short Int16;
typedef unsigned short Int32;

typedef struct DirectivesTag
{
Int8 source;
Int8 dest;
} Directives;

typedef struct RecordTag
{
Int16 length;
Directives directives;
} Record;

Med ARM7 kompileren kan man selv bestemme hvilken struktur alignment
man vil bruge, men det er nu en gang besluttet at det skal være DWord
for at få bedst mulig performance ud af MCU'en, med derpå følgende
memory frås.

ARM7 kompileren gør følgende hvis man erklærer en Record:

adr 0 : LSB length
adr 1 : MSB length
adr 2 : <padding>
adr 3 : <padding>
adr 4 : source
adr 5 : dest

På PC'en genererer Borland kompileren følgende:

adr 0 : LSB length
adr 1 : MSB length
adr 2 : source
adr 3 : length

Det er jo et lille problem, men meget naturligt for en CISC maskine.
Det kaldes også den naturlige alignment, men det jeg vil er at tvinge
Borland kompileren til at aligne strukturen Directives i Record
strukturen på en DWord adresse. Det kan man da også hvis man fusker
lidt og definerer Directives som en union indeholdende en annonym
struktur på følgende måde:

typedef union DirectivesTag
{
Int32 dummy; /* To force 32bit alignment */
struct
{
Int8 source;
Int8 dest;
};
} Directives;

Men det er jo ikke ligefrem det jeg er interesseret i, da jeg jo så
skal rette alle mine strukturer (og der er dælme mange). Jeg har
prøvet "alt" med Borland kompileren. #pragma option -a1/-a2/-a4, men
lige meget hjælper det på struktur alignment, da det kun indvirker på
simple data typer. Øv!

Jeg har prøvet at kompilerer med MSVC++ compileren og den er i stand
til at lave den ønskede alignment, men kan det virkelig passe at jeg
skal skifte kompiler pga. det??? Jeg har snakket med Borland/Inprise,
men de vil have penge for support, og de folk jeg har haft gratis fat
i hos Borland/Inprise ved ikke om det er muligt.

Er der ikke en, eller nogle, som kan give mig et guldkorn til hvilken
option, synlig som usynlig, som løser problemet let og elegant.??

På forhånd mange tak....

/Thomas

 
 
Ivan Johansen (19-05-2001)
Kommentar
Fra : Ivan Johansen


Dato : 19-05-01 10:33

Thomas Lykkeberg wrote:
> Det er jo et lille problem, men meget naturligt for en CISC maskine.
> Det kaldes også den naturlige alignment, men det jeg vil er at tvinge
> Borland kompileren til at aligne strukturen Directives i Record
> strukturen på en DWord adresse. Det kan man da også hvis man fusker
> lidt og definerer Directives som en union indeholdende en annonym
> struktur på følgende måde:

Jeg tror desværre du er nødt til at bruge din fusker-løsning. Efter min
mening bør man dog ikke overføre en hel struct, men istedet overføre et
element af gangen. Du kan eventuelt prøve at stille spørgsmålet på
news://newsgroups.borland.com/borland.public.cppbuilder.language.

Jeg håber du får det til at virke.
Ivan Johansen

Thomas Lykkeberg (19-05-2001)
Kommentar
Fra : Thomas Lykkeberg


Dato : 19-05-01 14:13

On Sat, 19 May 2001 11:32:39 +0200, Ivan Johansen <NG@Padowan.dk>
wrote:
>Jeg tror desværre du er nødt til at bruge din fusker-løsning. Efter min
>mening bør man dog ikke overføre en hel struct, men istedet overføre et
>element af gangen. Du kan eventuelt prøve at stille spørgsmålet på
>news://newsgroups.borland.com/borland.public.cppbuilder.language.

Hej Ivan

Jeg tror ikke jeg er helt med, når du siger "overføre et element ad
gangen". Min kommunikationsprotokol mellem PC'en og ARM7 (Target) er
en simpel pakke protokol, med en header som indeholder længden på
pakken, samt typen af pakken og her er der i virkeligheden tale om et
signal navn til en realtime kernel nede i target. Hver pakke ser kort
ud på følgende måde.

<header>
length (16 bit)
type (16 bit)
<body>
data (array of 8 bit)

Her er data de egentlige data fra det pågældende signal.

Lad mig lige til hvis jeg har misforstået noget.

/Thomas

Ivan Johansen (19-05-2001)
Kommentar
Fra : Ivan Johansen


Dato : 19-05-01 21:13

Thomas Lykkeberg wrote:
> Jeg tror ikke jeg er helt med, når du siger "overføre et element ad
> gangen". Min kommunikationsprotokol mellem PC'en og ARM7 (Target) er
> en simpel pakke protokol, med en header som indeholder længden på
> pakken, samt typen af pakken og her er der i virkeligheden tale om et
> signal navn til en realtime kernel nede i target. Hver pakke ser kort
> ud på følgende måde.
>
> <header>
> length (16 bit)
> type (16 bit)
> <body>
> data (array of 8 bit)

Jeg ville kun sende længde, type og data. Jeg ville ikke sende de bytes,
der ligger i din struct for at få alignment til at passe. Så gør det
ingen forskel, hvordan data opbevares internt på de to systemer, og du
kan bruge en hvilken som helst compiler.

Ivan Johansen

Thomas Lykkeberg (20-05-2001)
Kommentar
Fra : Thomas Lykkeberg


Dato : 20-05-01 10:26

On Sat, 19 May 2001 22:13:28 +0200, Ivan Johansen <NG@Padowan.dk>
wrote:

>Jeg ville kun sende længde, type og data. Jeg ville ikke sende de bytes,
>der ligger i din struct for at få alignment til at passe. Så gør det
>ingen forskel, hvordan data opbevares internt på de to systemer, og du
>kan bruge en hvilken som helst compiler.

Den er jeg med på, men det kræver vel at du runtime kan lave offsetof
og sizeof i target og på PC'en, for at kunne finde ud af hvordan de
enkelte elementer skal pakkes ud?

/Thomas

Ivan Johansen (20-05-2001)
Kommentar
Fra : Ivan Johansen


Dato : 20-05-01 17:14

Thomas Lykkeberg wrote:
> Den er jeg med på, men det kræver vel at du runtime kan lave offsetof
> og sizeof i target og på PC'en, for at kunne finde ud af hvordan de
> enkelte elementer skal pakkes ud?

Jeg ved ikke hvordan din kommunikation foregår, men hvis du har en
funktion SendByte(), der sender en byte, kan du sende en struct således:

void SendByte(unsigned char);
struct
{
Int8 a;
Int16 b;
Int 32 c;
} Test;

SendByte(Test.a);
SendByte(Test.b >> 8);
SendByte(Test.b);
SendByte(Test.c >> 24);
SendByte(Test.c >> 16);
SendByte(Test.c >> 8);
SendByte(Test.c);

Jeg håber du forstod mig.

Ivan Johansen

Søg
Reklame
Statistik
Spørgsmål : 177559
Tips : 31968
Nyheder : 719565
Indlæg : 6408938
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste