0% found this document useful (0 votes)
25 views49 pages

Embedded Internship Report

The internship report details the operations and services of Take It Smart (OPC) Pvt. Ltd, an Indian engineering and software company specializing in embedded systems and IoT. It outlines the company's mission, vision, and core values, along with its various services such as embedded application development and web solutions. The report also provides technical details on hardware components like the Arduino Uno and NodeMCU, which are essential for embedded system projects.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views49 pages

Embedded Internship Report

The internship report details the operations and services of Take It Smart (OPC) Pvt. Ltd, an Indian engineering and software company specializing in embedded systems and IoT. It outlines the company's mission, vision, and core values, along with its various services such as embedded application development and web solutions. The report also provides technical details on hardware components like the Arduino Uno and NodeMCU, which are essential for embedded system projects.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 49

INTERNSHIP REPORT ON

“EMBEDDED SYSTEM AND IOT”

EXTERNAL GUIDE NAME Mr JAGANATH A

POSITION TECHNICAL LEAD

EMAIL ID [email protected]

PHONE NO 8792697647
ABOUT COMPANY

TAKE IT SMART (OPC) PVT.LTD is an Indian based engineering and Software


Company headquartered in Bangalore, Karnataka, India. It is both product and service oriented
software company. All offices employ an experienced team of professionals, with an outstanding
track record of handling complex web & Apps development projects.

2.2 COMPANY STRATERGY

 Purpose: To be a leader in the software Industry by providing enhanced services,


relationship and profitability.
 Vision: To provide quality services that exceeds the expectations of our esteemed
customers.
Mission: To build long term relationships with our customers and clients and provide
exceptional customer services by pursuing business through innovation and advanced technology.

 Core values:

 To incorporate good business practices in order to achieve customer satisfaction and treating
the customers with respect and faith.

 To grow through creativity, invention and innovation.

 To integrate honesty, integrity and business ethics into all aspects of the business function-
ing.

Goals:

 To improve, grow and become more efficient in the field electronics engineering and soft-
ware development and develop a strong base of key clients.

 To understand customer requirements and fulfill them.


 Increase the assets and investments of the organization to support the development of ser-
vices and expansion of the organization.

 To increase the productivity and improve the customer service satisfaction.

 To do Innovations in Software field and provide quality services to deliver a range of prod-
ucts.

2.3 COMPANY SERVICES


TAKE IT SMART (OPC) PVT.LTD have its own services such as,
 Embedded Applications development

 Web design and development

 IT Service

 Android app Development


 Web Bases Software Solutions
 Web Based ERP
 Web Based Ads Mobile Based Services: Mobile Web Apps a. Android Apps b. Windows
Apps c. IOS Apps d. Cross Plate forms Apps
 Native Apps
 Hybrid apps Get trained for industry requirements while you pursuing degree The Different
verticals that we operate in are:  Internship & Software Training

2.4 DOMAINS
TAKE IT SMART (OPC) PVT.LTD have working with several domains like-
 IT

 Digital marketing

2.5 DEPARTMENTS
 Marketing: These are the main section of the market departments:

 Sales department is responsible for the sales and distribution of the products to the different
regions.
 Promotion department decides on the type of promotion method for the products, arranges
advertisements and the advertising media used.

 Distribution department distributes the products across the industries.

 Embedded System and Internet of Things (IOT) department.

 Machine learning and web development department.

Business Address: Take It Smart (OPC) Pvt.Ltd

14,SGN Arcade, 1st Floor, 2nd stage, 1st Main Rd,

RPC Layout, Hoshalli Extension, Stage 1,

Vijayanagar, Bengaluru, Karnataka 560040

Mobile: +91-8050104212

Email: [email protected]

Website: www.takeitsmart.in
CONTENTS Page No

1. INTRODUCTION

2. HARDWARE DETAILS (Arduino UNO)

3.1. Atmega328 Microcontroller 8

3.1.1 Architecture 9

3.1.2 AVR CPU Core 10

3.1.3 Pin Configurations 12

3.1.4 Features 13

3.1.5 Power Modes 14

3.1.6 Ports 15

3.1.7 Analog to Digital Converter 15

3.1.8 USART 15

3.2. Power Supply 16

3.3 Relay 17

3.4 LM7805C Voltage Regulator 18

3.5 Crystal Oscillator 20


3.6 MAX232 and DB9 connector (Level Converter) 22

4. SOFTWARE REQUIREMENTS

4.1 Code Vision AVR Cross Compiler 25

4.2 AVR Studio Programmer 26

4.3 Embedded C 27

CHAPTER 1

INTRODUCTION

1.ABOUT EMBEDDED SYSTEM

The combination of hardware and software either fixed in capability or programmable is know
Embedded system , that is designed for a specific function. Embedded systems is device used
to control, monitor the operation of equipment’s , machinery or plant. “Embedded” refers to
the internal part.

These are classified into different steps :

Based on the Performance and Functional Requirement:

1. REAL TIME EMBEDDED SYSTEMS: type of systems are defined as these


systems in which the truthfulness of the system depends not only on the logical
result computation, but also the results are produced on time.
 Hard real-time systems (e.g., Avionic control).
 Firm real-time systems (e.g., Banking).
 Soft real-time systems (e.g., Video on demand).

2. DETACHED EMBEDDED SYSTEMS:

 This systems do not require a host like a computer, depends on itself.


 It takes the inputs from the either analog or digital and processes, calculates and modi-
fied the data and gives the end data through the link device which either controls, drives
and displays the linked devices.
 examples: mp3 music players, digital cameras, video game , microwave
ovens and temperature checkup systems.

3. NETWORKED EMBEDDED SYSTEMS:

 These systems are branch to a network to access the resources.


 connected network can be LAN, WAN, or the internet. The connection maybe
wireless or wired. This system is highest growing area in embedded system appli-
cations.

4. MOBILE EMBEDDED SYSTEMS:


.
 The basic limitations of these devices is the other resources and limitations.
 Mobile embedded systems are used in portable embedded devices like cell phone,
mobiles, digital cameras, mp3 players and personal digital assistants, etc

Based on the Performance of the Microcontroller:


1. SMALL SCALE EMBEDDED SYSTEMS:

 These types of systems are designed with a 8 or 16-bit single microcontroller, that
may be generated by a battery.
 For the developing embedded software for this embedded systems, the im-
portant programming tools are editor, assembler, cross assembler and IDE.

2. MEDIUM SCALE EMBEDDED SYSTEMS:

 Medium scale embedded systems are designed with a 16 or 32-bit MC, RISCs or DSPs.
 Both hardware and software complexities are available.
 For the developing embedded software for this system, the main tools are C, C+
+, JAVA, Visual,RTOS, debugger, source code engineering tool, simulator and
IDE.

3. WORDLY EMBEDDED SYSTEMS:

 These systems are designed with 32-bit.


 type of embedded systems have large hardware and software complexities.
 Which may require scalable or configurable processor and programming logical arrays.

CHAPTER 2

HARDWARE COMPONENTS

The hardware components used in our project is listed below.

1 Arduino Uno(Atmega328 microcontroller)

2 Power Supply

3 Relay

6 BLUETOOTH transceiver.

7. DC motor

8. Flame Sensor
10. MQ135
12. IR sensor
13. NodeMCU

2.1 Arduino Uno

Arduino is an open source, PC paraphernalia and programming organization,


endeavour, and client group that plans and produce microcontroller packs for
constructing programmed devices and intelligent object that can detect and
control questions in the real world. The inception of the Arduino extend
began at the Interaction Design Institute in Ivrea, Italy. The equipment
reference plans are appropriated under a Creative Commons Attribution
Share.

Atmega328 microcontroller

The microcontroller is at the core of every embedded module. Hence, great care must be exercised
in choosing the right microcontroller without compromising on functionality. Keeping in view many
factors that governed the correct implementation of our project the Atmega48 microcontroller from
Atmel Corporation’s AVR microcontroller family was chosen. Few crucial reasons may be cited so
as to justify our choice of this microcontroller. The first being, that all AVR microcontrollers are
designed to deliver more performance at lesser power consumption. It is compatible with popular
protocols like I2C and SPI. It also has advanced features like an on chip analog to digital converter,
six pulse width modulation channels, and data retention is supported up to a hundred years at 25º C.
Also compilers for the Atmega48/8 are available free of cost from the manufacturer. An added
advantage is that the AVR series can be programmed using the AVRGCC (GNU C compiler), thus
making it an undisputed choice for even GNU/Linux based programmers. The Atmega48
microcontroller has execution speeds of up to one MIPS per MHz of clock frequency. Elucidating
the specifications of the CPU of the AVR, it is an 8 bit microcontroller with advanced RISC
architecture. The CPU is designed for the stellar combination of parallelism and performance. Thus
the CPU uses the Harvard architecture (separate memories and buses for program and data). The
CPU also accommodates a 32 general purpose 8-bit registers.
8

3.1.1 Architecture

The Atmega328 is a low-power CMOS 8-bit microcontroller based on the AVR enhanced RISC
architecture. By executing powerful instructions in a single clock cycle, the ATmega88 achieves
throughputs approaching 1 MIPS per MHz allowing the system designer to optimize power
consumption versus processing speed. The AVR core combines a rich instruction set with 32 general
purpose working registers. All the 32 registers are directly connected to the Arithmetic Logic Unit
(ALU), allowing two independent registers to be accessed in one single instruction executed in one
clock cycle. The resulting architecture is more code efficient while achieving throughputs up to ten
times faster than conventional CISC microcontrollers. The architectural block diagram is as shown
in the next page.

Figure
3.1: Architectural Block Diagram of ATmega 328
3.1.2 AVR CPU Core

This section discusses the AVR core architecture in general. The main function of the CPU core is
to ensure correct program execution. The CPU must therefore be able to access memories, perform
calculations, control peripherals, and handle interrupts.

3.1.3 Pin Configurations

Figure 3.3: Pin configuration of the Atmega48 microcontroller

3.1.5 Power modes

The Idle mode stops the CPU while the SRAM, Timer/Counters, USART, 2-wire Serial Interface,
SPI port, and interrupt system continue to function. In the Power-down mode, the register contents
are saved but the oscillator is frozen until an interrupt is raised or the hardware is reset. In the
Power-save mode, the asynchronous timer is running while the remaining peripheral components of
the device are sleeping
3.1.6 Ports

The ports of the AVR have read-modify-write functionality when used as general digital I/O ports,
as stated in the datasheet of the device. The ports are bi-directional I/O ports with optional internal
pull-ups. Each port pin mainly has three register bits which are DDxn, PORTxn and PINxn. DDxn is
the data direction bit and indicates input or output at a particular pin of any port .
If DDxn is set to one, the pin is used as output pin, else it is an input pin. If PORTxn is written to a
logic one, and if DDxn is set to zero that particular pin’s internal pull up resistor is activated. The
DDxn is accessed at the DDRx register, the PORTxn is in the PORTx register and the PINxn is at
the PINx register. Writing a logic one to PINxn will toggle PORTxn. The alternate functions of the
port pins and the port registers are explained at the end as part of the datasheets. The pin value can
be read at any time through the PINxn register bit, irrespective of the DDxn pin setting.
3.1.7 Analog to digital converter

The Atmega48 is equipped with a successive approximation analog to digital converter with a
resolution of 10 bits. All the input channels of the ADC are connected to a multiplexer.

3.1.8 USART

A universal asynchronous receiver/transmitter (usually abbreviated UART and pronounced


is a type of "asynchronous receiver/transmitter", a piece of computer hardware that translates data
between parallel and serial forms. A UART is usually an individual (or part of an) integrated circuit
used for serial communications over a computer or peripheral device serial port.

15

Serial transmission of digital information (bits) through a single wire or other medium is
much more cost effective than parallel transmission through multiple wires. A UART is used to
convert the transmitted information between its sequential and parallel form at each end of the link.
Each UART contains a shift register which is the fundamental method of conversion between serial
and parallel forms.

The UART usually does not directly generate or receive the external signals used between
different items of equipment. Typically, separate interface devices are used to convert the logic level
signals of the UART to and from the external signaling levels. Communication may be "full duplex"
(both send and receive at the same time) or "half duplex" (devices take turns transmitting and
receiving).
3.1.8.1 Features

 Asynchronous or Synchronous Operation


 Full Duplex Operation (Independent Serial Receive and Transmit Registers)
 Master or Slave Clocked Synchronous Operation
 High Resolution Baud Rate Generator

3.1 NodeMCU V3 For Fast IoT Applica-


tion Development

The best way to develop quickly an IoT application with less Integrated circuits to add is to choose
this circuit “NodeMCU”. Today,we will give a detailed Introduction on NodeMCU V3. It is an open-
source firmware and development kit that plays a vital role in designing a proper IoT product using a
few script lines.

The module is mainly based on ESP8266 that is a low-cost Wi-Fi microchip


incorporating both a full TCP/IP stack and microcontroller capability. It is introduced
by manufacturer Espressif Systems. The ESP8266 NodeMcu is a complex device, which
combines some features of the ordinary Arduino board with the possibility of connecting to
the internet.

Arduino Modules and Microcontrollers have always been a great choice to incorporate automation
into the relevant project. But these modules come with a little drawback as they don’t feature a
built-in WiFi capability, subsequently, we need to add external WiFi protocol into these devices to
make them compatible with the internet channel.

This is the famous NodeMCU which is based on ESP8266 WiFi SoC. This is version 3 and it is
based on ESP-12E (An ESP8266 based WiFi module). NodeMCU is also an open-source
firmware and development kit that helps you to prototype your IOT product within a few
LUA script lines, and of course you can always program it with Arduino IDE.
In this article, We will try present useful details related to this WiFi Development Kit, its main
features, pinout and everything we need to know about this module and the application domain.
Introduction NodeMCU V3

NodeMCU V3 is an open-source firmware and development kit that plays a vital role in designing an
IoT product using a few script lines.

Multiple GPIO pins on the board allow us to connect the board with other peripherals and are
capable of generating PWM, I2C, SPI, and UART serial communications.

 The interface of the module is mainly divided into two parts including both
Firmware and Hardware where former runs on the ESP8266 Wi-Fi SoC and later is
based on the ESP-12 module.
The firmware is based on Lua – A scripting language that is easy to learn, giving
a simple programming environment layered with a fast scripting language that connects you with a
well-known developer community.
And open source firmware gives you the flexibility to edit, modify and rebuilt

the existing module and keep changing the entire interface until you succeed in optimizing the
module as per your requirements.

 USB to UART converter is added on the module that helps in converting USB data
to UART data which mainly understands the language of serial communication.
Instead of the regular USB port, MicroUSB port is included in the module that
connects it with the computer for dual purposes: programming and powering up the board.

 The board incorporates status LED that blinks and turns off immediately, giving
you the current status of the module if it is running properly when connected with
the computer.
The ability of module to establish a flawless WiFi connection between two
channels makes it an ideal choice for incorporating it with other embedded devices like Raspberry Pi.

NodeMCU V3 Pinout
NodeMCU V3 comes with a number of GPIO Pins

figure shows the Pinout of the board.


 There is a candid difference between Vin and VU where former is the reg-
ulated voltage that may stand somewhere between 7 to 12 V while later is
the power voltage for USB that must be kept around 5 V.

3.2 Power Supply

Power supply is used to energies the whole module. The power supply can be in the form
of wired or battery. In our project 12v battery/adapteris used as a power supply.

16

3.3 Relay
Relay is an electrically operated switch. Relays allow one circuit to switch a
second circuit which can be completely separate from the first. Relays can switch AC and
DC, transistors can only switch DC. Relays can switch higher voltages than standard
transistors. Relays are often a better choice for switching large currents (> 5A). Relays
can switch many contacts at once.

Figure 3.4: Relay symbol

10
Figure 3.5: Circuit diagram of relay

17

3.4 Crystal Oscillator - 16MHz :


A crystal oscillator is an electronic circuit that uses the mechanical resonance of a
vibrating crystal of piezoelectric material to create an electrical signal with a very precise
frequency. This frequency is commonly used to keep track of time, to provide a stable
clock signal for digital integrated circuits, and to stabilize frequencies for radio
transmitters and receivers.

The most common type of piezoelectric resonator used is the quartz crystal, so oscillator
circuits designed around them were called "crystal oscillators".A crystal is a solid in
which the constituent atoms, molecules, or ions are packed in a regularly ordered,
repeating pattern extending in all three spatial dimensions.

3.5 BLUETOOTH (TRANSRECIEVER)

BLUETOOTH was created to address the market need for a cost-effective,


standards-based wireless networking solution that supports low data-rates, low-power
consumption-users expect battery to last months to years, security, and reliability.
BLUETOOTH is the only standards-based technology that addresses the unique needs of
most remote monitoring and control and sensory network applications.

The initial markets for the BLUETOOTH Alliance include Consumer Electronics,
Energy Management and Efficiency, Health Care, Home Automation, Building
Automation and Industrial Automation.
11
24

Flame Sensor:

A sensor which is most sensitive to a normal light is known as a flame sensor. That’s why
this sensor module is used in flame alarms. This sensor detects flame otherwise
wavelength within the range of 760 nm – 1100 nm from the light source. This sensor can
be easily damaged to high temperature. So this sensor can be placed at a certain distance
from the flame. The flame detection can be done from a 100cm distance and the detection
angle will be 600. The output of this sensor is an analog signal or digital signal. These
sensors are used in fire fighting robots like as a flame alarm.

12
IR SENSOR

• A Passive Infrared sensor (PIR sensor) is an electronic device that


measures infrared (IR) light radiating from objects in its field of view. PIR sensors
are often used in the construction of PIR-based motion detectors (see below).
Apparent motion is detected when an infrared source with one temperature, such
as a human, passes in front of an infrared source with another temperature, such as
a wall.

DHT11:

The requirement of a sensor is to react for input physical property and convert it
into an electrical signal that is suitable with electronic circuits (Fraden 2010, 2).
Sensors are electronic devices that measure a physical quality such as light or
temperature and convert it to a voltage. Example of digital temperature and
moisture sensor is presented in Graph 9. There are two types of sensors: digital
and analog.

The output of digital sensor where is between 0 and 1 which can translate to
sensors voltage range. Analog sensor can output any value between its voltage
ranges. According to the reading from the sensor changes its output. Digital
sensor output is ON (1) often 5v, or OFF (0), 0v. Analog sensor is used to measure
precise numerical information like temperature or speed. Analog sensors can
13
output almost an infinite range of values. Output pin of sensor connected to
input pinafore denim show the digital form is obtained by the conversion of data.

Some sensors have analog to digital converter embedded to the sensor so the data
is outputted as digital data. After data is processed to digital form, it can be
processed on the microcontroller. (Karvinen & Karvinen, 2014.)

14
Chapter-4
SOFTWARE REQUIREMENTS

The software components used in our project is listed below.


1. Arduino ide
2.Embedded C

4.1 Arduino IDE

You will be needing Arduino IDE software to write and upload the programming logic
onto the Arduino Uno board

4.2 Embedded C
Embedded C is extensive and contains many advanced concepts. The range of modules
covers a full introduction to C, real-time and embedded systems concepts through to the
design and implementation of real time embedded or standalone systems based on real-
time operating systems and their device drivers. Real time Linux (RTLinux) is used as an
example of such a system. The modules include an introduction to the development of
Linux device drivers. Embedded C covers all of the important features of the C language
as well as a good grounding in the principles and practices of real-time systems
development including the POSIX threads (pthreads) specification.

The design of the modules is intended to provide an excellent working knowledge of the
C language and its application to serious real time or embedded systems. Those wanting
in-depth training specifically on RTLinux or Linux kernel internals should contact us to
discuss their requirements; this set of modules is geared more towards providing the
groundwork for approaching those domains rather than as in-depth training on a specific
approach.

Embedded C contains essential information for anyone developing embedded systems


such as microcontrollers, real-time control systems, mobile device, PDAs and similar
applications. This C course is based on many years experience of teaching C, extensive
industrial programming experience and also participation in the ANSI X3J11 and BSI
standards bodies that produced the standard for C. We focus on the needs of day-to-day
users of the language with the emphasis being on practical use and delivery of reliable
software.

15
GENERAL ROLES AND RESPONSIBILITIES

I was interned at the Embedded Department where i was provided exposure to


various microcontroller boards that were available for development of various
IOT application areas like consumer, home automation, security, surveillance,
health care, etc. The main agenda of the department to bond the gap between
the company and the students by providing them with practical experience by
considering the various constraints that comes into effect during the physical
implementation of a project.

The department where I was interned helped me bridge the gap between
the industry and academia by providing the complete experience to on board
using the various microcontroller boards like AVR microcontroller, nodemcu
microcontroller etc.

The department has an Industry Excellence Experience Center to learn,


innovate, and prototype embedded designs on various Industry standard
hardware and microcontroller platforms. At the same time build a Rewarding
Career to students in embedded Engineering Domain. The Lab setup and training
helped me to become a competent and productive Analog and Digital design
Engineers. The training enabled me to acquire knowledge, skills and practical
experience across the entire front end and backend Full Custom Flow (Circuit to
tape- out). The training covers key fundamental concepts of Physical Design
methodology which will enhance the employability of the students. The Sessions,
Lab exercises and Industry Standard Projects enabled me to get through instills
confidence and the analytical abilities required to work on complex industry’s
challenges in various Deep Sub-Micron Technology Process. Exposure to the use
of Physical Design tools familiarity with timing closure and related topics are
covered.

16
34

Chapter-5

BIBLIOGRAPHY

1.https://www.microchip.com/en-us/products/microcontrollers-and-microprocessors/8-bit-mcus/avr-mcus
2.https://arduino-esp8266.readthedocs.io/en/latest/

17
Take IT Smart Report

Module 1: Embedded C Programming

Introduction to C:
● C-language is always a preferred choice for Embedded software development because of
the following reasons:
○ C supports low-level access through pointers
○ C-language is processor independent
○ C-data types are suitable for Embedded Systems because these data types are
portable.
○ C supports Bit Manipulation, Memory management, and multithreading fea-
tures.
Difference Between C and Embedded C

S.No. C Embedded C

1 It is a structural and general Embedded C is generally used to develop


purpose programming microcontroller-based applications.
language used by the
developers to build desktop-
based applications.

2 C is a high-level programming Embedded C is just the extension variant of the C


language. language.

3 This programming language is On the other hand, embedded C language is truly


hardware independent. hardware dependent.

4 The compilers in C language The compilers in embedded C are OS


are OS dependent. independent.

5 Here, the traditional or Here, we need a specific compiler that can help
standard compilers are used to in generating micro-controller based results.
run the program.

6 Famous compilers used in C Famous compilers used in embedded C are GCC,


are Intel C++, Borland turbo C, Keil Compiler, SPJ Compiler, Embedded GNU C
and more. Compiler and more.

Tools used to work on:


18
Embedded C development relies on a variety of tools, including Integrated Development
Environments (IDEs), compilers, debuggers, and simulators. Common IDEs include Eclipse, Keil,
IAR Embedded Workbench, and Visual Studio. Debugging tools like GDB and JTAG are essential
for inspecting and modifying code during runtime. Cross-compilers, simulators (like QEMU), and
emulators (like Proteus) are used to translate and test code on different architectures.
Integrated Development Environments (IDEs):
 Eclipse: A versatile, open-source IDE that can be customized for embedded C de-
velopment.
 Keil: A popular IDE, especially for 8051 and ARM-based microcontrollers.
 IAR Embedded Workbench: A commercial IDE with strong support for various
embedded processors.
 Visual Studio: Microsoft's IDE, also suitable for embedded development, espe-
cially on Windows.
 MPLAB X: An open-source IDE from Microchip, specifically for their PIC microcon-
trollers.
 Arduino IDE: If you're using Arduino boards, their IDE is a convenient starting
point.
 NetBeans: A free, open-source IDE that can support C and C++ development.
 CLion: A lightweight IDE from JetBrains specifically designed for C and C++ devel-
opment.
Compilers:
 Cross-compilers: Compile code on one system (like a PC) to run on a different sys-
tem (the target embedded device).
 MPLAB XC8: A free compiler from Microchip for PIC microcontrollers.
 IAR Compiler: A commercial compiler known for its optimization capabilities.

Debuggers:
 GDB (GNU Debugger): A powerful command-line debugger.
 JTAG (Joint Test Action Group): A standard for testing and debugging integrated
circuits, often used in embedded systems.
 In-circuit emulators: Devices that allow debugging without physically having to
disassemble the target device.
Simulators and Emulators:
 QEMU: A versatile emulator that can simulate various architectures.
 Proteus: A simulator for electronic circuits, allowing you to test the interaction of
your software with the hardware.
 MATLAB/Simulink: Used for modeling and simulating real-time systems, includ-
ing embedded systems
Other Tools:
 Static analyzers: Tools that analyze code for potential errors and vulnerabilities
before compilation.
 Code coverage tools: Help ensure that your code is thoroughly tested.
 Profiling tools: Tools that help identify performance bottlenecks in your code.
 Build tools: Makefiles or CMake are used to automate the build process.
 Real-time operating systems (RTOS): Like FreeRTOS, provide a framework for
scheduling tasks and managing resources in a real-time environment.
 Version control systems: Like Git, help manage and track changes to your code.

Fundamentals of C:
19
Key Characteristics of Embedded C
 Efficiency: In Embedded C we can create an efficient code to optimize the limited re-
sources available in embedded systems. It aims to minimize memory usage and maximize
performance.
 Direct Hardware Interaction: Embedded C allows programmers to interact directly with
hardware components, such as microcontrollers, sensors, actuators, and other peripher-
als. This direct interaction facilitates precise control over the hardware, critical in embed-
ded applications.
 Low-level Programming: Embedded C involves low-level programming, which deals with
hardware-specific details like memory addresses, I/O ports, and register manipulation.
This level of control is essential for efficiently managing hardware resources.
 Real-time Operations: Embedded systems often operate in real-time environments, re-
quiring precise timing and response to events. Embedded C allows programmers to han-
dle real-time tasks efficiently.
Structure of Embedded C Program
 Comments: Comments are readable text written to help user understand the code easily.
They are ignored by compiler and do not take up any memory in the final code. There are
two types of comments, Single line comments and Multiline comments.
 Preprocessor Directive: In Embedded C Preprocessor Directives are represented using
#include or #define. Preprocessor Directives are used to indicate a header file specific to
a microprocessor or microcontroller which contains all the functions, SFR's and the bits in
those SFR's. reg51 header file is used in case of 8051 microcontroller.
 Global Variables: Global variables as the name suggests are global to program that is
they can be accessed anywhere in the program. Global variables are static variables and
are placed in RAM memory locations.
 Local Variables: Local variables in contrast to global variables are confined to their re-
spective functions. Normally these variables are placed in stack or registers. It is only
valid within the function in which it is declared.
 Function: Function is a group of statements that together performs a task. A function
declaration tells the compiler about the name, return type and parameter of the func-
tion. A function definition provides actual body of the function.
 Main Function: Every Embedded C program has one main function and may contain one
or more functions in the main functions. The program execution starts from the main
function, and it is a core of every execution. If more than one main function is written in
the code, then compiler will confuse from where to start the program execution.
Standard Embedded C Data Types
Data Type Bits Range

Unsigned char 8 0 - 255

Signed char 8 -128 - +127

Unsigned int 16 0 - 65535

Signed int 16 -32768 - +32767

bit 1 0-1

sbit 1 0-1

20
sfr 8 0 - 255

sfr16 16 0 - 65535

Embedded C Programming Block Diagram

Memory Layout of a C Program:

Text Segment
 After we compile the program, a binary file generates, which is used to execute our pro-
gram by loading it into RAM. This binary file contains instructions, and these instructions
get stored in the text segment of the memory.
 Text segment has read-only permission that prevents the program from accidental modi-
fications.
 Text segment in RAM is shareable so that a single copy is required in the memory for fre-
quent applications like a text editor, shells, etc.
Initialized data segment:
Initialized data segment or data segment is part of the computer's virtual memory space of a C
program that contains values of all external, global, static, and constant variables whose values
are initialized at the time of variable declaration in the program. Because the values of variables
can change during program execution, this memory segment has read-write permission. We can
further classify the data segment into the read-write and read-only areas. const variable comes
under the read-only area. The remaining types of variables come in the read-write area. For
example,

21
const hello* = "Data segment";

Here, the pointer variable hello comes under the read-write area, and the value of the string
literal "Data segment" lies comes under initialized read-only data segment.

#include<stdio.h>

/* global variables stored in the read-write part of


initialized data segment
*/
int global_var = 50;
char* hello = "Hello World";
/* global variables stored in the read-only part of
initialized data segment
*/
const int global_var2 = 30;

int main() {
// static variable stored in initialized data segment
static int a = 10;
// ...
return 0;
}

In this example, variables global_var and pointer hello are declared outside the scope of main()
function because of which they are stored in the read-write part of the initialized data
segment but, global variable global_var2 is declared with the keyword const and hence it is
stored in the read-only part of initialized data segment. Static variables like a are also stored in
this part of the memory.
Uninitialized data segment
An uninitialized data segment is also known as bss (block started by symbol). The program loaded
allocates memory for this segment when it loads. Every data in bss is initialized to arithmetic
0 and pointers to null pointer by the kernel before the C program executes. BSS also contains all
the static and global variables, initialized with arithmetic 0. Because values of variables stored in
bss can be changed, this data segment has read-write permissions.

#include <stdio.h>

// Uninitialized global variable stored in the bss segment


int global_variable;

int main()
{
// Uninitialized static variable stored in bss
static int static_variable;

// ..
printf("global_variable = %d\n", global_variable);
printf("static_variable = %d\n", static_variable);
return 0;
}

Output
global_variable = 0
22
static_variable = 0

Here, both the variables global_variable and static_variables are uninitialized. Hence they are
stored in the bss segment in the memory layout in C. Before the program execution begins, these
values are initialized with value 0 by the kernel. This can be verified by printing the values of the
variable as shown in the program.
Stack
The stack segment follows the LIFO (Last In First Out) structure and grows down to the lower
address, but it depends on computer architecture. Stack grows in the direction opposite to heap.
Stack segment stores the value of local variables and values of parameters passed to a
function along with some additional information like the instruction's return address, which is to
be executed after a function call.

Stack pointer register keeps track of the top of the stack and its value change when push/pop
actions are performed on the segment. The values are passed to stack when a function is
called stack frame. Stack frame stores the value of function temporary variables and some
automatic variables that store extra information like the return address and details of the caller's
environment (memory registers). Each time function calls itself recursively, a new stack frame is
created, which allows a set of variables of one stack frame to not interfere with other variables of
a different instance of the function. This is how recursive functions work.
Let us see an example to understand the variables stored in the stack memory segment.

#include<stdio.h>

void foo() {
// local variables stored in the stack
// when the function call is made
int a, b;
}

int main() {
// local variables stored in the stack
int local = 5;
char name[26];
foo();
// ..
return 0;
}

Here, all the variables are stored in a stack memory layout in C because they are declared inside
their parent function's scope. These variables only take the space in memory till their function is
executed. For example, in the above code, the first main() starts its execution, and a stack frame
for main() is made and pushed into the program stack with data of variables local and name.
Then in main, we call foo, then another stack frame is made and pushed for it separately, which
23
contains data of variables a and b. After the execution of foo, its stack frame is popped out, and
its variable gets unallocated, and when the program ends, main's stack frame also gets popped
out.
Heap
Heap is used for memory which is allocated during the run time (dynamically allocated memory).
Heap generally begins at the end of bss segment and, they grow and shrink in the opposite
direction of the Stack. Commands like malloc, calloc, free, realloc, etc are used to manage
allocations in the heap segment which internally use sbrk and brk system calls to change memory
allocation within the heap segment. Heap data segment is shared among modules loading
dynamically and all the shared libraries in a process.

#include <stdio.h>
#include <stdlib.h>
int main() {
// memory allocated in heap segment
char *var = (char*) malloc ( sizeof(char) );
// ..
return 0;
}

Here, we create a variable of data type char by allocation memory of size 1 byte (equal to size
of char in C) at the time of program execution. Because the variable is created dynamically such
variables are initialized in the heap segment of the memory.
Command-line arguments
When a program executes with arguments passed from the console like argv and argc and other
environment variables, the value of these variables gets stored in this memory layout in C.

#include<stdio.h>

int main(int argc, char *argv[]) {


int i;

// first value in argv stores file name


printf("File name = %s\n", argv[0]);
printf("Number of arguments passed = %d\n", argc-1);
for(i = 1; i < argc; i++) {
printf("Value of Argument_%d = %s\n", i, argv[i]);
}

return 0;
}

Output:
~$ gcc file_1.c -o file_1
~$ ./file_1 100 23 43 69
File name = ./file_1
Number of arguments passed = 4
Value of Argument_1 = 100
Value of Argument_2 = 23
Value of Argument_3 = 43
Value of Argument_4 = 69

24
This example explains how command-line arguments are passed and used in the program. Here,
this segment stores the value of variables argc and argv where argc stores the number of
arguments passed and argv stores the value of actual parameters along with file name.

Compilation process of a C Program:

What is a Compilation?
Before diving into the traditional definition of compilation, let us consider an example where
there is a person A who speaks Hindi language and person A wants to talk to person B who only
knows English language, so now either of them requires a translator to translate their words to
communicate with each other. This process is known as translation, or in terms of programming,
it is known as compilation process.
The compilation process in C is converting an understandable human code into a Machine
understandable code and checking the syntax and semantics of the code to determine any syntax
errors or warnings present in our C program. Suppose we want to execute our C Program written
in an IDE (Integrated Development Environment). In that case, it has to go through several
phases of compilation (translation) to become an executable file that a machine can understand.

Compilation process in C involves four steps:


1. Preprocessing
2. Compiling
3. Assembling
4. Linking

The Compilation Process in C


a. Pre-Processing
Pre-processing is the first step in the compilation process in C performed using the pre-processor
tool (A pre-written program invoked by the system during the compilation). All the statements
starting with the # symbol in a C program are processed by the pre-processor, and it converts our
program file into an intermediate file with no # statements. Under following pre-processing tasks
are performed :
i. Comments Removal
Comments in a C Program are used to give a general idea about a particular statement or part of
25
code actually, comments are the part of code that is removed during the compilation process by
the pre-processor as they are not of particular use for the machine. The comments in the below
program will be removed from the program when the pre-processing phase completes.

/* This is a
multi-line comment in C */

#include<stdio.h>

int main()
{
// this is a single-line comment in C

return 0;
}

ii. Macros Expansion


Macros are some constant values or expressions defined using the #define directives in C
Language. A macro call leads to the macro expansion. The pre-processor creates an intermediate
file where some pre-written assembly level instructions replace the defined expressions or
constants (basically matching tokens). To differentiate between the original instructions and the
assembly instructions resulting from the macros expansion, a '+' sign is added to every macros
expanded statement.
Macros Examples:
Defining a value
#define G 9.8
Defining an expression
#define SUM(a,b) (a + b)
iii. File inclusion
File inclusion in C language is the addition of another file containing some pre-written code into
our C Program during the pre-processing. It is done using the #include directive. File inclusion
during pre-processing causes the entire content of filename to be added to the source code,
replacing the #include<filename> directive, creating a new intermediate file.
Example: If we have to use basic input/output functions like printf() and scanf() in our C program,
we have to include a pre-defined standard input output header file i.e. stdio.h.
#include <stdio.h>
iv. Conditional Compilation
Conditional compilation is running or avoiding a block of code after checking if a macro is defined
or not (a constant value or an expression defined using #define). The preprocessor replaces all
the conditional compilation directives with some pre-defined assembly code and passes a newly
expanded file to the compiler. Conditional compilation can be performed using commands
like #ifdef, #endif, #ifndef, #if, #else and #elif in a C Program. Example :
 Printing the AGE macro, if AGE macro is defined, else printing Not Defined and ending
the conditional compilation block with an #endif directive.
#include <stdio.h>

// if we uncomment the below line, then the program will print AGE in the output.
// #define AGE 18

int main()
{
// if `AGE` is defined then print the `AGE` else print "Not Defined"
#ifdef AGE
printf("Age is %d", AGE);
26
#else
printf("Not Defined");
#endif

return 0;
}
OUTPUT:
Not Defined

Explanation:
#ifdef directive checks if the macro AGE is defined or not, and as we have commented
the #define statement the #ifdef AGE block of code will not execute and control flow will move to
the #else block and Not Defined will be printed on the output screen, #endif ensures that the
conditional compilation block ends there.
Now let's see the below figure that shows how a pre-processor converts our source code file into
an intermediate file. Intermediate file has an extension of .i, and it is the expanded form of our C
program containing all the content of header files, macros expansion, and conditional
compilation.

b. Compiling
Compiling phase in C uses an inbuilt compiler software to convert the intermediate (.i) file into
an Assembly file (.s) having assembly level instructions (low-level code). To boost the
performance of the program C compiler translates the intermediate file to make an assembly file.
Assembly code is a simple English-type language used to write low-level instructions (in micro-
controller programs, we use assembly language). The whole program code is parsed (syntax
analysis) by the compiler software in one go, and it tells us about any syntax
errors or warnings present in the source code through the terminal window.
The below image shows an example of how the compiling phase works.

27
c. Assembling
Assembly level code (.s file) is converted into a machine-understandable code (in
binary/hexadecimal form) using an assembler. Assembler is a pre-written program that translates
assembly code into machine code. It takes basic instructions from an assembly code file and
converts them into binary/hexadecimal code specific to the machine type known as the object
code.
The file generated has the same name as the assembly file and is known as an object file with an
extension of .obj in DOS and .o in UNIX OS.
The below image shows an example of how the assembly phase works. An assembly file area.s is
translated to an object file area.o having the same name but a different extension.

d. Linking
Linking is a process of including the library files into our program. Library Files are some
predefined files that contain the definition of the functions in the machine language and these
files have an extension of .lib. Some unknown statements are written in the object (.o/.obj) file
that our operating system can't understand. You can understand this as a book having some
words that you don't know, and you will use a dictionary to find the meaning of those words.
Similarly, we use Library Files to give meaning to some unknown statements from our object file.
The linking process generates an executable file with an extension of .exe in DOS and .out in
UNIX OS.
The below image shows an example of how the linking phase works, and we have an object file
having machine-level code, it is passed through the linker which links the library files with the
object file to generate an executable file.

28
Storage classes:
auto
This is the default storage class for all the variables declared inside a function or a block. Auto
variables can be only accessed within the block/function they have been declared and not
outside them (which defines their scope).
Properties of auto Variables
 Scope: Local
 Default Value: Garbage Value
 Memory Location: RAM
 Lifetime: Till the end of its scope
static
This storage class is used to declare static variables that have the property of preserving their
value even after they are out of their scope! Hence, static variables preserve the value of their
last use in their scope.
Properties of static Storage Class
 Scope: Local
 Default Value: Zero
 Memory Location: RAM
 Lifetime: Till the end of the program
register
This storage class declares register variables that have the same functionality as that of the auto
variables. The only difference is that the compiler tries to store these variables in the register of
the microprocessor if a free register is available making it much faster than any of the other
variables.
Properties of register Storage Class Objects
 Scope: Local
 Default Value: Garbage Value
 Memory Location: Register in CPU or RAM
 Lifetime: Till the end of its scope
extern
Extern storage class simply tells us that the variable is defined elsewhere and not within the
same block where it is used. Basically, the value is assigned to it in a different block and this can
be overwritten/changed in a different block as well.
Also, a normal global variable can be made extern as well by placing the ‘extern’ keyword before
its declaration/definition in any function/block.
Properties of extern Storage Class Objects
 Scope: Global
 Default Value: Zero
 Memory Location: RAM
29
 Lifetime: Till the end of the program.

Type Qualifiers
Type qualifiers in C are keywords that modify the properties of variables. They provide additional
information to the compiler about how a variable should be treated, enabling optimizations and
ensuring correct program behavior, especially when dealing with hardware or
concurrency. There are four main type qualifiers in C: const, volatile, restrict,
and _Atomic (introduced in C11).
const
The const qualifier specifies that a variable's value cannot be changed after initialization. It is
used to define constants and to prevent accidental modification of data.

const int MAX_VALUE = 100;


const char* MESSAGE = "Hello";

volatile
The volatile qualifier indicates that a variable's value can be changed by external factors outside
the program's control, such as hardware or other threads. This prevents the compiler from
optimizing reads or writes to the variable, ensuring that the most up-to-date value is always
used.

volatile int sensor_data;

restrict
The restrict qualifier is used with pointers and indicates that the pointer is the only way to access
the memory it points to within a specific scope. This allows the compiler to perform more
aggressive optimizations, as it can assume that there are no other aliases to the memory
location.

void copy_array(int* restrict dest, const int* restrict src, int size);

_Atomic
The _Atomic qualifier (introduced in C11) specifies that access to a variable is atomic, meaning
that it cannot be interrupted by other threads. This is crucial for writing thread-safe code.

_Atomic int counter;

Flow control:
30
In Embedded C, control statements are essential for managing program flow, making decisions,
and repeating actions based on conditions. These statements include conditional statements
(like if, else, and switch), loop statements (like for, while, and do-while), and jump statements
(like break, continue, and goto).

Key Control Statements in Embedded C:


 Conditional Statements:
 if: Executes a block of code if a condition is true.
 else: Executes a block of code if the preceding if condition is false.
 switch: Selects one block of code to execute based on the value of an expres-
sion.
 Loop Statements:
 for: Repeats a block of code a specific number of times.
 while: Repeats a block of code as long as a condition is true.
 do-while: Repeats a block of code at least once, then continues as long as a con-
dition is true.
 Jump Statements:
 break: Exits the closest enclosing for, while, do-while, or switch statement.
 continue: Skips the rest of the current iteration of a loop and proceeds to the
next iteration.
 goto: Jumps to a labeled statement within the same function.

EXAMPLE:

#define PIN_LED 13

void setup() {
pinMode(PIN_LED, OUTPUT);
}

void loop() {
// Blink LED
digitalWrite(PIN_LED, HIGH);
delay(1000);
digitalWrite(PIN_LED, LOW);
delay(1000);

// Check if a button is pressed


if (digitalRead(BUTTON_PIN) == HIGH) {
// Do something if button is pressed
// ...
} else {
// Do something if button is not pressed
// ...
}
}

Explanation:
 The if statement checks the state of a button (defined by BUTTON_PIN).
 If the button is pressed (HIGH), one block of code is executed; otherwise, the other block
is executed.
 The delay function introduces pauses, controlling the blink rate of the LED.
 The code demonstrates how control statements can be used to respond to external in-
31
puts and manage the execution flow of an embedded system.

Operators:

Operators are symbols that perform operations on operands (variables and values). C language
has several types of operators, including:
 Arithmetic Operators:
Used for mathematical calculations.
 + (addition)
 - (subtraction)
 * (multiplication)
 / (division)
 % (modulus - remainder of division)
 Relational Operators:
Used for comparing values.
 == (equal to)
 != (not equal to)
 > (greater than)
 < (less than)
 >= (greater than or equal to)
 <= (less than or equal to)
 Logical Operators:
Used for combining or negating logical expressions.
 && (logical AND)
 || (logical OR)
 ! (logical NOT)
 Bitwise Operators:
Used for manipulating individual bits in binary numbers.
 & (bitwise AND)
 | (bitwise OR)
 ^ (bitwise XOR)
 ~ (bitwise NOT)
 << (left shift)
 >> (right shift)
 Assignment Operators:
Used for assigning values to variables.
 = (simple assignment)
 += (add and assign)
 -= (subtract and assign)
 *= (multiply and assign)
 /= (divide and assign)
 %= (modulus and assign)
 &= (bitwise AND and assign)
 |= (bitwise OR and assign)
 ^= (bitwise XOR and assign)
 <<= (left shift and assign)
 >>= (right shift and assign)
 Other Operators:
 sizeof (returns the size of a variable or data type in bytes)
 ? : (ternary or conditional operator)
 , (comma operator)
 . and -> (member access operators for structures and unions)
 & and * (address-of and dereference operators for pointers)
32
Functions:
A function in C is a set of statements that when called perform some specific tasks. It is the basic
building block of a C program that provides modularity and code reusability. The programming
statements of a function are enclosed within { } braces, having certain meanings and performing
certain operations. They are also called subroutines or procedures in other languages.
Syntax of Functions in C
The syntax of function can be divided into 3 aspects:
1. Function Declaration
2. Function Definition
3. Function Calls
Function Declarations
In a function declaration, we must provide the function name, its return type, and the number
and type of its parameters. A function declaration tells the compiler that there is a function with
the given name defined somewhere else in the program.
Syntax
return_type name_of_the_function (parameter_1, parameter_2);
The parameter name is not mandatory while declaring functions. We can also declare the
function without using the name of the data variables.

Example
int sum(int a, int b); // Function declaration with parameter names
int sum(int , int); // Function declaration without parameter names

Function Definition
The function definition consists of actual statements which are executed when the function is
called (i.e. when the program control comes to the function).
A C function is generally defined and declared in a single step because the function definition
always starts with the function declaration so we do not need to declare it explicitly. The below
example serves as both a function definition and a declaration.
return_type function_name (para1_type para1_name, para2_type para2_name)
{
// body of the function
}

33
Function Call
A function call is a statement that instructs the compiler to execute the function. We use the
function name and parameters in the function call.
In the below example, the first sum function is called and 10,30 are passed to the sum function.
After the function call sum of a and b is returned and control is also returned back to the main
function of the program.

Role of functions

Function Return Type


Function return type tells what type of value is returned after all function is executed. When we
don’t want to return a value, we can use the void data type.
Example:
int func(parameter_1,parameter_2);
The above function will return an integer value after running statements inside the function.
34
Note: Only one value can be returned from a C function. To return multiple values, we have to use
pointers or structures.
Function Arguments
Function Arguments (also known as Function Parameters) are the data that is passed to a
function.
Example:
int function_name(int var1, int var2);
Conditions of Return Types and Arguments
In C programming language, functions can be called either with or without arguments and might
return values. They may or might not return values to the calling functions.
1. Function with no arguments and no return value
2. Function with no arguments and with return value
3. Function with argument and with no return value
4. Function with arguments and with return value
How Does C Function Work?
Working of the C function can be broken into the following steps as mentioned below:
1. Declaring a function: Declaring a function is a step where we declare a function. Here we
specify the return types and parameters of the function.
2. Defining a function: This is where the function’s body is provided. Here, we specify what
the function does, including the operations to be performed when the function is called.
3. Calling the function: Calling the function is a step where we call the function by passing
the arguments in the function.
4. Executing the function: Executing the function is a step where we can run all the state-
ments inside the function to get the final result.
5. Returning a value: Returning a value is the step where the calculated value after the exe-
cution of the function is returned. Exiting the function is the final step where all the allo-
cated memory to the variables, functions, etc is destroyed before giving full control back
to the caller.
Types of Functions
There are two types of functions in C:
1. Library Functions
2. User Defined Functions

1. Library Function
A library function is also referred to as a “built-in function”. A compiler package already exists
that contains these functions, each of which has a specific meaning and is included in the
package. Built-in functions have the advantage of being directly usable without being defined,
whereas user-defined functions must be declared and defined before being used.
For Example:
pow(), sqrt(), strcmp(), strcpy() etc.
Advantages of C library functions
 C Library functions are easy to use and optimized for better performance.
 C library functions save a lot of time i.e, function development time.
 C library functions are convenient as they always work.

2. User Defined Function


Functions that the programmer creates are known as User-Defined functions or “tailor-made
functions”. User-defined functions can be improved and modified according to the need of the
programmer. Whenever we write a function that is case-specific and is not defined in any header
file, we need to declare and define our own functions according to the syntax.
Advantages of User-Defined Functions
 Changeable functions can be modified as per need.
 The Code of these functions is reusable in other programs.
 These functions are easy to understand, debug and maintain.
35
Passing Parameters to Functions
The data passed when the function is being invoked is known as the Actual parameters. In the
below program, 10 and 30 are known as actual parameters. Formal Parameters are the variable
and the data type as mentioned in the function declaration. In the below program, a and b are
known as formal parameters.

We can pass arguments to the C function in two ways:


1. Pass by Value
2. Pass by Reference

Pass by value / Pass by reference:


1. Pass by Value
Parameter passing in this method copies values from actual parameters into formal function
parameters. As a result, any changes made inside the functions do not reflect in the caller’s
parameters.
Example:
// C program to show use
// of call by value
#include <stdio.h>

void swap(int var1, int var2)


{
int temp = var1;
var1 = var2;
36
var2 = temp;
}

// Driver code
int main()
{
int var1 = 3, var2 = 2;
printf("Before swap Value of var1 and var2 is: %d, %d\n",
var1, var2);
swap(var1, var2);
printf("After swap Value of var1 and var2 is: %d, %d",
var1, var2);
return 0;
}

Output
Before swap Value of var1 and var2 is: 3, 2
After swap Value of var1 and var2 is: 3, 2

2. Pass by Reference
The caller’s actual parameters and the function’s actual parameters refer to the same locations,
so any changes made inside the function are reflected in the caller’s actual parameters.
Example:

// C program to show use of


// call by Reference
#include <stdio.h>

void swap(int *var1, int *var2)


{
int temp = *var1;
*var1 = *var2;
*var2 = temp;
}

// Driver code
int main()
{
int var1 = 3, var2 = 2;
printf("Before swap Value of var1 and var2 is: %d, %d\n",
var1, var2);
swap(&var1, &var2);
printf("After swap Value of var1 and var2 is: %d, %d",
var1, var2);
return 0;
}

Output
Before swap Value of var1 and var2 is: 3, 2
After swap Value of var1 and var2 is: 2, 3

Arrays:
37
An array is a variable that can store multiple values. For example, if you want to store 100
integers, you can create an array for it.
int data[100];
How to declare an array?
dataType arrayName[arraySize];
For example,

float mark[5];
Here, we declared an array, mark, of floating-point type. And its size is 5. Meaning, it can hold 5
floating-point values.
It's important to note that the size and type of an array cannot be changed once it is declared.

Access Array Elements


You can access elements of an array by indices.
Suppose you declared an array mark as above. The first element is mark[0], the second element
is mark[1] and so on.

Declare an Array
Few keynotes:
 Arrays have 0 as the first index, not 1. In this example, mark[0] is the first element.
 If the size of an array is n, to access the last element, the n-1 index is used. In this exam-
ple, mark[4]
 Suppose the starting address of mark[0] is 2120d. Then, the address of the mark[1] will
be 2124d. Similarly, the address of mark[2] will be 2128d and so on.
This is because the size of a float is 4 bytes.

How to initialize an array?


It is possible to initialize an array during declaration. For example,
int mark[5] = {19, 10, 8, 17, 9};
You can also initialize an array like this.
int mark[] = {19, 10, 8, 17, 9};
Here, we haven't specified the size. However, the compiler knows its size is 5 as we are initializing
it with 5 elements.

38
Initialize an Array
Here,
mark[0] is equal to 19
mark[1] is equal to 10
mark[2] is equal to 8
mark[3] is equal to 17
mark[4] is equal to 9

Change Value of Array elements


int mark[5] = {19, 10, 8, 17, 9}

// make the value of the third element to -1


mark[2] = -1;

// make the value of the fifth element to 0


mark[4] = 0;

Access elements out of its bound!


Suppose you declared an array of 10 elements. Let's say,
int testArray[10];
You can access the array elements from testArray[0] to testArray[9].
Now let's say if you try to access testArray[12]. The element is not available. This may cause
unexpected output (undefined behavior). Sometimes, you might get an error, and some other
times your program may run correctly.
Hence, you should never access elements of an array outside of its bound.

Multi-Dimensional Arrays
In C programming, you can create an array of arrays. These arrays are known as multidimensional
arrays. For example,
float x[3][4];
Here, x is a two-dimensional (2d) array. The array can hold 12 elements. You can think the array
as a table with 3 rows and each row has 4 columns.

Similarly, you can declare a three-dimensional (3d) array. For example,


float y[2][4][3];
39
Here, the array y can hold 24 elements.

Initializing a multidimensional array


Here is how you can initialize two-dimensional and three-dimensional arrays:

Initialization of a 2d array
// Different ways to initialize two-dimensional array

int c[2][3] = {{1, 3, 0}, {-1, 5, 9}};

int c[][3] = {{1, 3, 0}, {-1, 5, 9}};

int c[2][3] = {1, 3, 0, -1, 5, 9};

Initialization of a 3d array
You can initialize a three-dimensional array in a similar way to a two-dimensional array. Here's an
example,
int test[2][3][4] = {
{{3, 4, 2, 3}, {0, -3, 9, 11}, {23, 12, 23, 2}},
{{13, 4, 56, 3}, {5, 9, 3, 5}, {3, 1, 4, 9}}};

Arrays of characters and strings:

Arrays and pointers


Passing Array to function

Structures and Union:


What is structures
Declaration and initialization
Nested structure
Array of structure
Passing structure through functions
Allocation of memory
Structure comparison
Structure bit operation
TypeDef for portability
Union
Overlapping members

Pointers:
The purpose of Pointers
Defining the pointers
The & and * operators
Pointers Assignments
Pointers Arithmetic
Types of pointers
Array of pointers
Pointers to structure and union
Pointers to Dynamic allocation
40
Pointers type casting

Dynamic Memory Allocation:

Dynamic memory allocation is the process of allocating and deallocating memory blocks during a
program's runtime, as opposed to static memory allocation which occurs at compile time. It
allows programmers to reserve memory as needed, use it, and then release it back for reuse,
making it more efficient than statically allocating a fixed amount of memory.
To allocate memory dynamically, library functions are malloc(), calloc(), realloc() and free() are
used. These functions are defined in the <stdlib.h> header file.

C malloc()

The name "malloc" stands for memory allocation.

The malloc() function reserves a block of memory of the specified number of bytes. And, it
returns a pointer of void which can be casted into pointers of any form.

Syntax of malloc()

ptr = (castType*) malloc(size);

Example

ptr = (float*) malloc(100 * sizeof(float));

The above statement allocates 400 bytes of memory. It's because the size of float is 4 bytes.
And, the pointer ptr holds the address of the first byte in the allocated memory.

The expression results in a NULL pointer if the memory cannot be allocated.

calloc()

The name "calloc" stands for contiguous allocation.

The malloc() function allocates memory and leaves the memory uninitialized, whereas
the calloc() function allocates memory and initializes all bits to zero.

Syntax of calloc()

ptr = (castType*)calloc(n, size);

Example:

ptr = (float*) calloc(25, sizeof(float));

The above statement allocates contiguous space in memory for 25 elements of type float.

ree()

41
Dynamically allocated memory created with either calloc() or malloc() doesn't get freed on their
own. You must explicitly use free() to release the space.

Syntax of free()

free(ptr);

This statement frees the space allocated in the memory pointed by ptr.

realloc()

If the dynamically allocated memory is insufficient or more than required, you can change the
size of previously allocated memory using the realloc() function.

Syntax of realloc()

ptr = realloc(ptr, x);

Here, ptr is reallocated with a new size x.

42

You might also like