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]