Embedded C
Eng. Mohammed Sokkary Embedded Software engineer
Welcome to the course
Contacts :
Email: eng_mohammed@ymail.com
Connect via LinkedIn
http://eg.linkedin.com/in/engmohammed
Connect via Facebook
Mohammed Ibrahim Sokkaree
Remeber
Life has no limitations except the ones you make
Course Objective
Writing programs and algorithms using C. Programming microcontrollers. Applying the embedded C technique.
Contents
Contents
Introduction Variables and Constants Conditional Statements Operator Loops Arrays, Strings, and Pointers Nonprimitive Data types Function and Macros Selected Topics in embedded C
Introduction
Why C language ?
C is a programming language that allows a software engineer to efficiently communicate with a computer.
Function Oriented Language.
C is a highly flexible and adaptable language, Since its creation in 1970 by Dennis Ritchie.
Standards
K&R ANSI C Brian Kernighan and Dennis Ritchie 1983 the American National Standards Institute began the standardisation process 1989 the International Standards Organisation continued the standardisation process 1990 a standard was finalised
ISO C
Standard C
Embedded C ?
Embedded Systems is not only a SW stack
SW
Devise Driver OS Abstraction Layer
HW
Why embedded C
Its Not a language . Its a technique
Embedded SW engineer
Portability Optimization Quality Readability Complexity HW Compatibility HW knowledge Min. Resources
Compilation process
Editor Compiler Assembler Linker
Editor
Its used to edit the C code
Compiler
It used to convert our C code to the assembly code. Then, the assembler convert it from assembly to machine code.
Linking
The final stage
linking the object code to code libraries This stage produces an executable program, which is named a.out under linux by default.
IDE
Integrated development environment ALL in One solution.
Welcome to C programming
#include
Its handled in the pre-processing operation. Its used to add the contents of the header file to the *.c file. #include <header_file.h>
Search the include path
#include header_file.h
Search the current directory then the include path
main() function
The entry point. The return type is int.
The default return type in C.
int main(void){ .. }
int main(int argc, char ** argv){ .. }
Hello
#include <stdio.h> /* comment */ int main(void) { printf("Hello\n"); printf("Welcome to the Course!\n"); return 0; }
Variables
Variables and Constants
Scope
Life time
Variable
address
Value
Type
Name
variables
Variables are memory storage (placeholder) for values that might change during program life time.
Variables
Must start with a character or an underscore only. From second letter and on, it can be a character, a digit, or an underscore. Shall not take the name of language reserved keywords (if, for, while, etc...) It is case sensitive.
Name
Variables
Life time
Stack heap
Scope
How program stack works
int main(void) { int b,c; func2(b,c); } void Func2(int b2,int c2) { func3(); } void Func3() { int x,y ; } The stack will be empty after finishing the execution
x c2 c
func3 func2 func1
y b2 b
Variables
Life time
Local auto Static Global extern
Scope
: Example 1:
Whats the life time and scope of the variables in example 1 ?
Variables
Data Type
Char Int
1 byte Used to hold a character This data type is used to represent integer values. Int = 1 word processor specific
Data Types
float/double
Fractional numbers double is double
Data Type
How to know the size ?
Sizeof() will help you.
Standard length
Data Type
Data Type
typedef keyword.
typedef unsigned int unit16;
Readability
portability
Variables
Value
Signed Unsigned const
Variables address
Pointers Register
Integers with different bases Example 2
%d Causes an integer to be printed in decimal notation %o Causes an integer to be printed in octal notation. %x Causes an integer to be printed in hexadecimal notation, abcdef are used. %X Causes an integer to be printed in hexadecimal notation, ABCDEF are used.
Remember
Group 1 Qualifier/Modifier extern, typedef, auto, register, static signed, unsigned short, long const volatile Default auto
2 3 4 5
signed Processor specfic Not Not
Example
short unsigned volatile const int a=5;
Any order , Different Groups
Operators
Operators
Arithmetic
+ Addition - Subtraction * Multiplication / Division % Mod (remainder) ++ Increment -- Decrement
X++ ++X Example 3 X++ ++X
Operators
Relational
> Greater than < Less than >= Greater than or equal <= Less than or equal != Not equal == equal
Operators
Logical
&& Logical And || Logical Or ! Logical Not
Bit wise
| bitwise Or & bitwise And ~ bitwise Not ^ bitwise Xor
Example
a = 1 /*0000 0001*/ b = 2 /*0000 0010*/
(a && b) -> will evaluate to TRUE
(a & b) -> will evaluate to 0 which is interpreted as FALSE!!!/*0000 0000*/
Operators
Shift
>> <<
Ex.
int i = 0x00000001; int j = i << 3; /*Now
j = 0x00000008*/
Operators Precedence
Example 4
Check Operators Precedence
HELP ME !!!
i = 10;
(!i == 5) Vs. (i != 5)
Arithmetic operations with assignment!!!
+= -= *= /= %= &= |= ^= <<= >>=
x = x op y
Functions
Functions
Function is a block of reusable code.
type function_name(arg_list);
VoidmyFunc1(int Int myFunc1(int Int*myFunc1(int
x); x); x);
Function Declaration/ Definition
/*Function declaration or prototype*/ int add(int a, int b); /*Function defintion or body*/ int add(int a, int b) { return (a + b); }
Function Call int x = 1, y = 2, z; z = add(x, y);
Note: Function name with no argument is a pointer to the function
Recursive functions
Function Calls itself
int factorial(int n) { int result; /*This is called the termination condition*/ if(l == n) { return (1); } /* recursive call */ result = factorial(n-l) * n; return(result); }
Conditional Statements
If/else
Syntax. Condition. Guidelines.
Note
Any non zero value evaluates as TRUE
Example
If( a >= 100) { /* Do action1*/ { elseif(a >= 50) { /* Do Action2*/ } else { /*the default action */ }
Usage of if-else
Conditional Non overlapping conditions Control the Program Flow
Switch
-How to make it ? -Whats the condition ? -Whats break ? -Whats default ?
example
switch(litre_count) { case 0: printf(empty\n"); break; case 1: printf(1 litre only \n"); break; case 2: printf(Stop filling the container\n"); break; default: printf(system down!\n"); break; }
Switch Vs. If/else
Which is better ? Can I use string in Switch ? Switch cases ordering ? If/else condition ordering?
?
The ternary operator
Var = (condition) ? Value_if_true : value_if_false;
Example:
Result = (x > 0) ? 5 : -4 ;
Loops
for loop
Used to repeat a certain task n numbers of times
For loop
How does it work? Whats optional ?
For(int i = 0;i < 10;i++) { printf(HELLO\n); }
example
X 2 3
Y 1 1 1 1
int main(void) { int x=1,y=1; for(;y;printf("%d %d\n",x,y)) y=x++<=5; return 0; }
4 5
6
7
1
0
Think about it .. !!!
What does this mean ?
for(j = 5; j == 0; j--) { /*CODE*/ }
For loop
If(you know the number of iterations) { decision = use for loop; } else { decision = use while; }
while
Do.. while
Compare
For / while / Dowhile
Break Vs. Continue
Break
break statement is used to trigger early exit of loops
continue statement forces the loop body to skip executing the rest of the current iteration and start from the beginning of the next iteration. ends the execution of the current function and returns control to the caller. The value of the expression in the return statement is returned to the caller as the return value of the function.
Continue
Return
Arrays
Arrays
I Dont KNOW ARRAYS
What DO you Know ?
Arrays
An array is a collection of data items (called elements) all of the same type C always allocates the array in a single block of memory The size of the array, once declared, is fixed
Arrays
int a[5] = { 10, 20, 30, 40, 50 }; double d[100] = { 1.5, 2.7 }; long n[50] = { 0 }; ===================================== Whats wrong with this code ->
int i = 7; const int c = 5; int a[i]; double d[c];
Arrays
const int SIZE = 10; int i; int group1[SIZE]; /*first group of numbers*/ int group2[SIZE]; /*second group of numbers*/ int group3[SIZE]; /*result of summation*/ /*Code that fills group1 and group2 with values*/ for(i = 0; i < SIZE; i++) { group3[i] = group1[i] + group2[i]; }
Strings
WE DONT HAVE STRINGS
Strings
char courseName1[100] = "ANSI C"; char courseName2[100] = {'A', 'N', 'S', 'I', ' ', 'C', '\0'}; printf(courseName1); printf(courseName2);
Array of char Terminated with \0
Nonprimitive Data types
Structure
Setup your template Create your instance Access the instance members
Structures
allows the user to define his/her own data types
struct tire { int int char* };
m_pressure; m_diameter; m_brand;
Struct Car { struct tire m_frontTire; struct engine m_Engine; int colour; };
Structure Initialization
struct Tire testTire = {10, 100, "Zooba"};
struct Tire testTire; testTire.m_pressure = 10; testTire.m_diameter = 100; testTire.m_brand = "Zooba"; (testTire.m_pressure)++; printf("The tire pressure = %d\n", testTire.m_pressure);
Quizzzzzzzz
Can we make Array of Structures
Unions
union of one or more variable of one or more data types that shares the same space.
union testUnion { int a; /*occupy 4 bytes*/ char b; /*occupy 1 byte (shares the first byte of the variable a)*/ };
Instead of using 5 bytes, we only use 4 bytes
Enumeration
data type is designed for variables that contain only a limited set of values.
Ex.
days of a week
Dont forget typedef enum week_day today = MONDAY; week_day today = SUNDAY;
Pointers
Pointers
normal variables hold values, pointer variables hold memory addresses int * x ; /* Pointer to integer*/
- size of the pointer = size of integer - x value is the integer address - Ex.
char c = 'Z'; char* p = &c; *p = 'A';
Whats the contents of c ?
Pointers
int *sokkaree; long int *p; int* pf; char c, d, *pc int* pd, e, f; char* start;
Pointers
we use an '*' right after the type to declare a pointer variable '&' is called the address-of operator, and it is used to get the address of its operand. Note:
Array name with no index is a pointer to the 1st element in the array Pointers cant be used with register variable
Pointers Example
Lets Have FUN
*p++
*p Find value p++ increment pointer
(*p)++
*p Find value ()++ increment value
Discussion
Zero, NULL, NULL terminator
Pointers Pointers & Pointers
Using the variable a, give definitions for the following:
a) An integer b) A pointer to an integer c) A pointer to a pointer to an integer d) An array of 10 integers e) An array of 10 pointers to integers f) A pointer to an array of 10 integers g) A pointer to a function that takes an integer as an argument and returns an integer h) An array of ten pointers to functions that take an integer argument and return an integer
Answer
a) int a; // An integer b) int *a; // A pointer to an integer c) int **a; // A pointer to a pointer to an integer d) int a[10]; // An array of 10 integers e) int *a[10]; // An array of 10 pointers to integers f) int (*a)[10]; // A pointer to an array of 10 integers g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
MACROS
Macros
All preprocessors has to be preceded by a '#' character
#include #define #if , #else , #elif , #ifdef #undef
#endif
Examples
Conditional compilation This is very useful if you're writing programs that run on different platforms, for example Linux and Windows
#define TEST 1 int main() { #if TEST printf("Test is set\n"); /*Will only be compiled in if TEST is nonzero*/ #else printf("Test is reset\n"); /*Will only be compiled in if TEST is zero*/ #endif return 0; }
Examples
#define MAX_LENGTH 5 Difference between #if , #ifdef , #ifndef
Function like Macros
Macros can be written to perform functions.
#define ABS(val) ((val)>=0) ? (val) : -(val)
This is a macro definition that takes one argument and returns the absolute value of it.
Example
Check the difference between the different preprocessing operations.
Dynamic memory allocation
Dynamic Memory Allocation
malloc(the size of memory to allocate in bytes);
Return NULL if it cannot allocate Void pointer is the default return type.
We must FREE the memory, why?
Ex.
int* pIntArr = (int*) malloc (10 * sizeof(int));
General Discussion
Call By Value / Call by Reference
By Value
void swap(int i, int p) { int w = i; printf("inside swap before: i = %d, p = %d\n", i, p); i = p; p= w; printf("inside swap after: i = %d, j = %d\n", i, p); }
Changes inside will never affect outside
Call By Value / Call by Reference
by Reference
void swap(int* i, int* p) { int w = *i; printf("inside swap before: i = %d, p = %d\n", *i, *p); *i = *p; *p = w;
printf("inside swap after: i = %d, p = %d\n", *i, *p); }
Passing pointer, So it will affect outside
Compare
Structures Vs. Arrays. Function like macro Vs. Inline function.
Thank you