Chapter 3: Hardware level programming of
embedded systems
1
CHAPTER 3. HARDWARE LEVEL
PROGRAMMING OF EMBEDDED SYSTEMS
➢ Programming embedded systems at the hardware level involves writing software that
directly interacts with the underlying hardware components without the abstraction
provided by operating systems.
➢This type of programming is often done in languages like Assembly or utilizing low-level
languages like C to access specific registers and control hardware peripherals.
➢Here are the key aspects of hardware-level programming for embedded systems:
1. Understanding the Hardware:
❑ Before diving into hardware-level programming, it's crucial to have a deep understanding of
the embedded system's hardware architecture.
❑ This includes knowledge of the microcontroller or microprocessor, memory organization, I/O
ports, and other peripherals. 2
HARDWARE LEVEL …
2. Choosing the Right Language:
❑ While Assembly language is the most direct way to program at the hardware level, it
can be complex and platform-specific.
❑ Many embedded systems are programmed in low-level languages like C, which
allows for more abstraction while still providing control over hardware components.
3. Accessing Memory and Registers:
❑ Embedded systems typically have specific memory addresses and registers
associated with various hardware components.
❑ In hardware-level programming, you directly manipulate these addresses and
registers to control and communicate with peripherals.
3
HARDWARE LEVEL …
4. Peripheral Programming:
❑ Embedded systems often include peripherals such as timers, GPIO (General Purpose
Input/Output) pins, UART (Universal Asynchronous Receiver-Transmitter), SPI (Serial Peripheral
Interface), I2C (Inter-Integrated Circuit), ADC (Analog-to-Digital Converter), and more.
❑ Hardware-level programming involves configuring and controlling these peripherals.
❑ Example (Using C):
// Configuring GPIO pins as output
#define GPIO_PORTA_DIR_REG *((volatile uint32_t*) 0x40004000)
GPIO_PORTA_DIR_REG |= 0x01; // Set pin 0 as output
// Writing to GPIO pins
#define GPIO_PORTA_DATA_REG *((volatile uint32_t*) 0x400043FC)
GPIO_PORTA_DATA_REG |= 0x01; // Set pin 0 high
4
HARDWARE LEVEL …
5. Interrupt Handling:
❑ Hardware-level programming includes managing interrupts directly.
❑This involves configuring interrupt registers, writing interrupt service routines (ISRs), and handling
interrupt requests from peripherals or external events.
❑ Example (Using C):
// Configuring and enabling interrupts for a timer
#define TIMER0_CTL_REG *((volatile uint32_t*) 0x4003000C)
#define NVIC_EN0_REG *((volatile uint32_t*) 0xE000E100)
TIMER0_CTL_REG |= 0x01; // Enable timer
NVIC_EN0_REG |= 1 << 19; // Enable interrupt for Timer 0 5
HARDWARE LEVEL …
6. Memory Management:
➢ In embedded systems, memory management is crucial.
➢ Hardware-level programming involves managing both RAM and ROM effectively, considering factors
like data storage, program execution, and optimization.
7. Real-time Constraints:
➢ Many embedded systems have real-time constraints, requiring careful consideration of timing and
responsiveness.
➢ Hardware-level programming allows for precise control over timing-critical operations.
6
HARDWARE LEVEL …
8. Testing and Debugging:
Debugging at the hardware level can be challenging. Techniques such as using debugging tools, logic
analyzers, and in-circuit emulators can aid in identifying and fixing issues.
9. Energy Efficiency:
Optimizing code for energy efficiency is often a consideration in embedded systems. Hardware-level
programming allows for fine-tuning to minimize power consumption.
7
HARDWARE LEVEL …
10. Documentation and Standards:
➢Maintain clear documentation of memory addresses, register configurations, and other
hardware-related information.
➢Adhere to hardware-specific standards and guidelines to ensure portability and maintainability.
➢Challenges:
• Lack of portability due to hardware-specific code.
• Steeper learning curve, especially when dealing with Assembly language.
• Limited tool support compared to higher-level languages.
➢Advantages:
• Fine-grained control over hardware resources.
• Efficient code execution, crucial for resource-constrained devices.
• Well-suited for systems with real-time constraints.
8
▪ Architecture: 8-bit RISC (Reduced Instruction Set Computer)
▪ Uses Harvard Architecture (separate instruction and data memory)
▪ Efficient instruction execution, good for timing-sensitive applications
▪ Widely used in Arduino Uno and hobbyist platforms
▪ Architecture: 32-bit RISC (ARM Cortex-M4F core with FPU)
▪ Harvard Architecture with pipelining and Thumb-2 instruction set
▪ Used in real-time control systems, industrial applications
▪ STM32F4 offers high performance and low power consumption
▪Architecture: CISC (Complex Instruction Set
Computer)
▪Single accumulator-based CPU, limited registers
▪Originally developed by Intel; many derivatives exist
today
▪Popular in education, legacy systems, and simple
control tasks
▪ MSP430: 16-bit RISC architecture, ultra-low power design
▪ Modified Harvard Architecture with high efficiency
▪ PIC16F877A: 8-bit microcontroller with Harvard Architecture
▪ Both are popular for low-cost and energy-sensitive applications
▪ Architecture: Tensilica Xtensa LX6 Dual-Core, custom RISC
architecture
▪ Integrated Wi-Fi and Bluetooth with hardware acceleration
▪ Popular in IoT applications due to rich feature set
▪ Programmable via C, C++, MicroPython, and Arduino IDE
▪ Architecture: 64-bit ARM Cortex-A72, high-performance
application processor.
▪ Runs full Linux OS (Raspberry Pi OS, Ubuntu, etc.)
▪ Used in multimedia, AI applications, edge computing.
▪ Not a traditional microcontroller but used in embedded
systems.
▪ Both use ARM Cortex-M3, 32-bit RISC architecture
▪ NXP LPC1768 is suitable for industrial applications (mbed
platform)
▪ Arduino Due offers accessibility with powerful MCU
▪ Cortex-M3 provides excellent interrupt handling and low power
▪ Large number of instructions, some very specific and powerful
▪ Designed to complete tasks with fewer lines of assembly code
▪ Slower clock speeds and more complex decoding logic
▪ Examples: x86 processors, 8051 microcontroller
▪ Small set of simple instructions, each executes in one clock cycle
▪ Optimized for pipelining and high-speed operation
▪ Requires more instructions for complex tasks, but simpler
hardware
▪ Examples: ARM Cortex cores, AVR, MIPS, RISC-V
3.1 PROGRAMMING IN C
➢ Programming in C for embedded systems is a common practice due to the language's efficiency,
portability, and ability to access low-level hardware features.
➢ When working with embedded systems, C allows you to write code that directly interacts with the
hardware, making it well-suited for resource-constrained devices.
➢ Here are key considerations and examples for programming in C for embedded systems:
1. Toolchain Setup:
➢ Set up a C compiler and development environment tailored for your embedded system.
➢ This includes tools such as compilers, linkers, and debuggers. Popular choices include GCC for
cross-compiling and IDEs like Eclipse or Visual Studio with appropriate plugins.
18
PROGRAMMING IN C
2. Memory Management:
➢C provides control over memory, which is crucial in embedded systems.
➢Be mindful of stack and heap usage, and allocate memory efficiently.
➢Utilize static memory allocation where possible to avoid dynamic memory
management overhead.
➢Example:
// Static memory allocation
int buffer[100]; // Allocates an array of 100 integers statically
19
PROGRAMMING IN C
3. Data Types:
➢ Understand the data types provided by C and their representation in memory.
➢ Choose appropriate data types to conserve memory and ensure efficient data handling.
Example:
// Define a structure to represent a sensor reading
struct SensorData {
int sensorId;
float value;
};
20
PROGRAMMING IN C
4. Bit Manipulation:
➢ C allows manipulation of individual bits, a common requirement in embedded systems for
configuring registers and controlling hardware.
➢ Example:
// Set a specific bit in a register
#define REG_ADDR 0x40004000
*((volatile uint32_t*) REG_ADDR) |= (1 << 5); // Set bit 5
21
PROGRAMMING IN C
5. I/O Operations:
➢ Directly access and manipulate I/O ports and peripherals using C to control external devices like
sensors, LEDs, or communication interfaces.
➢ Example:
// Configuring GPIO pin as output
#define GPIO_PORTA_DIR_REG *((volatile uint32_t*) 0x40004000)
GPIO_PORTA_DIR_REG |= 0x01; // Set pin 0 as output
// Writing to GPIO pin
#define GPIO_PORTA_DATA_REG *((volatile uint32_t*) 0x400043FC)
GPIO_PORTA_DATA_REG |= 0x01; // Set pin 0 high
22
PROGRAMMING IN C
6. Interrupt Handling:
➢C allows you to write Interrupt Service Routines (ISRs) to handle interrupts from
peripherals or external events.
➢Example:
// ISR for Timer 0
void Timer0_ISR(void) {
// Handle timer interrupt
// Setting up Timer 0 interrupt
#define TIMER0_CTL_REG *((volatile uint32_t*) 0x4003000C)
#define NVIC_EN0_REG *((volatile uint32_t*) 0xE000E100)
TIMER0_CTL_REG |= 0x01; // Enable timer
NVIC_EN0_REG |= 1 << 19; // Enable interrupt for Timer 0 23
PROGRAMMING IN C
7. Avoiding Standard Libraries:
➢ In resource-constrained environments, it's common to avoid using standard libraries to
reduce code size.
➢Instead, implement only the necessary functionalities.
8. Real-time Considerations:
➢In real-time systems, ensure that critical operations meet timing constraints.
➢ Minimize interrupt latency and use timer peripherals effectively.
9. Debugging Techniques:
➢ Embedded systems may not have sophisticated debugging tools.
➢Use techniques like printf debugging, LEDs, or serial communication for debugging.
24
PROGRAMMING IN C
10. Documentation and Comments:
➢Thoroughly document your code, especially memory addresses, register configurations, and
critical sections.
➢Use comments to explain the purpose of code sections.
11. Testing on Target Hardware:
➢ Frequently test your code on the target hardware to ensure compatibility and identify issues
early in the development process.
➢ Programming in C for embedded systems requires a balance between low-level hardware
control and higher-level abstraction.
➢With C, you have the flexibility to optimize for performance while maintaining a reasonable
level of portability.
➢Deep understanding of the hardware, efficient memory management, and careful
consideration of real-time requirements are key to successful embedded C programming 25
3.2 DEVELOPMENT PLATFORMS FOR
EMBEDDED SOFTWARE
➢ Development platforms for embedded software provide the necessary tools, libraries, and frameworks to
facilitate the development of firmware and applications for embedded systems.
➢ These platforms typically include integrated development environments (IDEs), compilers, debuggers, and
libraries tailored for embedded development.
➢ Here are some popular development platforms used in the industry:
1. Arduino:
➢ Description: Arduino is an open-source hardware and software platform widely used for prototyping and
developing embedded systems.
26
DEVELOPMENT PLATFORMS…
➢ Features:
• Arduino IDE: Provides a simple yet powerful integrated development environment for writing, compiling, and
uploading code to Arduino boards.
• Extensive library support: Arduino libraries offer pre-written code for interfacing with sensors, actuators,
displays, communication modules, etc.
• Beginner-friendly: Arduino is known for its ease of use, making it suitable for beginners and experienced
developers alike.
27
DEVELOPMENT PLATFORMS…
2. Raspberry Pi:
➢ Description: Raspberry Pi is a series of single-board computers popular for embedded projects, IoT applications,
and educational purposes.
➢ Features:
• Raspberry Pi OS: A Linux-based operating system optimized for Raspberry Pi boards, providing a familiar
environment for software development.
• GPIO pins: Raspberry Pi boards feature GPIO pins for interfacing with external hardware components, making
them versatile for various projects.
• Diverse applications: Raspberry Pi can be used for home automation, robotics, media centres, and more.
28
DEVELOPMENT PLATFORMS…
3. Platform IO:
➢ Description: Platform IO is an open-source ecosystem for IoT development compatible with various
development platforms, including Arduino, ESP8266, ESP32, Raspberry Pi, and many others.
➢ Features:
• Cross-platform IDE: PlatformIO integrates with popular IDEs such as Visual Studio Code, Atom, and Eclipse,
providing a unified development environment.
• Library manager: PlatformIO includes a library manager for easy installation and management of libraries.
• Built-in support for debugging, unit testing, and continuous integration.
29
DEVELOPMENT PLATFORMS…
4. STM32CubeIDE:
➢ Description: STM32CubeIDE is an integrated development environment from STMicroelectronics tailored for
STM32 microcontrollers.
➢ Features:
• Eclipse-based IDE: STM32CubeIDE is based on the Eclipse IDE, offering a familiar environment for developers.
• STM32CubeMX: Integrated with STM32CubeMX, a graphical tool for configuring STM32 microcontrollers and
generating initialization code.
• Hardware debugging: Supports hardware debugging using ST-LINK or other compatible debuggers.
30
DEVELOPMENT PLATFORMS…
5. Keil µVision:
➢ Description: Keil µVision is a popular IDE for developing firmware for microcontrollers, particularly those based
on ARM Cortex-M architectures.
➢ Features:
• ARM compiler: Includes a compiler specifically optimized for ARM Cortex-M processors, providing efficient code
generation.
• Simulation and debugging: Supports simulation and debugging of embedded applications using various debug
probes.
• RTOS support: Offers integration with popular real-time operating systems (RTOS) like FreeRTOS, CMSIS-RTOS,
etc.
31
DEVELOPMENT PLATFORMS…
6. Espressif IoT Development Framework (ESP-IDF):
➢ Description: ESP-IDF is the official development framework for ESP32 and ESP8266 microcontrollers from
Espressif Systems.
➢ Features:
• FreeRTOS-based: ESP-IDF is built on top of FreeRTOS, providing support for multitasking and real-time
operations.
• Command-line tools: Includes a set of command-line tools for project configuration, building, flashing, and
debugging.
• Rich peripheral support: Offers APIs and drivers for various peripherals like GPIO, UART, SPI, I2C, Wi-Fi, and
Bluetooth.
32
DEVELOPMENT PLATFORMS…
7. NI LabVIEW:
➢ Description: LabVIEW from National Instruments is a graphical programming environment commonly used for
test, measurement, and control applications, including embedded systems.
➢ Features:
• Graphical programming: LabVIEW uses a dataflow programming model with graphical representations of code,
making it accessible to engineers and scientists.
• Real-time and FPGA modules: LabVIEW includes modules for developing real-time and FPGA-based embedded
systems.
• Hardware integration: Supports integration with NI hardware platforms, including CompactRIO and Single-Board
RIO, for hardware-in-the-loop (HIL) testing and control applications.
33
DEVELOPMENT PLATFORMS…
➢ These development platforms provide a range of features and tools to support embedded software
development across different hardware architectures and applications.
➢ The choice of platform depends on factors such as project requirements, familiarity with tools, hardware
compatibility, and ecosystem support.
34
3.3INTRODUCTION TO ARDUINO
➢ Arduino is an open-source hardware and software platform designed for hobbyists, makers, students, and
professionals to create interactive electronic projects.
➢ It consists of both physical programmable circuit boards (microcontroller boards) and a software development
environment used to write and upload code to the board.
➢ Arduino boards are widely used in various fields, including electronics, robotics, IoT (Internet of Things),
automation, and education.
35
DEVELOPMENT PLATFORMS FOR…
➢ Here's an overview of the key aspects of Arduino:
1. Hardware: Arduino boards come in various shapes and sizes, but they typically share common
components:
❑ Microcontroller: The heart of the Arduino board, responsible for executing code and controlling attached
peripherals.
❑ Common microcontroller families used in Arduino include ATmega (e.g., ATmega328 for Arduino Uno) and ARM
Cortex-M (e.g., SAMD21 for Arduino Zero).
❑ Input/Output (I/O) Pins: These pins allow the Arduino to interface with external devices such as sensors, LEDs,
motors, and displays.
❑ Arduino boards typically feature digital pins (for binary input/output) and analogue pins (for analogue input).
36
DEVELOPMENT PLATFORMS FOR…
❑ Power Supply: Arduino boards can be powered via USB, battery, or an external power supply.
❑ They often include voltage regulators to provide stable power to the components.
❑ USB Interface: Enables communication between the Arduino board and a computer for programming and serial
communication.
2. Software Development Environment: The Arduino software development environment, often
referred to as the Arduino IDE (Integrated Development Environment), provides a user-friendly
platform for writing, compiling, and uploading code to Arduino boards. Key features include:
37
DEVELOPMENT PLATFORMS FOR…
➢ Key features of Arduino software development environment include:
❑ Code Editor: A text editor for writing Arduino sketches (programs) using a
simplified version of the C++ programming language.
❑ Compiler: The Arduino IDE includes a compiler that translates sketches into
machine code compatible with the target microcontroller.
❑ Library Support: Arduino offers a vast collection of libraries providing pre-
written code for interfacing with various sensors, actuators, communication
modules, and other peripherals.
❑ Serial Monitor: A tool for debugging and serial communication between the
Arduino board and a connected computer. 38
DEVELOPMENT PLATFORMS FOR…
3. Programming with Arduino:
➢ Programming with Arduino involves writing sketches, which are small programs
written in C/C++ syntax.
➢ Each sketch typically consists of two main functions:
▪ setup(): This function is called once when the Arduino board is powered on or reset. It is used to initialize variables,
configure pins, and perform setup tasks.
▪ loop(): The loop function runs continuously after the setup function completes. It contains the main logic of the program
and is where most of the action happens.
39
DEVELOPMENT PLATFORMS FOR…
➢ Here's a simple example of an Arduino sketch that blinks an LED connected to pin 13:
void setup() {
pinMode(13, OUTPUT); // Set pin 13 as output
}
void loop() {
digitalWrite(13, HIGH); // Turn on the LED
delay(1000); // Wait for 1 second
digitalWrite(13, LOW); // Turn off the LED
delay(1000); // Wait for 1 second
} 40
DEVELOPMENT PLATFORMS FOR…
4. Community and Ecosystem: Arduino boasts a large and active community of
users, makers, educators, and developers.
➢ The Arduino community shares projects, tutorials, and resources, making it easy
to learn and get support.
➢ Additionally, Arduino-compatible boards and components are widely available
from various vendors, providing flexibility and compatibility with different
hardware configurations.
41
DEVELOPMENT PLATFORMS FOR…
5. Applications of Arduino: Arduino boards are used in a wide range of
applications, including:
➢ DIY Electronics Projects: Building robots, home automation systems, weather
stations, and interactive art installations.
➢ Educational Purposes: Teaching electronics, programming, and robotics in
schools, colleges, and maker spaces.
➢ Prototyping and Product Development: Rapid prototyping of electronic
prototypes and proof-of-concept projects for commercial products.
42
DEVELOPMENT PLATFORMS FOR…
➢ Arduino provides a versatile platform for electronics enthusiasts and
professionals to bring their ideas to life.
➢With its easy-to-use hardware and software ecosystem, Arduino enables users to
create innovative projects and explore the world of electronics, programming, and
physical computing.
➢Whether you're a beginner or an experienced developer, Arduino offers a
welcoming and supportive environment for learning, experimenting, and building
cool stuff! 43
44