ARM Cortex-M Embedded C Fundamentals/Tutorial
-Aviral Mittal (avimit att yhaoo dat cam)
https://www.linkedin.com/in/avimit/
 This tutorial uses Keil uVision 5 IDE available to download for free. Follow this link

SITE HOME

This techerature is about the process starting from writing a simple embedded C-code to its execution.
This techerature attempts to use no jargon, and is targeted for anyone who is interested in knowing how to start writing a embedded C-program or an assembly language program for ARM Cortex-M series processor.
The world is flooded with information, however the information resides in a way that all of the information appears to be junk to a person from some other background. For example if you are from hardware background, the software information appears to be cryptic. For example in software world they use the word 'image' for a binary file that is obtained from a corresponding C program. Seriously if you dont know what an 'image file' is, then somehow jpeg or gifs come into your imagination. I have no idea why its called an 'image'. This techerature is an attempt to keep it very simple without the use of 'what-software-assumes-everyone-knows-by-birth' kind of jargon.

This is all about ARM architecture, so its focused on embedded 'c' aka the c program written for a ARM based Microcontroller.

C-code is human readable, the processor cannot execute it. It must be converted into 0s and 1s, because that is what a processor can execute.
So before the C-code can be executed, this C-Code must be converted into processor instructions in binary format, then this binary format instructions will then be placed into memory, and the processor will then start fetching and executing instructions from this memory (see on use of the software jargon 'image file')
But this sounds very simple. Behind the scenes a lot things happen, a lot of things have to be considered.


The very basic Embedded C program:
This section describes a very simple embedded C-program with some explanation.
Let us Consider a very simple embedded C program to start with:

typedef unsigned long uint32_t;
int main ()
{
    int ii;
    for(ii=0;ii<305419896;ii++) {
    *((uint32_t *)0x40E00018) = 0x87654321;
      asm("NOP");
    }
    while(1){}
}
 

If you have no prior knowledge of embedded C, the above code is already cryptic, but let me explain it line by line:
The first line is a definition of a type of data, the program will use. A new type of data is defined which is called 'uint32_t'. This is defined as a 'long'. 'long' is a predefined data type in C language which represents a binary number that is 32 bit wide.

The second line is the 'main' function call. Essential for every C-program. And this is where the user will write what they want to do.
'int ii' is self explanatory, its declaration of an integer, which will be used in a 'for loop'. In C language, explicit declaration of all the variables is required before you can use them.
The 'for (ii......) is again self explanatory, a for loop is started which will execute 305419896 times.
then you have the line:
*((uint32_t *)0x40E00018) = 0x87654321;
looks like a world-war 2 encrypted code to instruct someone to fire a torpedo!.
Let me explain:

C language uses what are called 'pointers'. Pointer is an address to a memory location. The 'star' or 'asterisk' is used to define/declare a pointer.
'0x' : this means that the value that follows '0x' is in hexadecimal format.

Now the above line of code simply means, that the user wants to send a hex value of 0x8765_4321 to a memory location 0x40E0_0018. Simple.
The '(unit32_t *)' written in braces above means that the user intends to convert the constant value of '0x40E0_0018' to another type of data, i.e. to a pointer, so that it can be used as a address to a memory location. A pointer points to a memory location simple.

See here we have just explained how a constant data (0x40E0_0018) is now converted into another type of data called a pointer data type. The Software guys call it 'type casting'. i.e. cast a type of data into another. Or change one type of data into another. So here it is 'type casting' jargon busted.

Then '*((uint32_t *)0x40E00018) = 0x87654321' collectively means that the user now wants to write a value of 0x8765_4321 to the memory location 0x40E0_0018. The 'star' of a pointer refers to the value at the location pointed to by the pointer. So in the above line the user assigns 0x8765_4321 to 'star' of  '(uint32_t *)0x40E00018'.  Remember, '(uint32_t *)0x40E00018' is a pointer pointing to the memory location 0x4E0_0018.

The asm("NOP") is a 'no-operation' instruction in assembly language, and is used here as I dont know what is the alternative in C-language. To use assembly instructions in C language, 'asm("Assembly_Instruction)' is used.

Now comes the while loop:
while (1) {}.
This code will be there in most of the embedded C programs. In Embedded world the processor will run as long as it has power. Its like a jinnie out of the bottle, it must do something all the times. If the power to the processor is not shut off, or the processor is not put to sleep it will keep on doing 'something'. So the above while (1) do nothing loops does exactly the same.

SITE HOME

                                                                                Next =>



Embedded C programs are written for some target microcontroller. A typical microcontroller has a microprocessor, memory, peripherals and a clock source at the least. The above C-program writes to a memory location This memory location could belong to a 'register' inside a peripheral device.