Ohh no, big-endian :-(

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Ohh no, big-endian :-(

5,383 Views
BasePointer
Contributor II
Hi,
 
I'm porting my fully ansi-c compatible Microchip PIC project to HCS08. I need to convert some structs to little endian. I don't like this at all.
 
Can we say 8 bit MCUs such as HCS08s are little-endian or big-endian? They are just 8 bit. How can we talk about endianizm for them?
 
I'm using Hitech PICC18 that is little endian compiler for PIC. But CodeWarrior generates big-endian code for HCS08. Can't CW support little endian code generation for HCS08 family?
 
I have found some conversion functions on the google such as below. I wonder if 32 bit double type conversion is same with long? And I couldn't find anything about array conversion. I need to convert a struct such as
typedef struct
{
 unsigned long  A;
 unsigned int   B;
 unsigned char  C[3];
 double         D[3];
 unsigned char  E;
} TFoo;
 
////////////////////////////////
short convert_short(short in)
{
 short out;
 char *p_in = (char *) ∈
 char *p_out = (char *) &out;
 p_out[0] = p_in[1];
 p_out[1] = p_in[0]; 
 return out;
}

long convert_long(long in)
{
 long out;
 char *p_in = (char *) ∈
 char *p_out = (char *) &out;
 p_out[0] = p_in[3];
 p_out[1] = p_in[2];
 p_out[2] = p_in[1];
 p_out[3] = p_in[0]; 
 return out;
}
////////////////////////////////
 
Regards.
Labels (1)
Tags (1)
0 Kudos
7 Replies

1,001 Views
Lundin
Senior Contributor IV
In ANSI C, float numbers are stored in the same way no matter platform.
0 Kudos

1,001 Views
CompilerGuru
NXP Employee
NXP Employee


Lundin wrote:
In ANSI C, float numbers are stored in the same way no matter platform.




ANSI C 89 does not define how floating point numbers are encoded.
But here we are lucky, apart from the byte ordering, which is different for floats on a HC08 and on x86, they are compatible, both are using IEEE floating-points.
The swapping (same as for longs) still has to be done tough. I don't know about pic, but looks like it uses also the same encoding. Also both x86 and HC08 have 4 and 8 byte floating point types, the right one with the same size has to be choosen.
There is no format like the 80 bits extended precision format on x86, but this is not so common there as well.
0 Kudos

1,001 Views
Lundin
Senior Contributor IV
I see. I was unsure about it before I posted so I actually checked the standard, but C99 rather than 89/91. In C99 it is stated that the floating point format must be according to IEC 60559 which should be the same as IEEE 754.

And while Codewarrior doesn't support C99, but it supports C++ which I believe also requires the above mentioned standard.
0 Kudos

1,001 Views
CompilerGuru
NXP Employee
NXP Employee
Sorry, but the HC08 is big endian.
There are many parts where the architecture does explicitely use big endian byte ordering, for example 16 bit return addresses stored by a jsr or the 16 bit LDHX/STHX/CPHX instructions.
Daniel

BTW: If your application depends on the byte ordering, it is not "fully ansi-c compatible", it depends on some compiler and architecture specifics :smileywink:
0 Kudos

1,001 Views
BasePointer
Contributor II
BTW: If your application depends on the byte ordering, it is not "fully ansi-c compatible", it depends on some compiler and architecture specifics Smiley Wink

Hi,

You may be right Smiley Happy I didn't write my program in the past by thinking that I will be able to port it to a different mcu. My application is communicating with WinXP work at a PC that is also little endian. For example, When I need to send a huge stuct to PC, I use that simple method:

Code:

t_huge_struct val; // contains doubles, ints, chars, bitfields, array..etc, ~2000 byteSendMemoryAsHex(&val, sizeof(t_huge_struct));


And decoding it at PC side is easy due to PC and MCU have same memory map for t_huge_struct variable.

Code:

DecodeHexStrMemory(RecvStr, &val); //sizeof(RecvStr) = 2*sizeof(t_huge_struct)


 
But now, I need to write a interface for whole struct :smileysad:

I wonder if all type casing that is valid in little endian system is also valid in big endian system?

Code:

unsigned int tmp = 125;unsigned char val = (unsigned char)tmp; // val == 125?signed int tmp = -5;signed char val = (signed char)tmp; // val == -5?double tmp = -2134.12;signed int val = (signed int)tmp; // val == -2134?
0 Kudos

1,001 Views
Lundin
Senior Contributor IV
Typecasting integer types as done in your example is endian-independant. Typecasting pointers might cause problems though:

unsigned short x = 0xAABB;
unsigned char y;

y = *((unsigned char*)&x);

It will give you 0xAA on big endian and 0xBB with little endian.
0 Kudos

1,001 Views
bigmac
Specialist III
Hello,
 
I suspect that the problem lies primarily with the communications path between HCS08 and the PC.  Assuming the communications occurs on a byte-by-byte basis, the sequence of the bytes sent does become important - and this is not really to do with ANSI C compliance, but is determined by the details of the communications format chosen. 
 
For this situation, the HCS08 communications would need to match the sequence of bytes that the PC program expects.  So this may only affect the communications functions for the HCS08 - to convert each multiple byte structure element prior to transmission, and following reception of data from the PC.  Few other changes may be necessary.
 
Regards,
Mac
 
0 Kudos