0% found this document useful (0 votes)
4 views

Embedded Systems Practices

The document outlines essential practices in real-time embedded systems, including modular programming, state machines, and memory management, accompanied by C++ code examples for each topic. It also discusses advanced techniques such as low-power optimization, priority-based scheduling, and real-time network communication. The content emphasizes efficient system design and provides practical implementations to enhance understanding of embedded systems programming.

Uploaded by

Gamindu Udayanga
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Embedded Systems Practices

The document outlines essential practices in real-time embedded systems, including modular programming, state machines, and memory management, accompanied by C++ code examples for each topic. It also discusses advanced techniques such as low-power optimization, priority-based scheduling, and real-time network communication. The content emphasizes efficient system design and provides practical implementations to enhance understanding of embedded systems programming.

Uploaded by

Gamindu Udayanga
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

Embedded Systems Practices

provide explanation & C++ code

The image presents common practices in real-time embedded systems, including modular
programming, state machines, polling vs. interrupt-driven approaches, timing algorithms,
memory management, function callbacks, resource access control, and circular buffers. Below is
an explanation of each topic along with corresponding C++ code examples.

1. Modular Programming

Explanation:

Code is structured into independent modules for better reusability, manageability, and testability.
This is achieved using separate files and header files in C++.

C++ Code Example:

cpp

// motor.h (Header file)


#ifndef MOTOR_H
#define MOTOR_H

class Motor {
public:
void start();
void stop();
};

#endif

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 1/16
cpp

// motor.cpp (Implementation file)


#include <iostream>
#include "motor.h"

void Motor::start() {
std::cout << "Motor started" << std::endl;
}

void Motor::stop() {
std::cout << "Motor stopped" << std::endl;
}

cpp

// main.cpp (Main module)


#include "motor.h"

int main() {
Motor motor;
motor.start();
motor.stop();
return 0;
}

2. State Machine

Explanation:

Used to manage system states and transitions.


Can be implemented using switch-case or function pointers.

C++ Code Example:

cpp

#include <iostream>

enum State { OFF, ON };

State buttonPressed(State currentState) {


return (currentState == OFF) ? ON : OFF;
}

int main() {
State currentState = OFF;
std::cout << "Initial State: OFF" << std::endl;

currentState = buttonPressed(currentState);
std::cout << "New State: " << (currentState == ON ? "ON" : "OFF") << std::endl;

return 0;
}

3. Polling vs. Interrupt-Driven

Polling: Constantly checks a condition, wasting CPU cycles.


Interrupts: Executes a function only when an event occurs, saving CPU power.

C++ Code Example (Interrupt Simulation)


Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 2/16
cpp

#include <iostream>
#include <thread>
#include <chrono>

bool keyPressed = false;

void interruptHandler() {
std::cout << "Key pressed! Handling interrupt..." << std::endl;
keyPressed = false; // Reset key state
}

void pollingMethod() {
while (true) {
if (keyPressed) {
interruptHandler();
}
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // Simulate delay
}
}

int main() {
std::thread pollingThread(pollingMethod);

std::this_thread::sleep_for(std::chrono::seconds(2));
keyPressed = true; // Simulate key press

pollingThread.join();
return 0;
}

4. Timing and Scheduling Algorithms

Explanation:

Ensures tasks complete within deadlines.


Uses timers, real-time operating system (RTOS) scheduling.

C++ Code Example (Using Timers)

cpp

#include <iostream>
#include <chrono>
#include <thread>

void task() {
std::cout << "Executing scheduled task..." << std::endl;
}

int main() {
std::cout << "Task scheduled to run in 3 seconds..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
task();
return 0;
}

5. Memory Management Strategies

Explanation:

Different memory allocation strategies such as stack, heap, and pool allocation.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 3/16
C++ Code Example (Heap Allocation)

cpp

#include <iostream>

int main() {
int* ptr = new int(10); // Heap allocation
std::cout << "Heap allocated value: " << *ptr << std::endl;
delete ptr; // Free memory
return 0;
}

6. Function Callbacks

Explanation:

Uses function pointers to create dynamic and event-driven applications.

C++ Code Example:

cpp

#include <iostream>

void callbackFunction() {
std::cout << "Callback function executed!" << std::endl;
}

void registerCallback(void (*callback)()) {


std::cout << "Registering callback..." << std::endl;
callback();
}

int main() {
registerCallback(callbackFunction);
return 0;
}

7. Resource Access Control

Explanation:

Uses mutexes and semaphores to prevent race conditions in multi-threaded environments.

C++ Code Example (Mutex for Thread Safety)

cpp

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void accessResource(int threadID) {


std::lock_guard<std::mutex> lock(mtx);
std::cout << "Thread " << threadID << " accessing resource" << std::endl;
}

int main() {

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 4/16
std::thread t1(accessResource, 1);
std::thread t2(accessResource, 2);

t1.join();
t2.join();
return 0;
}

8. Circular Buffers

Explanation:

Uses a fixed-size buffer with wrap-around indexing for efficient data storage.

C++ Code Example:

cpp

#include <iostream>

#define SIZE 5

class CircularBuffer {
int buffer[SIZE];
int head = 0, tail = 0;
int count = 0;

public:
void enqueue(int value) {
if (count == SIZE) {
std::cout << "Buffer full!" << std::endl;
return;
}
buffer[tail] = value;
tail = (tail + 1) % SIZE;
count++;
}

int dequeue() {
if (count == 0) {
std::cout << "Buffer empty!" << std::endl;
return -1;
}
int value = buffer[head];
head = (head + 1) % SIZE;
count--;
return value;
}
};

int main() {
CircularBuffer cb;
cb.enqueue(1);
cb.enqueue(2);
cb.enqueue(3);
std::cout << "Dequeued: " << cb.dequeue() << std::endl;
cb.enqueue(4);
return 0;
}

Conclusion

These C++ implementations cover essential real-time embedded system practices.

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 5/16
Polling vs. Interrupts, Callbacks, and Resource Access Control are particularly important for
efficient system design.

Let me know if you need further details or enhancements in any specific area! 🚀

what else?

Apart from the common practices mentioned in the image, real-time embedded systems involve
several advanced techniques and optimizations that improve efficiency, responsiveness, and power
management. Below are additional crucial topics along with their C++ implementations.

9. Low-Power Optimization Strategies


Explanation:

Embedded systems often operate on battery power, requiring low-power modes like sleep, deep
sleep, and dynamic frequency scaling.
Techniques like clock gating, interrupt-based wake-up, and power-aware scheduling help
optimize energy consumption.

C++ Code Example (Simulating Low-Power Mode)

cpp

#include <iostream>
#include <thread>
#include <chrono>

void enterLowPowerMode() {
std::cout << "Entering low power mode..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5)); // Simulating deep sleep
std::cout << "Waking up from low power mode!" << std::endl;
}

int main() {
std::cout << "System running..." << std::endl;
enterLowPowerMode();
std::cout << "Resuming normal operation." << std::endl;
return 0;
}

🔹 In real hardware, you would use MCU sleep modes instead of `sleep_for`.

10. Priority-based Task Scheduling


Explanation:

Real-Time Operating Systems (RTOS) use priority scheduling to determine which task should
execute.
Preemptive scheduling ensures that higher-priority tasks execute first.

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 6/16
C++ Code Example (Priority-based Scheduling)

cpp

#include <iostream>
#include <queue>
#include <functional>

struct Task {
int priority;
std::string name;

bool operator<(const Task& other) const {


return priority < other.priority; // Higher priority first
}
};

int main() {
std::priority_queue<Task> taskQueue;

taskQueue.push({3, "Low Priority Task"});


taskQueue.push({1, "High Priority Task"});
taskQueue.push({2, "Medium Priority Task"});

while (!taskQueue.empty()) {
std::cout << "Executing: " << taskQueue.top().name << std::endl;
taskQueue.pop();
}

return 0;
}

🔹 In RTOS (like FreeRTOS), you would use `xTaskCreate` with priorities.

11. Interrupt Handling with Debouncing


Explanation:

Switches & buttons often generate multiple signals due to mechanical bounce.
A debounce algorithm filters out rapid unintended state changes.

C++ Code Example (Button Debouncing)

cpp

#include <iostream>
#include <chrono>
#include <thread>

bool isButtonPressed() {
// Simulate button press with bouncing
static int count = 0;
count++;
return (count % 3 == 0); // Every 3rd read is an actual press
}

void debounceButton() {
bool lastState = false;
while (true) {
bool currentState = isButtonPressed();
if (currentState && !lastState) {
std::cout << "Button Pressed!" << std::endl;
}
lastState = currentState;
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Debounce delay
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 7/16
}
}

int main() {
debounceButton();
return 0;
}

🔹 Hardware MCUs use external pull-up resistors + software debouncing.


12. Finite State Machine with Event Handling
Explanation:

More complex than a simple state machine.


Handles multiple events & transitions dynamically.

C++ Code Example (Traffic Light FSM)

cpp

#include <iostream>

enum State { RED, GREEN, YELLOW };

void nextState(State &current) {


switch (current) {
case RED:
std::cout << "Changing from RED to GREEN" << std::endl;
current = GREEN;
break;
case GREEN:
std::cout << "Changing from GREEN to YELLOW" << std::endl;
current = YELLOW;
break;
case YELLOW:
std::cout << "Changing from YELLOW to RED" << std::endl;
current = RED;
break;
}
}

int main() {
State currentState = RED;
for (int i = 0; i < 5; i++) {
nextState(currentState);
}
return 0;
}

🔹 FSMs are heavily used in robotics, automation, and communication protocols.


13. Embedded Cryptography for Secure Communication
Explanation:

Secure embedded systems use encryption for data security.


Algorithms like AES, RSA, SHA256 are used in IoT, firmware updates, and network
communication.

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 8/16
C++ Code Example (Simple XOR Encryption)

cpp

#include <iostream>
#include <string>

std::string encryptDecrypt(std::string text, char key) {


for (char &c : text) {
c ^= key; // XOR encryption
}
return text;
}

int main() {
std::string msg = "HelloWorld";
char key = 'X';

std::string encrypted = encryptDecrypt(msg, key);


std::cout << "Encrypted: " << encrypted << std::endl;

std::string decrypted = encryptDecrypt(encrypted, key);


std::cout << "Decrypted: " << decrypted << std::endl;

return 0;
}

🔹 For real-world security, use AES encryption (OpenSSL library).


14. Real-Time Data Logging for Monitoring
Explanation:

Embedded systems need real-time data logging to monitor sensor data, logs, and debugging
info.

C++ Code Example (Log to File)

cpp

#include <iostream>
#include <fstream>
#include <ctime>

void logData(const std::string& message) {


std::ofstream logFile("log.txt", std::ios::app);
std::time_t now = std::time(nullptr);
logFile << std::ctime(&now) << ": " << message << std::endl;
}

int main() {
logData("System Started");
logData("Sensor value: 42");
logData("System Shutting Down");
return 0;
}

🔹 Embedded devices often store logs in EEPROM or SD cards.


15. Real-Time Network Communication (MQTT, CAN Bus)
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 9/16
Explanation:

Embedded systems communicate via protocols like MQTT (IoT), CAN Bus (automotive), SPI, I2C.
Message Queuing Telemetry Transport (MQTT) is commonly used for IoT devices.

C++ Code Example (Simulated Network Message)

cpp

#include <iostream>
#include <queue>

std::queue<std::string> messageQueue;

void sendMessage(const std::string& msg) {


messageQueue.push(msg);
}

void receiveMessage() {
if (!messageQueue.empty()) {
std::cout << "Received: " << messageQueue.front() << std::endl;
messageQueue.pop();
}
}

int main() {
sendMessage("Hello from Sensor 1");
sendMessage("Temperature: 23°C");

receiveMessage();
receiveMessage();

return 0;
}

🔹 For real applications, use the `mosquitto` MQTT C++ library.

Final Thoughts
Beyond the common practices in embedded systems, these advanced techniques help design
scalable, efficient, and secure real-time applications.
✅ Next Steps:
Implement RTOS-based scheduling (FreeRTOS)
Add interrupt-driven GPIO handling
Use hardware timers for precision timing
Implement real-time CAN Bus protocol

🚀 Which topic do you want me to expand on next?

All

Got it! I'll provide detailed explanations and C++ implementations for the following real-time
embedded system topics:

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 10/16
🚀 Topics Covered:
1. RTOS-based scheduling (FreeRTOS)
2. Interrupt-driven GPIO handling
3. Hardware timers for precision timing
4. Real-time CAN Bus protocol

1. RTOS-based Scheduling (FreeRTOS)


Explanation:

Real-Time Operating System (RTOS) schedules tasks dynamically.


FreeRTOS is widely used for task management, message queues, and semaphores.
Uses preemptive scheduling with different priority levels.

C++ Code Example (FreeRTOS Task Scheduling)

cpp

#include "FreeRTOS.h"
#include "task.h"
#include <Arduino.h> // Required for ESP32 or STM32 boards

void Task1(void* pvParameters) {


while (1) {
Serial.println("Task 1 Running");
vTaskDelay(pdMS_TO_TICKS(1000)); // Delay for 1 second
}
}

void Task2(void* pvParameters) {


while (1) {
Serial.println("Task 2 Running");
vTaskDelay(pdMS_TO_TICKS(500)); // Delay for 0.5 seconds
}
}

void setup() {
Serial.begin(115200);
xTaskCreate(Task1, "Task 1", 1000, NULL, 1, NULL);
xTaskCreate(Task2, "Task 2", 1000, NULL, 2, NULL);
}

void loop() {
// Empty, since RTOS handles scheduling
}

🔹 FreeRTOS is ideal for ESP32, STM32, ARM Cortex MCUs.


2. Interrupt-Driven GPIO Handling
Explanation:

Polling wastes CPU time, while interrupts react to events instantly.


Attach an external interrupt to a GPIO pin to detect button presses, sensor changes, etc..

C++ Code Example (External Interrupt Handling)

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 11/16
cpp

#include <Arduino.h>

#define BUTTON_PIN 2

volatile bool buttonPressed = false;

void IRAM_ATTR handleInterrupt() {


buttonPressed = true;
}

void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleInterrupt, FALLING);
}

void loop() {
if (buttonPressed) {
Serial.println("Button Pressed!");
buttonPressed = false; // Reset flag
}
}

🔹 Uses `attachInterrupt()` to trigger `handleInterrupt()` on button press.

3. Hardware Timers for Precision Timing


Explanation:

Uses hardware-based timers for accurate task execution.


Useful for PWM generation, periodic tasks, real-time measurements.

C++ Code Example (ESP32 Timer)

cpp

#include <Arduino.h>

hw_timer_t * timer = NULL;


volatile bool timerFlag = false;

void IRAM_ATTR onTimer() {


timerFlag = true;
}

void setup() {
Serial.begin(115200);
timer = timerBegin(0, 80, true); // Timer 0, prescaler 80 (1us resolution)
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 1000000, true); // 1 second period
timerAlarmEnable(timer);
}

void loop() {
if (timerFlag) {
Serial.println("Timer Triggered!");
timerFlag = false;
}
}

🔹 ESP32 and STM32 use dedicated hardware timers for high precision.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 12/16
4. Real-time CAN Bus Communication
Explanation:

Controller Area Network (CAN Bus) is used in automotive, industrial, and robotics
applications.
Uses message-based communication between multiple devices.

C++ Code Example (ESP32 CAN Bus Communication)

cpp

#include <ESP32CAN.h>
#include <CAN_config.h>

CAN_device_t CAN_cfg;

void setup() {
Serial.begin(115200);
CAN_cfg.speed = CAN_SPEED_500KBPS;
CAN_cfg.tx_pin_id = GPIO_NUM_5;
CAN_cfg.rx_pin_id = GPIO_NUM_4;
CAN_init();
}

void loop() {
CAN_frame_t frame;
frame.MsgID = 0x100;
frame.FIR.B.DLC = 8;
for (int i = 0; i < 8; i++) {
frame.data.u8[i] = i;
}

ESP32Can.CANWriteFrame(&frame);
delay(1000);
}

🔹 CAN Bus is essential for vehicle electronics, industrial automation, and robotic systems.
Final Thoughts
✅ We covered advanced real-time embedded system topics:
RTOS-based multitasking (FreeRTOS)
Interrupt-driven GPIO handling
High-precision hardware timers
Real-time CAN Bus communication

💡 Next Steps:
Implement SPI/I2C communication
Integrate real-time data logging
Optimize power consumption using deep sleep modes

🚀 Which embedded system topic should I cover next?

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 13/16
Implement SPI/I2C communication

SPI and I2C Communication in Embedded Systems

✅ Explanation
SPI (Serial Peripheral Interface) and I2C (Inter-Integrated Circuit) are common serial
communication protocols in embedded systems.
SPI is faster but requires more wires, while I2C supports multiple devices with just two wires.

1. SPI Communication
✅ How SPI Works
Full-duplex communication using four lines:
MOSI (Master Out, Slave In)
MISO (Master In, Slave Out)
SCK (Clock)
CS/SS (Chip Select)
Master controls the communication, and slaves respond.

📌 SPI Code Example (Master & Slave Communication)


Master Device (ESP32/Arduino)

cpp

#include <SPI.h>

#define SS_PIN 10

void setup() {
Serial.begin(115200);
SPI.begin();
pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH);
}

void loop() {
digitalWrite(SS_PIN, LOW);
byte response = SPI.transfer(0x42); // Send data to slave
digitalWrite(SS_PIN, HIGH);

Serial.print("Received from Slave: ");


Serial.println(response, HEX);
delay(1000);
}

Slave Device

cpp

#include <SPI.h>

volatile byte receivedData;

void setup() {

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 14/16
Serial.begin(115200);
SPI.begin();
pinMode(MISO, OUTPUT);
SPCR |= _BV(SPE); // Enable SPI in slave mode
SPI.attachInterrupt();
}

ISR(SPI_STC_vect) {
receivedData = SPDR; // Read received data
SPDR = receivedData + 1; // Send modified data back
}

void loop() {
Serial.print("Received: ");
Serial.println(receivedData, HEX);
delay(1000);
}

🔹 Uses `SPI.transfer()` for data exchange between master and slave.

2. I2C Communication
✅ How I2C Works
Two-wire communication (SDA, SCL)
Supports multiple masters/slaves using device addresses.
Master initiates communication, and slave responds.

📌 I2C Code Example (Master & Slave Communication)


Master Device (ESP32/Arduino)

cpp

#include <Wire.h>

#define SLAVE_ADDRESS 0x08

void setup() {
Wire.begin();
Serial.begin(115200);
}

void loop() {
Wire.beginTransmission(SLAVE_ADDRESS);
Wire.write("Hello from Master");
Wire.endTransmission();

delay(500);
}

Slave Device

cpp

#include <Wire.h>

#define SLAVE_ADDRESS 0x08

void receiveData(int byteCount) {


while (Wire.available()) {
char c = Wire.read();
Serial.print(c);

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 15/16
}
Serial.println();
}

void setup() {
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveData);
Serial.begin(115200);
}

void loop() {
delay(1000);
}

🔹 I2C is ideal for connecting multiple sensors or low-speed devices.


Final Thoughts
✅ We implemented SPI & I2C communication for real-time embedded systems.
🚀 Next Steps:
Integrate SPI with sensors (e.g., MPU6050, OLED)
Use I2C for multiple device communication
Implement error handling & acknowledgments in I2C/SPI

👉 Which embedded communication topic should I expand on next?

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 16/16

You might also like