watchloop
watchloop

Reputation: 21

Little and Big Endian access on boards with multiple devices - Embedded software architecture

We have several boards, think of them as motherboards. These motherboard contains different devices from microprocessors,ASICs and FPGAs... So far all the devices are 16 bit Big endian based. The problem at the moment is that we're using a new ASIC that is 32 little endian based while all other devices on the mobo are big endian. We have created specific apis to read/write 32 bit little endian. In the future we might have mobo's that can have a mixture of devices using 16/32 Big/little endian. These same devices could be used on different new or old mobos.

We use Embedded C (in Vxworks)as the language and our software is modularized to use common code and mobo specific code. Solutions of using #defines and checking #ifdef have arrised but I'm not entirely sure how to go with them. We can't really use #ifdef on the processor type because that same processor could be used on a different mobo with different access requirements.

I would greatly appreciate some help architecturally and right down technically in terms of a sample C code example if possible.

Upvotes: 1

Views: 321

Answers (1)

indiv
indiv

Reputation: 17866

Write an API for your device.

The API will provide a guarantee that it will accept data from the microprocessor in the microprocessor's byte order, and return data to the microprocessor in the microprocessor's byte order. Then the API does the LE->BE or whatever conversion.

At the least, you'd have asic_read32 or fpga_read16, for instance. Your asic_read32() function would be like this:

/* asic is little endian */
asic_read32(...)
    if microprocessor is big endian  /* do this at compile time with #if */
        le_data = read32_le(...)
        return to_big_endian(le_data)
    else
        return read32_le(...)

And your microprocessor app happily ignores that any of this is going on:

uin32_t num_bytes_frobbed = asic_read32(BYTES_FROBBED_REG);
printf("Frobbed %u bytes so far.\n", num_bytes_frobbed);

As a bonus, all access to your device will go through a single API, so you can put in locks if necessary to make device access multithread safe.

If you feel comfortable with it and it's appropriate, you might be able to abstract out the device itself and implement a higher-level functions like get_frobbing_statistics(struct frobbing_stats *stats).

Upvotes: 1

Related Questions