Little Endians Issue...

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

Little Endians Issue...

1,756 Views
PabloA
Contributor II

Hi there, I'm trying to adapt a C code wrote for an ATMEL uC to my MCF51CN128 ColdFire. The code was made to read an SD Card whose data is written like little Indians, in a word field the first byte correspond to the lower byte of this word. For example, if I read from the memory 0xE7, 0x00, 0x00, 0x00 (in this order) it means 0x000000E7 long word. When I read the SD card from SPI interface, I fill a buffer with the same structure.

The code use struct format to identify diferent kind of fields and word on the complete buffer, like this:

 

//Structure to access Master Boot Record for getting info about partioions

struct MBRinfo_Structure{

unsigned char nothing [446];             //ignore, placed here to fill the gap in the structure    

unsigned char partitionData [64];      //partition records (16x4)

unsigned int signature;                   //0xaa55

};

 

In my first try I realized that in the signature struct, defined like above, it don't represented the right data so I change the definition like this,

 

unsigned short int signature;                   //0xaa55


in order to take just 2 bytes to make the int word, but, and naw my problem, when the uC read this data it read like 0x55AA (like is stored) when it have to take 0xAA55.

Why in the ATMEL code the data are correctly interpreted? It don't have any extra code to change the data format.


mbr = (struct MBRinfo_Structure *) buffer;       //if it is not boot sector, it must be MBR

 

if(mbr->signature != 0xaa55) return 1;       //if it is not even MBR then it's not FAT32

 

 

 

How I can solve this problem?


Thanks for your time.


Best regards.


Pablo.


Labels (1)
0 Kudos
1 Reply

760 Views
TomE
Specialist II

The Coldfire is big-endian as you've found out. Your code was written for a little-endian machine.

There is no easy way around this. Code can be written for Big or Little, or with a lot of effort, a lot of GOOD design work up front, very clean division of functions and structures and extensive testing on BOTH architectures it can be made to be able to be compiled for both.

Every structure you define that represents the SD controller, the commands sent to the SD card and the data in the File System on that card (and binary data you may be reading from the files) has to have:

  1. Data that represents a stream or array of bytes left alone,
  2. Data that is represented as 16-bit words byte-swapped,
  3. Data that is represented as 32-bit words four-byte-swapped

Programmers have been dealing with this "for ever" and at least seriously since the early 1980's. That's because all of the Network data representations of Ethernet and TCP/IP are defined in big-endian order. That means that all networking code on all Intel little-endian PCs is full of byte swapping. The convention there is to be very careful about which data is in "Network Order" and which is in "Host Order". For details I suggest you read this Wikipedia article:

http://en.wikipedia.org/wiki/NUXI#History

Please read ALL of the above article. Top to bottom. It is not a simple problem to solve. Everyone thinks it should be simple to fix when they first have this problem. It takes a while to realise how DEEP this problem is.

> How I can solve this problem?


Rewrite all of your code to work on both ends. The usual way in network code is to define the four functions or macros "ntohs(), htons(), ntohl(), htonl()" which are "Network To Host Short" (two byte swap) and "... Long" (four bytes end-around). Both "short" ones are identical, the naming is to help you when reading the code to see which side of the assignment or test is in which order. You define these to perform byte-swaps when compiling for little-endian machines, and to do nothing on big-endian machines, So as a very first step:

if(ntohs(mbr->signature) != 0xaa55) return 1;

You're reading a FAT file system? Every line of code that reads or (shudder!) writes to the directories has to swap the right elements too. I'm looking at the source code for a commercial FAT-system module that runs on Coldfire. There are 255 lines in 11 files with two-byte-swap macros and 54 lines with four-byte-swaps.

If reusing your code is important it might be preferable to change to one of Freescale's ARM-based chips. If you have to use this chip you should find or buy code designed and tested to run on that chip.

Tom