Hello all,

I have endian problems using the reference operator (&),
the deference  operator (*) or the element deference  operator (->)
together witch data structs which are compiled using pack(1).
The problems appear onlx if these data structs are located within
the litlle endian part of the memory RAM.

These are the failure patterns using the various referencing mechanisms (& or * or ->) for float values:

write1:          testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
                   testLE1->floatvalue = 50.0;

read_1a:       var = testLE1->floatvalue           ok
read_1b:       f = &testLE1->floatvalue;
                   var = *f;                                    failure

write    2:      testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
                   f = &testLE1->floatvalue;
                   *f = 50.0;

read_2a:       var = testLE1->floatvalue           failure
read_2b:       f = &testLE1->floatvalue;
                   var = *f;                                    ok


Used hardware (target):
Taishan board with PowerPC 440gx processor (big endian)

Development environment:
DENX Linux version 2.6.25.4
DENX ELDK version 4.1 build 2007-01-19
gcc release 4.0.0

Due to historical reasons the Linux kernel is configured so that a
small part of the memory can be used as an automated converter between little endian <-> big endian. It is possible to write to a little endian address and read from the big endian address and vice versa.

I tried several possible invocations of the compiler, all show the same result :

gcc -mcpu=440 -mno-strict-align -pedantic -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c gcc -mcpu=405 -mno-strict-align -pedantic -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c gcc -mcpu=405 -mno-strict-align -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c gcc -mcpu=405 -Wall -O0 -o endian_float_pack1a endian_float_pack1a.c


My additional comment for the following code sample :



All accesses within the big endian part work well, regardsless of using pack(1) or pack(4). Writing and reading of data structure elements with pack(4) within the little endian part is also ok -
but my program needs pack(1).


This is my code sample using pack(1) :

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define BIG_ENDIAN_ADDRESS      0xB0000000
#define LITTLE_ENDIAN_ADDRESS   0xB0200000
#define ENDIAN_SIZE             0x100000

//#pragma pack(4)
#pragma pack(1)
typedef struct test1
{
 char  mist;
 int   intvalue;
 float floatvalue;
} testT1;
#pragma pack(0)

int main(int argc, char *argv[])
{
 testT1 *testLE1;
 float  *f, float1, float2;
 char   *ch;

 testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
 testLE1->floatvalue = 50.0;

 ch = (char*)&testLE1->floatvalue;
 f = &testLE1->floatvalue;
printf("(1) %9f %9f [%02x,%02x,%02x,%02x] ", testLE1->floatvalue, *f, ch[0], ch[1], ch[2], ch[3]);
 float1 = testLE1->floatvalue;
 ch = (char*)&float1;
 printf("%9f [%02x,%02x,%02x,%02x] ", float1, ch[0], ch[1], ch[2], ch[3]);
 float2 = *f;
 ch = (char*)&float2;
 printf("%9f [%02x,%02x,%02x,%02x] ", float2, ch[0], ch[1], ch[2], ch[3]);
 printf("%9f\n", *(&testLE1->floatvalue));

 testLE1 = (testT1*)LITTLE_ENDIAN_ADDRESS;
 f = &testLE1->floatvalue;
 *f = 50.0;
 ch = (char*)&testLE1->floatvalue;
 f = &testLE1->floatvalue;
printf("(2) %9f %9f [%02x,%02x,%02x,%02x] ", testLE1->floatvalue, *f, ch[0], ch[1], ch[2], ch[3]);
 float1 = testLE1->floatvalue;
 ch = (char*)&float1;
 printf("%9f [%02x,%02x,%02x,%02x] ", float1, ch[0], ch[1], ch[2], ch[3]);
 float2 = *f;
 ch = (char*)&float2;
 printf("%9f [%02x,%02x,%02x,%02x] ", float2, ch[0], ch[1], ch[2], ch[3]);
 printf("%9f\n", *(&testLE1->floatvalue));

 return 0;
}

If I run the program the console outputs are different :

Output onto the console using pack(4): The values in the brackets [....] show the byte ordering (1) 50.000000 50.000000 [00,00,48,42] 50.000000 [42,48,00,00] 50.000000 [42,48,00,00] 50.000000 (2) 50.000000 50.000000 [00,00,48,42] 50.000000 [42,48,00,00] 50.000000 [42,48,00,00] 50.000000

Output onto the console using pack(1): The values in the brackets [....] show the byte ordering (1) 50.000000 0.000000 [42,48,00,00] 50.000000 [42,48,00,00] 0.000000 [00,00,48,42] 50.000000 (2) 0.000000 50.000000 [00,00,48,42] 0.000000 [00,00,48,42] 50.000000 [42,48,00,00] 0.000000


regards
Thomas

--

Thomas Korn
ifp - Ingenieurbüro für Prozessautomatisierung
Friedrich Werber Str. 44

D-78315 Radolfzell
Tel: (+49) 7732 98 27 89 - 13
Fax: (+49) 7732 98 27 89 - 44

Internet: www.ifp-beisch.com
EMail:    [EMAIL PROTECTED]



Reply via email to