Embedded C
Embedded C
com
License
This power point presentation by BHARATI
SOFTWARE is licensed under CC BY-SA 4.0
To view a copy of this license, visit
https://creativecommons.org/licenses/by-sa/4.0
Important Links
• For the full video course please visit
– https://www.udemy.com/course/microcontroller-embedded-c-programming/
• Course repository
– https://github.com/niekiran/Embedded-C/
• Explore all FastBit EBA courses
– http://fastbitlab.com/course1/
• For suggestions and feedback
– [email protected]
Social media
• Join our Facebook private group for technical discussion
• https://www.facebook.com/groups/fastbiteba/
• Linkedin
• https://www.linkedin.com/company/fastbiteba/
• Facebook
• https://www.facebook.com/fastbiteba/
• YouTube
• https://www.youtube.com/channel/UCa1REBV9hyrzGp2mjJCagBg
• Twitter
• https://twitter.com/fastbiteba
What is a program ?
• A program is a series of instructions that cause a
computer or a microcontroller to perform a
particular task.
• A computer program includes more than just
instructions. It also contains data and various
memory addresses on which the instructions
work to perform a specific task.
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Survey by Embedded.com
C programming standardization
• The C programming language was initially developed in AT&T
labs by Professor Brian W. Kernighan and Dennis Ritchie,
known as K&R C.
• During the year 1970, ‘C’ programming became very popular
but without any serious standardization to the language.
• The non-official standard was called K&R C, which led to many
ambiguities among different compiler programmers, and that
led to non-portable codes.
• K&R C was the first non-official ‘C’ standard
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
C programming standardization
• In 1989 American National Standard Institute designed and approved first
official C standard called X3.159-1989, and in 1990 it was approved by ISO as
an international standard for C programming language: ISO/IEC 9899:1990
(This is also called ANSI C or C89 or C90 standard in short )
C programming standardization
• C11 is an informal name for ISO/IEC 9899:2011, which is a new
standard approved in December 2011. C11 supersedes the C99
standard.
• In this course, we will be using the ‘C11’ standard with some
compiler (GCC) extensions (gnu11). More on this, we will see later.
Compatibility
• Note that if you have written a code using C90 standard, then it
will compile without any issues in –std=C99
compilation(backward compatibility )
• If you have written a code using C99 standard specific features,
then It may not compile successfully in C90 compilation
cursor
H e l l o W o r l d ! Line 1
H e l l o W o r l d ! Line 1
cursor
b y e ! W o r l d ! Line 1
Comments
✓Generally Comments are used to provide the description or documentation
about the code you have written.
Comments
✓You can mention the comments anywhere you want in the program and your
comments will be ignored by the compiler .
✓Comments do not affect program or they do not consume any program memory
space . They are not part of the final executable generated . It is there just for the
documentation purpose .
Comments
In C there are two types of comments :
Single line comment
Multi-line comment
Data types :
✓Data type is used for declaring the type of a
variable
✓In C programming, data types determine the
type and size of data associated with variables
✓Before storing any value in a variable, first
programmer should decide its type
Examples
• Roy’s age is 44 years, 6 months and 200 days
• The temperature of the city X is +27.2 degrees
Celsius.
• Today date is 21st June
• I got an ‘A’ grade in school assignment
Data types :
Based on the real-world data we have
two significant data types in C
✓The C standard does not fix the storage sizes of different data types. It only talks
about the minimum and maximum values .
✓For example C standard says, the minimum storage size of a long type variable is
32 bits, and the max is 64 bits. So, exact size of the long type variable depends on
the compiler design.
✓Some compilers fix 32 bits storage size for long type variables and some
compilers fix 64 bits. Same is true for int data type, Some compilers fix 16bits
storage size for int type variables and some compilers fix 32 bits.
✓There is no other special meaning for the char data type, and it is
just another integer data type.
I am sure that X's temperature never goes below 0 degrees and never goes above
40 degrees Celsius.
That means City X's temperature will always be a positive value, and the max
value is less than 255.
So, here we can use unsigned char data type to represent temperature value.
Example-1
Variable definition
Data type Variable name
A B C
160 Km 40 Km
160 Km 40 Km
A B C
160 Km 40 Km
Format specifier
Range Calculation
Let us calculate the range of char data type.
Example
Represent the data -25 in 1 byte signed data representation
data
sign - 25 Magnitude
Magnitude will be stored in 2’s
complement form if data is negative
1 bit for sign 7 bits for magnitude
7 6 5 4 3 2 1 0
1 1 1 0 0 1 1 1 = 0XE7
hex value of decimal -25
So, in signed data context 0xE7 is -25
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Example
Represent the data 25 in 1 byte signed data representation
data
sign 25 Magnitude
+ve
7 6 5 4 3 2 1 0
0 0 0 1 1 0 0 1 = 0x19
(hex value of decimal 25)
Magnitude : 127
7 6 5 4 3 2 1 0
Highest value
0 1 1 1 1 1 1 1
Magnitude : -1
7 6 5 4 3 2 1 0
Highest value
1 1 1 1 1 1 1 1
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
✓You can just mention short (for signed ) or unsigned short . “int” will
be assumed.
sign - 25 Magnitude
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1
Binary representation of 25 using 2 bytes
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0
1s complement format of 25
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0
1’s complement format of 25
+ 1
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
Sign bit 2’s complement format representation of -25 using 2 bytes
sign - 25
1 bit for sign 15 bits for magnitude
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
0xFFE7
sign 25
1 bit for sign 15 bit for magnitude
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1
0x0019
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
sizeof operator
• sizeof operator of C programming language is
used to find out the size of a variable.
• The output of the sizeof operator may be
different on different machines because it is
compiler dependent.
Variables
0 1 1 0 0 1 1 1
1 1 0 0 0 1 0 0
0 1 1 0 0 1 1 1
Different
1 1 1 1 0 1 1 1 memory
1 1 1 0 0 1 1 0 locations
of the
0 1 1 0 0 1 1 0 computer
0 1 1 1 0 1 1 1 memory
0 1 1 1 0 1 1 1
0x0800 0 0 0 1 0 1 0 0
valueA
Data stored in the memory
location
Defining Variables
✓Before you use a variable, you have to define it.
Defining Variables
✓To define a variable, you only need to state its type,
followed by a variable name.
✓e.g., If the data type of the variable is char, then
compiler reserves 1 byte. If the data type is int then
compiler reserves 4 bytes .
Example :
char myExamScore; //This is called variable definition
Variable initialization
char myExamScore ; //Variable definition
myExamScore = 25; //This is called variable initialization
Observe that variable initialization is followed by
first defining the variable .
This is illegal
myExamScore = 25; //variable initialization
char myExamScore ; //Variable definition
This is legal
Variable scopes
• Variables have scopes
• A Variable scope refers to the accessibility of a
variable in a given program or function
• For example, a variable may only be available
within a specific function, or it may be
available to the entire C program
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Variable scopes
• Local scope variables (local variables )
• Global scope variables ( global variables )
A ‘C’ project
Extern
'extern' storage class specifier is used to access the
global variable , which is defined outside the scope of a
file.
Extern
The keyword ‘extern’ is relevant only when your
project consists of multiple files, and you need to
access a variable defined in one file from another file.
Address of a variable
ASCII codes
• The American National Standards Institute
(ANSI), which developed ANSI C, also
developed the ASCII codes.
• ASCII stands for “American Standard Code for
Information Interchange’
ASCII codes
• By using ASCII standard, you can encode 128
different characters.
• That's why to encode any ASCII character you
just need 7 bits. (you can use char data type )
A A p p p p l l e e : )
For the machine everything is number.
A p p l e : )
For the machine everything is number.
Address of a variable
0x00007FFF8E3C3821 0 1 0 0 0 0 0 1
(a pointer)
Variable name
Type casting
scanf
scanf
• scanf is a standard library function that allows
you to read input from standard in.
• Standard in for us is generally the keyboard
• By using scanf library function you can read
both characters and numbers from the
keyboard.
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
int age ;
printf(“Enter your age : “);
scanf(“%d”, &age);
int c;
printf(“Enter a character: “);
scanf(“%c”, &c);
getchar()
• If you just want to read a single character from
the keyboard in ASCII format then just use
getchar().
• getchar() function takes no argument and just
returns an int value which happens to be the
ASCII value of the key pressed
• int a = getchar(); // Here the program hangs until you press a key
followed by pressing the enter key.
printf
output buffer
Abcd\r\nmn\r
Keyboard
Input buffer
Program
scanf
getchar()
Input buffer
Program
scanf(“%f”,&n1);
Keyboard
Input buffer
10\n
Program
read by the scanf
scanf(“%f”,&n1);
Keyboard
Input buffer
\n
Unread data
Program
Keyboard
Input buffer
\n
Program
scanf(“%f”,&n2);
Read and discarded by the scanf
because its not a valid number
but a special character . Scanf waits
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Keyboard
Input buffer
45\n
Program
Read by scanf scanf(“%f”,&n2);
Keyboard
Input buffer
65\n
Program
Read by scanf scanf(“%f”,&n3);
Keyboard
Input buffer
\n
Unread data
Program
Keyboard
Input buffer
\n
Program
getchar() fetches \r
and returns.
Exercise
Exercise
Project
Type casting
Typecasting is a way of converting a variable or data
from one data type to another data type.
Pointers
0x00007FFF8E3C3828 0 1 1 0 0 1 1 1
0x00007FFF8E3C3827 1 1 0 0 0 1 0 0
0x00007FFF8E3C3826 0 1 1 0 0 1 1 1 Different
memory
0x00007FFF8E3C3825 1 1 1 1 0 1 1 1 locations of
0x00007FFF8E3C3824 1 1 1 0 0 1 1 0 the computer
0x00007FFF8E3C3823 0 1 1 0 0 1 1 0 memory
0x00007FFF8E3C3822 0 1 1 1 0 1 1 1
0x00007FFF8E3C3821 0 1 1 1 0 1 1 1
7 6 5 4 3 2 1 0
0x00007FFF8E3C3824 0 1 0 0 0 0 0 1
0x00007FFF8E3C3824
0x1F007FFF8E3C4821
address1
The pointer data type decides the behavior of the operations carried
out on the pointer variable.
Operations : read, write, increment, decrement
The pointer data type decides the behavior of the operations carried
out on the pointer variable.
Operations : read, write, increment, decrement
0x00007FFF8E3C3824
0x1F007FFF8E3C4821
address1
0x00007FFF8E3C3824 Before
0x1F007FFF8E3C4821
address1 0x85
An initialized pointer variable 0x00007FFF8E3C3824
A memory location address and value
*address1 = 0x89;
0x00007FFF8E3C3824 After
0x1F007FFF8E3C4821
address1 0x89
An initialized pointer variable 0x00007FFF8E3C3824
A memory location address and value
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Exercise
1) Create a char type variable and initialize it to value 100
2) Print the address of the above variable.
3) Create a pointer variable and store the address of the above
variable
4) Perform read operation on the pointer variable to fetch 1
byte of data from the pointer
5) Print the data obtained from the read operation on the
pointer.
6) Perform write operation on the pointer to store the value 65
7) Print the value of the variable defined in step 1
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
100 1
000000000061FE46 (Address of variable “data” )
data
value = *pAddress;
Dereferencing the address 000000000061FE46 to read the value stored
3
100 will be stored in the variable “value”
*pAddress = 65;
Dereferencing the address 000000000061FE46 to write the value 65
4
65 will be stored in the memory location addressed by 000000000061FE46
65
000000000061FE46 (Address of variable “data” )
data
0xFF 0X0000000000403017
0xFE 0X0000000000403016
0xAB 0X0000000000403015
0xCD 0X0000000000403014
0x11 0X0000000000403013
0x11 0X0000000000403012
0x23 0X0000000000403011
0x 45 0X0000000000403010 pAddress
(&g_data)
g_data
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
char *pAddress; pAddress = pAddress +1;
0xFF 0X0000000000403017
0xFE 0X0000000000403016
0xAB 0X0000000000403015
0xCD 0X0000000000403014
0x11 0X0000000000403013
0x11 0X0000000000403012
g_data
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
char *pAddress; pAddress = pAddress +5;
0xFF 0X0000000000403017
0xFE 0X0000000000403016
0x11 0X0000000000403013
0x11 0X0000000000403012
0x23 0X0000000000403011
0x 45 0X0000000000403010
g_data
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
int *pAddress;
0xFF 0X0000000000403017
0xFE 0X0000000000403016
0xAB 0X0000000000403015
0xCD 0X0000000000403014
0x11 0X0000000000403013
0x11 0X0000000000403012
0x23 0X0000000000403011
0x 45 0X0000000000403010 pAddress
g_data
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Int *pAddress; pAddress = pAddress +1;
0xFF 0X0000000000403017
0xFE 0X0000000000403016
0xAB 0X0000000000403015
0x11 0X0000000000403013
0x11 0X0000000000403012
0x23 0X0000000000403011
0x 45 0X0000000000403010
g_data
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Int *pAddress;
pAddress+2 pAddress+3 pAddress+4 pAddress+5 pAddress+6
pAddress
4 Bytes offset
8 Bytes offset
Importance of <stdint.h>
Each architecture(x86, 8051, PIC, ARM,etc.) has a natural, most-efficient
size, and the designers, specifically compiler implementers use the
natural native data size for speed and code size efficiency.
Portability Issues in C
✓In ‘C’ programming language the most commonly used data types “int” and
“long” cause portability issues.
✓The reason is that the storage size for ‘int’, ‘long’ type variable is not defined
within the C standard ( C90 or C99).
✓The compiler vendors have the choice to define the storage size for the
variable depending solely on hardware capabilities of the target platform, with
respect to the minimum widths defined by the standard.
stdint.h
✓The standard library header file stdint.h defines fixed-
width integers using alias data types for the standard data
types available in ‘C’
stdint.h
aliased data
types
uint32_t count=0;
count++;
Here, doesn’t matter under which
If( count > 65,536)
compiler this code compiles, the
{ compiler will always reserve 32bits for
//Do this task the variable by using suitable
standard data type.
}
Operators in ‘C’
An operator is a symbol
that tells the compiler to
perform a certain
mathematical or logical
manipulation on the
operands
Arithmetic(Mathematical) operators
+ addition
- subtraction
* multiplication
/ division
% modulus
Modulus produces the remainder from division.
For example:
14 % 4 evaluates to 2.
14 divided by 4 yields a remainder of 2.
uint32_t value ;
value = 20 or value = 14 ?
value = 2 + 3 * 4;
Operator Precedence
Operator precedence rules determine which
mathematical operation takes place first, i.e. takes
precedence over others. Parentheses, ( ), may be used
to force an expression to a higher precedence
Image source
https://en.cppreference.com
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Examples
* : higher precedence
+ : lower precedence
2 + 3 * 4
1
2 + 12
2
14
1 (2 + 3) * 4
5 * 4
2
20
4 * 5/2 * 5
2 or 50 ??
20 / 2 * 5
Associativity is used to
2 evaluate the expression
when there are two or more
operators of the same
10 * 5 precedence is present in an
expression.
3
50
Image courtesy
https://en.cppreference.com
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
12 + 3 - 4 / 2 < 3 + 1
12 + 3 - 4 / 2 < 3 + 1
12 + 3 - 2 < 3 + 1
15 - 2 < 3 + 1
13 < 3 + 1
13 < 4
0
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
+ addition
- subtraction
* multiplication
/ division
% modulus
x++ x--
Unary increment operator Unary decrement operator
Note : when the operand is pointer variable the behavior will be different and
we will discuss later
y=6 , x = 6 m=5, x = 6
A = -10, B=20;
C = 1 //true
Truth table
Image courtesy
https://en.cppreference.com
logical OR Operator : ||
✓ The logical-OR operator performs an inclusive-OR
operation on its operands.
✓ The result is 0 if both operands have 0 values.
✓ If either operand has a nonzero value, the result is 1.
✓ If the first operand of a logical-OR operation has a
nonzero value, the second operand is not evaluated.
Result : x = 0;
Operator Type
Unary
C=1; A
&
00101000
b Bitwise
operation
B b00011110
C= b00001000
C = A || B; C = A | B;
C=1;
A
|
00101000
b Bitwise
operation
B b00011110
C= b00111110
C = ! A; C = ~A;
C=0;
Bitwise
00101000
A b operation
C= ~A b11010111
C= -41
C = A ^ B;
A 00101000
b Bitwise
^ operation
B b00011110
C= b00110110
C=54
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Exercise
• Write a program which takes 2 integers from
the user , computes bitwise &,|,^ and ~ and
prints the result.
46 (0x2E) 47 (0x2F)
lsb lsb
b00101110 b00101111
Number is EVEN
Number is ODD
Test the least significant bit of the number using bitwise operation
If the lsb is zero, then number is EVEN
If the lsb is one, then number is ODD
b00000001
[mask] Mask_value (1)
Bit Masking is a technique in programming used to test or modify the states of the bits of a given data.
Modify : if the state of the bit is zero, make it one or if the state of the bit is 1 then make it 0
Test : check whether the required bit position of a data is 0 or 1
Mask value
If ( number & 1)
{
print(number odd)
}else
{
print(Number even)
}
b00010000
b10111110
[output] [output]
‘&’ is used to ‘TEST’ not to ‘SET’ ‘|’ is used to ‘SET’ not to ‘TEST’
7 6 5 4 3 2 1 0
[data]
b10111110
&
[Mask] b10001111
[output] b10001110
Only this portion is cleared out
‘&’ is used to ‘TEST and CLEAR’ not to ‘SET’
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
[data]
b10111110 [data] 10111110
b
& &
[Mask] b10001111 [Mask] ~(01110000)
b
Exercise
• Write a program to turn on the LED of your
target board
• For this exercise we need the knowledge of
– Pointers
– Bitwise operations
– Hardware connections
Hardware connections
• Lets understand how external hardware (LED)
is connected to MCU
– Refer schematic of the board you are using
In STM32Fx based
PORT-A PORT-E
MCUs , each port has
16 pins where you can
connect external
peripherals .
(LED, Display , button,
PORT-B PORTD Bluetooth transceiver ,
external memory (e.g.
EEPROM), Joy stick ,
keypad ,etc )
PORT-C
GPIO Port D
Peripheral’s
pins
GPIO D
peripheral
MICROCONTROLLER
GPIO D
peripheral
And its registers
MICROCONTROLLER
ARM
Data Code
Cortex M4
memory memory
CPU
32 bit address channel
32 bit data channel
System bus(AHB)
3
4
12
15
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
So, that means 4G(4,29,49,67,296 )different addresses can be put on address bus
PC
0x4000_0000
0x4000_0000 Address Bus
16 bits
Here Processor wants to talk to a peripheral register which is mapped at the address
0x4000_0000.
Processor either wants to read from the register or write in to the register.
The registers used to control and configure the Ethernet MAC peripheral and
registers used to read data from and write data into Ethernet MAC peripheral are
mapped in the address range of 0x4002_8000 to 0x40002_93FF.
*if you are using different MCU , then please refer to your device reference manual to obtain
the correct address range
MICROCONTROLLER
GPIOD
peripheral
And its registers
0x4002_0C02
32 bit register
0x4002_0C01
0x4002_0C06
32 bit register
0x4002_0C05
32 bits width
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
MICROCONTROLLER
ARM S-Bus
Cortex M4
CPU
memory
GPIOD
AHB Bus
GPIOC
Data exchange between
GPIOB peripheral and memory
happens over the bus
GPIOA
ARM S-Bus
Cortex M4
CPU
GPIOD
AHB1 Bus
GPIOC
Peripheral and memory
GPIOB
exchange data over this
GPIOA
Unary
char a = 111
char b = a >> 4
b=?
a 0 1 1 0 1 1 1 1
0
a 0 1 1 0 1 1 1 1 111 (0x6F)
0
a >> 1 0 0 1 1 0 1 1 1
0
a >> 2 0 0 0 1 1 0 1 1
0
a >> 3 0 0 0 0 1 1 0 1
a >> 4 0 0 0 0 0 1 1 0 6 (0X06)
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
0 0 0 0
a 0 1 1 0 1 1 1 1
a >> 4 0 0 0 0 0 1 1 0
0 0 0
a 0 1 1 0 1 1 1 1
A >> 3 0 0 0 0 1 1 0 1
Unary
a 0 1 1 0 1 1 1 1 0 111 (0x6F)
a << 1 1 1 0 1 1 1 1 0 0
a << 2 1 0 1 1 1 1 0 0 0
0 1 1 1 1 0 0 0 0
a << 3
Applicability
• Bitwise shift operators are very much helpful in
bit masking of data along with other bitwise
operators
• Predominantly used while setting or clearing of
bits
• Lets consider this problem statement :Set 4th bit
of the given data
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com 7 6 5 4 3 2 1 0
[Data] 0 0 0 0 1 0 0 0
Set 4th bit of the given data
[mask] 0 0 0 1 0 0 0 0
Data = 0x08
[output] 0 0 0 1 1 0 0 0
Data = Data | 0x10
= 0x18
[Data] 0 0 0 1 1 0 0 0
Clear 4th bit of the given data
[mask] 1 1 1 0 1 1 1 1
Data = 0x18
[output] 0 0 0 0 1 0 0 0
Data = Data & 0xEF
= 0x10
Bit extraction
• Lets consider this problem statement
1)Shift the identified portion to right hand side until it touches the least
significant bit ( 0th bit)
2)Mask the value to extract only 6 bits [5:0] and then save it in to
another variable
1 2 3 4 5 6 7 8 9
>> 9
1) Shift the identified portion to right hand side until it touches the least
significant bit ( 0th bit)
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
[Data] 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 After shifting
2) Mask the new value to extract only first 6 bits[5:0] and then save it in to another
variable
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
[Data] 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 After shifting
&
[mask] 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 [0x003F]
NO
1. if Statement
2. if-else Statement
3. if-else-if ladder
4. Conditional Operators
5. Switch/case Statement
1. if Statement
2. if-else Statement
3. if-else-if ladder
4. Conditional Operators
5. Switch/case Statement
Syntax : if statement
Single statement execution Multiple statement execution
if(expression) if(expression) {
statement; statement_1;
statement_2;
statement_3;
If the expression evaluation is true statement_4;
(nonzero), then only statement(s) statement_n;
will be executed }
if(expression)
Beginner's mistake :
Observe that no ; here
Equivalent to
The relational operators (==, >, <, >=, <=, !=) and the logical operators (&&, ||, !)
are frequently used as the basis of conditions in if and if/else conditional
statements to direct program flow.
Exercise
• Write a program that takes the user’s age and
decides whether a user can cast a vote or not.
• The minimum age for casting a vote is 18
years
• Print appropriate messages
1. if Statement
2. if-else Statement
3. if-else-if ladder
4. Conditional Operators
5. Switch/case Statement
if(expression) if (expression)
statement_1; {
else statement_1;
statement_2; statement_2;
}
else
{
statement_3;
statement_4;
}
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
If..else.. statement flow chart
if(expression)
‘If’ block statements
Exercise
• Write a program which receives 2 numbers
(integers ) from the user and prints the biggest
of two .
• If n1 == n2, then print “both numbers are
equal”
So, when you enter a character for the above code , the scanf fails and returns 0.
The scanf fails for the character input because it was expecting a number
1. if Statement
2. if-else Statement
3. if-else-if ladder
4. Conditional Operators
5. Switch/case Statement
Statement(s)1
False
True
else if(expression2 )
Statement(s)2
False
True
else if(expression3 )
Statement(s)3
False
else Statement(s)4
Exercise
• Write a program to calculate income tax
payable of the user . Tax is calculate as per
below table.
Total income % of tax
Up to $9,525 0 Tax payable = Income * (tax rate / 100)
$9,526 to $38,700 12%
$38,701 to $82,500 22%
> $82,500 32% + $1000
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
1. if Statement
2. if-else Statement
3. if-else-if ladder
4. Conditional Operators
5. Switch/case Statement
Conditional Operators
• Conditional operator is a ternary operator in C
used for conditional evaluation.
• Operator symbol ?:
• It’s a ternary operator because it operates on
three operands.
uint32_t a = ( 5 + 4) ? (9 -4 ) : 99;
uint32_t a = ( 5 + 4) ? (9 -4 ) : 99;
a = 5;
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
TRUE
FALSE
Use case
• Sometimes you can use conditional operator
to replace if..else statements
Using if….else
1. if Statement
2. if-else Statement
3. if-else-if ladder
4. Conditional Operators
5. Switch/case Statement
Exercise
• Write a program to calculate the area of different geometrical
figures
– Circle , triangle , trapezoid , square and rectangle
• The program should ask the user to enter the code for which user
wants to find out the area
– ‘t’ for triangle
– ‘z’ trapezoid
– ‘c’ circle
– ‘s’ square
– ‘r’ rectangle
Base Radius
Height
Trapezoid
Side
Base Square
Base
Height
Length
Width
Looping in ‘C’
Loops in ‘C’
• There are three types of loop statements in ‘C’
– while loop
– for loop
– do…while loop
while, for, do
(‘C’ reserved keywords)
Example
• Write a program which prints from 1 to 10
using ‘while’ loop
Equivalent to
Example
• Write a program to print all even numbers between 0
to 100(including boundaries )
• Also count and print how many even numbers you
find.
– Use ‘while’ loop or ‘for’ loop or ‘do while’ loop
– Later change the program to accept boundary numbers
from the user
Hangs forever
forever loop
A special form of the while loop is the forever loop. This is a loop that never ends. It is
common to see this in an embedded application in the main program. Unlike a PC
program, an embedded program may just run forever (or as long as it is powered up).
Loops in ‘C’
• There are three types of loop statements in ‘C’
– while loop
– for loop
– do…while loop
While, for, do
(standard ‘C’ keywords)
False
Repeat execution of code inside the “do”
body until expression evaluates to false(0)
Program continues with the
code outside loop body
}
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
Flow chart of for loop
www.fastbitlab.com
Execute block-3
TRUE Done
Execute body
i++ Incrementation/decrementation
(block-3)
for( ; ; )
{
for( ; ; )
{
}
}
Exercise
• Modify the LED on program in to LED toggle
program by creating a software delay between
LED on and LED off
• LED should continuously toggle with certain
time delay forever.
Exercise
• Write a program which reads the status of the
pin PA0. If the status of PA0 is LOW then turn
off the on board LED(PD12) and if the status of
PA0 is HIGH then turn on the LED.
• Change the status of PA0 pin manually by
connecting between GND and VDD points of
the board.
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Some hints
• PA0 should be in input mode
• To read from pin PA0, your code has to read
PORT-A input data register
✓It is part of the ARM Debug Interface Specification v5 and is an alternative to JTAG
✓ By using SWD inteface should be able to program MCUs internal flash , you can access
memory regions , add breakpoints, stop/run CPU.
✓The other good thing about SWD is you can use the serial wire viewer for your printf
statements for debugging.
ITM unit
FIFO
Debug connector(SWD)
SWO Pin
This SWO pin is connected to ST link circuitry
of the board and can be captured using our
debug software (IDE)
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Native compilation
Host Machine
sizeof
• Find out storage sizes of the below data types
for your cross compiler
– char
– int
– long
– long long
– double
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Build process
• Preprocessing
• Parsing
• Producing object file(s)
• Linking object files(s)
• Producing final executable
• Post processing of final executable
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Compilation stage of the build
Assembler
Preprocessing
compilation
linking
What is Microcontroller ?
• Microcontroller (MCU, μC) is a small computer system on a
single chip. But its resources and capabilities such as memory,
speed, external interfaces are very much limited than of a
desktop computer because of MCU targets embedded
applications.
• A typical microcontroller includes a processor, volatile and
non-volatile memories, input/output(I/O) pins, peripherals,
clock, bus interfaces on a single chip.
A Microcontroller
Code memory
Code Memory Type : Flash
data memory
Data Memory Type :
SRAM (Static RAM)
Internal memories
CPU
(volatile and non
(ARM Cortex Mx)
volatile )
Voltage regulators
And other power
control ckts
Clock producing
Peripherals
ckts
PIC16F887
"Peripheral Interface
Controller" made by
Microchip Technology
A Microcontroller
DISPLAY
Code memory
• The purpose of the code(Program) memory is to store
instructions and constant data of your program.
• There are different types of code memory
– ROM (Read only Memory)
• MPROM (Mask Programmable Read only Memory)
• EPROM (Ultraviolet Erasable Programmable ROM)
• EEPROM (Electrically Erasable Programmable ROM)
– OTP (On time programmable)
– Flash
– FRAM(Ferroelectric Random Access memory )
ROM
• Once code is stored inside the ROM, it cant be
modified . Only reading is allowed .
• Suitable during MCU production with prewritten
code targeting certain applications which will
never be modified.
• Usage of ROM technology reduces cost. Because
ROM is cheaper than Flash technology.
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
code
So, our main function
starts at address
0x080001e8 in the code
memory
code
This time we are going to again analyze the elf file of our project
Because at the end of the day, this file should contain all the code and data right ?
we must be surprised
here to see , our project
already has 1076 bytes of
data
data
Caller
Argument passing
(Call by value)
Callee
Please note that header files are not compulsory for your project but most of the
time header files bring more structure to our project and it is always
recommended to use header files. Some times usage of header files become
compulsory when you access C standard library codes or functions from your
source file.
C Standard libraries
*Not really true , will discuss more on this later. But for a time being let's believe
that main is starting point of execution of our c project
Function body
Executables
Led_project.elf Led_project.bin
Lets analyze the elf executable generated to understand what are the codes and
data hidden in our project .
Led_Project.elf
code data
Now, fortunately there is one command which we can run to analyze the
elf files . To understand code section and data section
Memory map
Processor core
Register sets
in ‘C’
• A Decimal Number contains a Decimal Point.
•125.55 is a decimal number ( a real number)
• In computer memory, the real numbers are stored according to the
representation standardized by the IEEE standard 754
• IEEE754 floating-point representation is an approximate representation
of real numbers.
• All computer systems and microcontrollers nowadays use this standard
to store real numbers in memory
• If you are working with numbers that have a fractional part or in case
you are using integers that don't fit into a long data type, then we can
use floating-point representation.
representation?
• To store, a too-small number in memory
• To store, a too big number in memory
• To ofstore,
Think these situations
decimal number
1) Storing charge of an electron (too small)
2) Storing light years to kilometers conversion
3) Which data type do you use to store 1.767 x 10100 (too big)?
+7.432 x 1048
+7.432 x 1048
Exponent
sign Mantissa
(Significand)
31 30 22 0
63 62 51 0
125.55
• You cannot represent this number in a program using integer data
types like int, char, long.
• You need particular data types to represent these decimal numbers
– Float (32-bit floating-point representation, single precision )
– Double (64-bit floating-point representation, double precision )
data types
• Use%lf format specifier to read or write double type variable
• Use %f format specifier to read or write float type variable
• Use %e %l format specifier to read or write real numbers in
e
scientific notation
• All constants with a decimal point are considered as double by
default
Exercise
• Find out the number of electrons responsible for
producing the given charge. Use scientific notation
while inputting and outputting the numbers.
Number of electrons = given charge / charge of Electron
Range of float
Storage size : 4 bytes
Precision : up to 6 decimal places
Value range : 1.2x10-38 to 3.4x1038
Range of double
Storage size : 8 bytes
Precision : up to 15 decimal places
Value range : 2.3x10-308 to 1.7x10308
Type qualifier
of a variable
‘const’ doesn’t mean that the value never changes, its only programming safety
feature to ensure that the programmer shouldn’t try to modify the value.
‘const’ doesn’t mean that the value never changes, its only
programming safety feature to ensure that the programmer shouldn’t
try to modify the value.
memory
• All local const variables are just like non-const variables as far as
memory placement is concerned. They are placed in RAM. The
only specialty of a const variable is, it is read-only
• All Global const variables are stored in ROM or FLASH. This also
further depends on linker script rules and the hardware on
which code runs.
• In STM32 target hardware, all global const variables live in
FLASH memory. So, when you try to modify the const variable
using its address, operation has no effect. Because flash memory
of the microcontroller is write-protected.
Use cases:
To define mathematical constants in the program
float const pi = 3.1415;
float const radius = 4;
int const number_of_months = 12;
• Here the pointer pData is modifiable but the data pointed by the
pData cannot be modifiable (read-only).
• So, we can say that pData is a pointer pointing to read-only data
Allowed Not-allowed
pData = (uint8_t*) 0x50000000;
*pData = 50;
• Here the pointer pData is read-only but the data pointed by the pData
can be modifiable.
• So, we can say that pData is a read only pointer pointing to modifiable
data
*pData = 10;
*pData = 60;
Use case :
Improve the readability
and guard the pointer
variables
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
• Here the pointer pData is read-only and the data pointed by the pData
is also read-only
• So, we can say that pData is a read only pointer pointing to read-only
data
pData is a constant pointer (*) pointing to constant data of type unsigned integer_8
Volatile
Volatile is a type qualifier in ‘C’ used with variables to instruct the
compiler not to invoke any optimization on the variable operation.
It tells the compiler that the value of the variable may change at
any time with our without the programmer’s consent. So, the
compiler turns off optimizing the read-write operations on variables
which are declared using volatile keyword
Syntax of using
‘volatile’
Use case :
This is a perfect case of accessing memory-mapped registers.
Use this syntax generously whenever you are accessing memory mapped
registers in your microcontroller code
Rarely used
Case4: volatile pointer to volatile data
uint8_t volatile *volatile pStatusReg;
0xF1
Input data register of a peripheral
Or a shared memory from which you are supposed to read-only
‘C’
• Structure is a data structure used to create user-defined
data types in ‘c’
• Structures allow us to combine data of different types
Creation of structure
struct tag_name
{
This is syntax
member_element-1; to create a
member_element-2; structure in C
member_element-3;
member_element-n;
};
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Example of a structure
struct CarModel
{
unsigned int This called structure definition
Structure definition doesn’t consume any memory
carNumber; .
uint32_t Its just a description or a record
carPrice;
uint16_t
carMaxSpeed; BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Variables of a structure
struct CarModel User defined data type Structure variables
{
unsigned int carNumber; struct CarModel CarBMW, CarFord , CarHonda ;
uint32_t carPrice; (Memory will be consumed when
uint16_t carMaxSpeed;
you create structure variables.)
float carWeight;
initialization
struct CarModel
{
unsigned int carNumber;
uint32_t carPrice;
uint16_t carMaxSpeed;
float carWeight;
struct CarModel CarBMW ={2021,15000,220,1330 }; // C89 method . Order is important
};
struct CarModel CarBMW ={.carNumber= 2021,.carWeight =1330 ,.carMaxSpeed =220,.carPrice =15000 };
//C99 method using designated initializers
Example
• Write a program to create a carModel structure discussed and
create 2 variables of type carModel. Initialize the variables
with the below given data and then print them
1. 2021,15000,220,1330
2. 4031,35000,160,1900.96
Example
• Write a program to create a carModel structure discussed and
create 2 variables of type carModel. Initialize the variables
with the user given data and then print all member elements .
Aligned/un-aligned data
access and structure
padding
short
Address 0403010 0403012 0403014 0403016 0403018 040301A
int
Address 0403010 0403014 0403018 040301C 0403020 0403024
char aboundary
char b char c char d
Address 0403010 0403011 0403012 0403013 0403014 0403015 0403016 0403017 0403018
short b short c
char a
char a
Address 0403010 0403011 0403012 0403013 0403014 0403015 0403016 0403017 0403018
Aligned data
char
Padding
Aligned data
char
Padding
Aligned data
• By default compiler always stores the data inside the memory in
aligned fashion(according to natural size boundary of variables )
• Aligned storage helps to achieve higher performance(in terms of
time & code space) using memory load and store instructions
• Aligned storage leads to generate fewer instructions to read data
from or write data into memory
• Reduces number of memory hits
• Aligned data consumes more data memory due to padding
Structure padding
Aligned storage
0 2 4
4 bytes width
arm-none-eabi-size packed_Vsnonpacked.elf
text data bss dec hexfilename
5144 108 1588 6840
1ab8packed_Vsnonpacked.elf packed
Finished building: default.size.stdout
};
struct CarModel carBMW, carFord; CardModel_t carBMW, carFord;
struct CarModel
{
unsigned int carNumber;
uint32_t carPrice;
uint16_t carMaxSpeed;
float carWeight;
struct CarModel *pcarBWM; //allowed
};
structure)
Contiguous memory
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
Let's say you have been given with the base address of a
structure variable and asked to change the member
element values what would you do ?
*(address_of_first_member_element_data1)= 0x55;
analysis
[Bits] 1 2 8 3 3 12 1 2
32 bits
Exercise
• Re-write the LED toggle application using
structure and bitfields. You have to create a
structure for every peripheral register you use
in this program.
• Access the structure member elements to
configure and access the peripheral registers.
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021
www.fastbitlab.com
32 bits
LSB
MSB
LSB
MSB
Bit-fields
SHORT_ADDR
ADDR_MODE STATUS
[Bits] 1 2 8 3 3 12 1 2
32 bits
So, can you convert this register information into a structure with bit fields ?
peripheral registers
32 bits width
0x4002_0C0
31 30 GPIOD port mode register 3 2 1 0
0
Register address
pin_15 pin_1 pin_0
32 bits width
0x4002_0C0
31 30 GPIOD port mode register 3 2 1 0
0
Register address
pin_15 pin_1 pin_0
32 bits width
0x4002_0C0
31 30 GPIOD port mode register 3 2 1 0
0
Register address
pin_15 pin_1 pin_0
32 bits width
0x4002_0C0
31 30 GPIOD port mode register 3 2 1 0
0
Register address
pin_15 pin_1 pin_0
32 bits width
0x4002_0C0
31 30 GPIOD port mode register 3 2 1 0
0
Register address
pin_15 pin_1 pin_0
peripheral
Update
Peripheral register
Peripheral circuit Configure sets
Exercise
• Create a generic structure for the GPIO peripherals,
which can be used to configure any GPIO peripheral.
• Keep individual bit field structures created in the
previous lecture as member elements of the above
mentioned generic structure.
• Re-Write the LED toggle application with the above
changes.
GPIOx
Note:
While writing member
elements into this structure,
give attention to offsets of
different registers.
Not maintaining the proper
offset will end up programming
wrong addresses
0x4 REG2
0x8 REG3
0xC REG4
0x10 REG5
0x14 REG6
Memory locations
Corresponds to
Address of the Member-element-1 : 0x4000_0C00 REG1
Address of the Member-element-2 : 0x4000_0C04 REG2
Address of the Member-element-3 : 0x4000_0C08 REG3
Address of the Member-element-4 : 0x4000_0C0C REG3
so on . ..
unions
unions
• A union in ‘C’ is similar to a structure except
that all of its members start at the same
location in memory.
• A union variable can represent the value of
only one of its members at a time.
structure
Structure memory allocation
0xE00 0xE01 0xE02 0xE03 0xE04 0xE05 0xE06 0xE07
System code
1. Bit extraction
2. Storing mutually exclusive data thus saving
memory
data
/* Extended address */
typedef struct typedef uint8 sAddrExt_t[SADDR_EXT_LEN];
{
union /* Combined short/extended device address */
{ typedef struct
uint16 shortAddr; {
ZLongAddr_t extAddr; union
} addr; {
byte addrMode; uint16 shortAddr; /* Short address */
} zAddrType_t; sAddrExt_t extAddr; /* Extended address */
} addr;
uint8 addrMode; /* Address mode */
} sAddr_t;
Optimization
Exercise
Modify the LED Toggle program by introducing
structure and bit fields to configure and access
the memory mapped peripheral registers.
Program optimization
• Optimization is a series of actions taken by the compiler
on your program’s code generation process to reduce
– Number of instructions (code space optimization )
– Memory access time (time space optimization )
– Power consumption
• By default, the compiler doesn’t invoke any optimization
on your program
• You can enable the optimization using compiler flags
optimization
• -O0
– No optimization .
– Not recommended for productions if you have limited code and ram space
– Has fastest compilation time
– This is debugging friendly and used during development
– A code which works with –O0 optimization may not work with –O0+ optimization levels. Code
needs to verified again.
• -O1
– Moderate optimization to decrease memory access time and code space
optimization
-O2 You need to work with different optimization levels to find
• Full optimization out what works for you.
• Slow compilation time For all code exercise we do in this course, we consider –O0
• Not debugging friendly optimization level.
-O3
• Full optimization of –O2 + some more aggressive optimization steps will be
taken by the compiler.
• Slowest compilation time
• May cause bugs in the program
• Not debugging friendly
Interfacing projects
Code from scratch using the
concepts of ,
• Pointers
• Memory mapped IOs
• Bitwise operators
• Structures and bit fields
• const and volatile type qualifiers
BHARATI SOFTWARE , CC BY-SA 4.0 , 2021