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.