Q

Emertxe-News & Blog

Home » C programming » Why is C the most preferred language for embedded systems?
Why is C the most preferred language for embedded systems?

Introduction

C is a general-purpose computer programming language which can be used in wide variety of applications. Operating systems, application software for computers ranging from supercomputers to embedded systems are written in C. While C has been a versatile programming language, it has been the most suitable one when it comes to Embedded Systems. In spite of being invented more than 30 years ago, when it comes to Embedded Systems, there is no other programming language which even comes close to C. Let us try to understand the reasons behind why is C the most preferred language for embedded systems, as a part of this blog post.

Embedded Systems

A computer system with a specific function within a larger system (mechanical or electrical system) is an embedded system. It is also possible that the Embedded Systems has real time computing constraints, thereby making them as Real-Time-Systems (RTS). Today Embedded Systems are everywhere starting from wearable devices to high-speed transportation systems.

Practically we can view Embedded Systems as a customized software running on a customized hardware. Since the hardware is very specific, software also needs to be tuned, which puts additional constraint on developer. Along with that, Embedded Systems are typically resource constrained systems, where usage of every other HW resource (ex: memory) must be done efficiently. C language is a killer when it comes to all these aspects!

Before use of C language

At first, micro-controller based systems, programs were developed using assemblers and fused into EEPROMs. There was no mechanism to find what the program was doing. LED, switches etc., were used to check the correct execution of program. As time proceeded, microprocessor specific and assembly-only as programming language got reduced. Embedded systems moved onto C.

Why C

There are specific reasons for why is C the most preferred language for Embedded Systems. Let us look into top-5 of them as follows.

1.Processor independent

C language is not specific to any microprocessor/micro-controller or any system. It can work on various hardware configuration. C doesn’t require same set of hardware to run a program. C language is platform independent whereas the applications written in C are not. Hence the concept “Write once Compile anywhere” came.

Example

We can compile and execute a C program written for one hardware in another hardware with little to no change. If there is a change required, it is only in terms of platform (Operating System) specific functions and system calls. This is said to be machine independent. While writing a program in C, user doesn’t have to know the underlying hardware specific details of the machine, since the compiler takes care of it. When developers compile a C program for a particular hardware, respective assembly code is generated. It is then linked with libraries (static and dynamic) to give an executable file. It should be noted that only C code is machine independent, the executable file generated is Machine as well as Platform (OS) dependent. So, whenever a code written in C must be used in another machine, it should be compiled and executed again.

2.Portability

Portability of a language is mainly important when an application program must be moved to other operating systems. Code developed in C is more portable and user can compile it on other platforms with least modifications. C code is efficient, easy to understand, maintain and debug. A program can be written in one machine and can be run on other machines.

Example

Let us consider simple example of two integer addition!

The size of integer variable depends on the underlying machine architecture. Popularly called as “Word Size” the size can be different. For example, in a 32-bit machine occupies 2 bytes whereas an integer variable in 64-bit machine takes 4-bytes.

The max value stored in a 4 byte (unsigned integer) can vary between 0 to 4,294,967,295 whereas in case of 2 byte the range reduces to 0 to 65535. In case of sum of two numbers (say A and B) exceeding 65535 it will create integer overflow in a 32-bit machine by giving incorrect output. Sample code snippet is given below.

In order to avoid or deduct the issue early, developer can use “typedef” and create a synonym (ex: 32 for int). This will be helpful when program is ported to another machine and the developer can make appropriate changes in the code, thereby making the program portable and avoid error.

#include<stdio.h>
int main()
{
   typedef int u32;                // u32 is a synonym for unsigned integer
   u32 a = 200000, b = 280000, c;  // a, b and c are variables of type int
   c = a + b;
   printf("\nSum is %d",c);
   return 0;
}

Fig 1: Example for Portability using typedef

Output

Why-is-C-the-most-preferred-language-for-embedded-systems-001

Fig 2: Sum of variables a and b displayed

3.Performance

C code gets compiled into raw binary executable which can be directly loaded into memory and executed. C provides optimized machine instructions for the given input, which increases the performance of the embedded system. Most of the high-level languages rely on libraries, hence they require more memory which is a major challenge in embedded systems.

For example, In Java, we need JVM (Java Virtual Machine) in addition to the jar files (Executable) which adds additional overhead in terms of performance and memory consumption. Newer languages provide support for garbage collection, dynamic typing etc., which degrades their performance. Since C does none of that, there is little to no overhead.

4.Bit manipulation

C is more flexible, structured language that provides “low level bit wise data manipulation” using the bit-wise operators. Using bit-wise operators, one could play with available bits, which comes handy when it comes to Embedded Systems (Ex: Handling registers).

Let us understand a basic example.

Example 1 – Setting or clearing a bit

To set a bit in a particular number, developers can use bitwise operators. In the below code,

number to be set and bit-position is provided by the user. By generating appropriate mask required results are generated.

Assuming the same case of registers, developer can set or clear a bit in a similar manner thereby getting the ability to program the hardware. Such facilities having in a high-level language like C gives lot of power to developer.

#include<stdio.h>
int main()
{
   int number, bit_position, newnumber;
   printf("enter the number to be set\n");
   scanf("%d",&number);
   printf("enter the bit to be set\n");
   scanf("%d",&bit_position);
   /* set-bit logic, where(1 << bit_position) is the mask */
   newnumber = (1 << bit_position) | number;       
   printf("Result after seeing the bit is %d\n",newnumber);
   return 0;
}

Fig 3: Bit-manipulation – example to set bit

Output

The third bit (whereas bit position is 2, representing bit b2) in number 11 has to be set high. 15 is the decimal answer after set bit operation is performed on 11.

Why-is-C-the-most-preferred-language-for-embedded-systems-002

Fig 4: Output -set bit

Example 2 – Encoding Algorithms

Encoding can be taken as another example for bit manipulation. If an important text or image has to be sent to others, we can encode the data and send it. Encoding will help in securing the data from hackers, since the original message will not be seen even if it is hacked. At the receiving end, decoding should be done by the receiver to obtain the original data. This is a boon to developers. And this is why C is the most preferred language for embedded systems than other languages.

In the below given encoding example, if the data bit is 1, then bitwise OR is performed with integer 1 and encoding is done. If the data bit is 0, then bit-wise AND is performed with (~1) and encoding is done. Hence original data is changed and encoded. Such encoding algorithm implementation is done with use in C language thanks to bit-wise operators.

//Encode function
Status encode(char data, FILE *source, FILE *destination)
{
   int idx;
   char ch;
   for( idx = 0; idx < 8; idx ++)   // loop to encode all 8 bits of a data byte
   {
      ch = fgetc(source); // gets a byte from source which is to be encoded,in ch 
      if (data & (1 << idx))        // checks for bit value 1 
      { 
         ch = ch | 1;
      }
      else                          // condition for bit 0
      {
         ch = ch &(~1);
      }
      fputc(ch,destination);        // stores encoded bit in destination
   }
   return 0;
}

Fig 5: Encoding function – example code

5.Memory management

It provides direct memory control without sacrificing benefits of high-level languages. We can directly access memory using pointers and perform various operations using them. When memory requirement is not known, we can allocate it dynamically and when memory requirement is known, we can allocate the memory statically. This is one of the main reasons for why is C the most preferred language for embedded systems.

Example 1 – Simple dynamic memory allocation

When amount of memory required is unknown, dynamic memory allocation is used, which also helps in optimized memory usage. In the below code, memory to pointer ptr is dynamically allocated during run time and malloc() returns a void pointer which can be type casted into pointer.

After allocating and performing appropriate operations (ex: addition in this case) the memory is freed up using the free() function.

#include<stdio.h>
#include<stdlib.h>
int main()
{
   int number, idx, *ptr, sum_of_elements = 0;
   printf("Enter number of elements: ");
   scanf("%d",&number);
   ptr = (int*) malloc(number * sizeof(int));
   printf("Enter elements of array: ");
   for(idx = 0; idx < number; ++ idx)
   {
     scanf("%d", ptr + idx);
     sum_of_elements += *(ptr+idx);          // adds array elements
   }
   printf("sum_of_elements = %d", sum_of_elements);
   free(ptr);
   return 0;
}

Fig 6: Array and dynamic memory allocation

Output

Why-is-C-the-most-preferred-language-for-embedded-systems-003

Fig 7: Output for memory management in array

Example 2 – User defined memory management

The pointer facility in C allows user to manage the memory in his own way. For example (in the code given below) we are allocating 100 bytes of memory and storing it into void pointer, as returned by the malloc() function.

Now these 100 bytes can be used the way the developer wants it. For example let us consider a requirement where the user wants to store a length and string contents continuously in memory like (len1,string1) | (len2,string2) | (len3,string3) …. (lenN,stringN) and print them.

Since the malloc() returns a void pointer, the user can do typecasting and assign them to character or integer pointers to access appropriate values. Pointer typecasting combined with pointer arithmetic features of C makes such things possible, which will be very difficult in other programming languages.

In case of Embedded systems, developers constantly need to manage and manipulate memory (ex: A frame of memory returned by the device driver from the hardware) where such powerful aspects of C comes handy for the developer.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LEN 100
int main()
{
   void *ptr;
   char str[MAX_LEN];
   int option, len = 0, idx, string_count = 0, *iptr;
   char *sptr;
   /* allocate 100 Bytes of memory dynamically */
   ptr = malloc(100); 
   /* type cast the target memory as integer pointer*/ 
   iptr = (int*)ptr;
   printf("please enter your strings one by one\n");
   option = 1;
   while (option == 1 )
   {
      printf("Enter your string\n");
      scanf("%s",str);
      /* store the length of the string in the beginning */
      len = strlen(str);
      string_count ++;
      *iptr = len;
      /* Increment integer pointer by 4 Bytes */
      iptr ++;
      /* Type cast the address as character pointer and copy the string */
      sptr = (char *)iptr;
      strcpy(sptr,str);
      /* Increment the string pointer so that next integer can be stored */
      sptr = sptr + strlen(str) + 1;
      /* Typecast it back to integer to store length */
      iptr = (int *)sptr;
      printf("\n Do you have more strings to enter? enter 1 for yes, else 0\n");
      scanf("%d",&option);
   }
   iptr = (int*)ptr;
   /* Print the contents of memory- length and string */
   for(i = 1; i <= string_count; i ++)
   {
      len = *iptr;
      printf("Length of string[%d] is %d\n",i,len);
      iptr++;
      printf("The string is \"%s\"\n",(char*)iptr);
      iptr = (int *)((char *)iptr + len + 1);
   }
   return 0;
}

Fig 8: Memory management (string and integer getting stored in same heap)

Output


Why-is-C-the-most-preferred-language-for-embedded-systems-004

Fig 9: Output- (string and integer)

Conclusion

Embedded Systems development has different set of challenges for developer as it is a resource constraint system. Also programming Embedded Systems involves dealing with actual hardware by controlling them via software.

Even though many languages existed previously and many are still evolving, C has emerged as the number of language when it comes to Embedded Systems programming. This article covered some of the feature of C that helps Embedded Systems developer to program it better. There are still many similar features that needs to be explored, will share them in future blog posts.

Happy learning and happy reading!

YOU MAY ALSO LIKE

Emertxe’s Online Training Programs in Embedded Systems & IoT

Emertxe’s Online Training Programs in Embedded Systems & IoT

The reason why Emertxe is the best choice for career advancement: eLearning and Online training programs are the way forward in the COVID-19 disrupted world. Riding along the digital revolution will ensure engineers are future-ready with skills to not only secure but...

Our Training Programs for Freshers

Our Training Programs for Freshers

Introduction: Emertxe is the leading training institute in Bangalore for Embedded Systems and IoT domains. It is a pioneer in training freshers since 2003 by providing excellent placement opportunities for freshers. Over the years 70000+ students have made their...

Q