Sunday, September 28, 2014

Writing portable Linux driver with respect to processor endianness


In my previous post I discussed about the Endianness concept.

There are many points to take care while writing a portable linux driver.One of the key point I wanted to mention here is the usage of some portable API's which will take care of the automatic endianness conversion for ensuring a portable driver.

Many times during kernel programming we interact with hardware devices for exchanging bytes of data.It can be the case that we receive data from hardware, we pack them and copy to application buffer and vice-versa.

Suppose I consider the case where I read some chunks of data from hardware and I need to copy the data to application buffer.I do not know that if its a little endian or a big endian processor where my driver is running and I only know that my application wants data in big endian format.

So if my driver was running on a little endian processor and I directly copy data to application buffer then it wrong.

So I use a API provided by linux kernel: cpu_to_be32()

Now this API takes as argument a 32-bit data and returns me the big endian format 32-bit data and therefore now I am happy, not to care about the native endianness.

Please have a look at some more API's in the below link and enjoy writing a portable linux driver:

Please have a look for such API's in below link:
http://lxr.free-electrons.com/source/include/linux/byteorder/generic.h

Determining Endianness of Native Processor


We generally encounter a very common term 'Endianness' while working in embedded programming.

Basically endianness is the way a machine architecture stores the data in the memory.We have two types of endianness - Little Endian and Big Endian.

In Little Endian architecture, lower byte data (LSB) is stored in lower address.
In Big Endian architecture, higher byte data (MSB) is stored in lower address.

Though various optimized and non optimized methods are available on internet, I have one more way of determining endianness of native processor.I guess it is one more non optimized method but yeah it is one method.

C code for determining endianness:

//This program determines the Endianness of Native Processor
#include <stdio.h>
void main()
{
int val1 = 256;
char val2 = 0;
val2 = (char*)val1;
if(0 == val2)
    printf("Native processor in Little Endian\n");
else
    printf("Native processor in Big Endian\n");
}

Please ignore warnings during compilation.GNU will give warnings because of non compatible typecasting.