1/78
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced | Call with Kai |
|---|
No analytics yet
Send a link to your students to track their progress
What is the stack?
a region of memory that stores local variables and functions calls.
memory is allocated on the stack during runtime when a program enters a fn.
memory is automatically freed when exiting a function
Why use the stack?
it is deterministic (moving stack ptr, no fragmentation), fast (predictable timing, safe for RT systems)
Stack downsides?
Much smaller than the heap.
Too much usage causes stack overflow.
What is the heap?
a region of memory used for dynamic memory allocation.
memory is allocated during runtime and freed manually.
Why is using the heap bad in embedded applications?
Non-deterministic, fragmentation risk, memory leak risk
C specific dynamic memory allocation
malloc()
free()
has no constructor
returns void *
C++ specific dynamic memory allocation
new
delete
calls constructor
What is a memory leak?
Allocated memory that is never freed.
Why are memory leaks bad in embedded?
Embedded systems have small RAM. Can exhaust the heap and cause embedded systems to crash.
What are dangling pointers?
Pointer that points to freed memory. Can cause unpredictable crashes
What is memory alignment?
Some CPUs require data to be aligned, ex: a 4 byte int must be at an address divisible by 4
Aligning memory increases performance and avoids faults.
Why is dynamic allocation dangerous in embedded?
Problems with fragmentation, non-deterministic timing (malloc can take unpredictable time), and heap exhaustion (no memory → system failure)
What is a pointer?
A variable that stores the memory address of another variable.
What is a reference?
an alias for an existing variable, providing direct access to the same object.
References allow functions to operate on existing variables without copying
In C++, & is used both as the address-of operator in expressions and as the reference declarator in type declarations.
Differences between pointer and references?
A pointer is an object that stores the memory address of another object and can be reassigned or null.
A reference is an alias to an existing object that must be initialized at creation and cannot be null.
const int* p vs. int* const p
Pointer to const data
Data cannot change
Const pointer
Pointer cannot change
How does pointer arithmetic work?
Arrays are contiguous in memory, but “contiguous” in element-to-element, not byte-to-byte.
Pointer arithmetic advances by element size so each pointer lands exactly on the next object.
Null Pointer Checks, how to do them? What happens if you dereference null?
if (p == NULL) return;
Catastrophic, hard fault
C vs. C++ in embedded
Embedded C++ provides abstractions like RAII, references, and strong typing
RAII example
class MutexLock {
public:
MutexLock(Mutex& m) : mutex(m) { mutex.lock(); }
~MutexLock() { mutex.unlock(); }
private:
Mutex& mutex;
};
Prevents problems with early returns in functions and makes code less verbose.
What are the 4 pillars of OOP?
Abstraction, Polymorphism, Inheritance, Encapsulation
What is abstraction?
a technique that manages complexity, exposing what an object does rather than how it does it
Example of abstraction?
A HAL: it can be as simple as a function that hides low-level register access, so users interact with hardware through APIs instead of raw registers.
Why is abstraction important?
Portability across MCU’s
Increases Readability of code
Increases safety (removes possibility of illegal register access)
What is polymorphism?
a technique that allows different objects to be treated through a common interface, whose implementation is determined at runtime (attained primarily with virtual functions)
Example of polymorphism?
think of a Sensor base class with read(), overridden by IMU and Lidar subclasses to read their values, the call to read() is known at runtime.
IMU and Lidar have different read implementations (virtual function in base class that is overridden by derived classes)
Why is C++ more type safe than C?
C makes more assumptions that can break things / cause unintended behavior.
Example: More explicit casting is required in C++ as opposed to C.
What is inheritance?
a technique that allows a class to extend the behavior of another class. (is-a)
Inheritance example?
IMU and Lidar classes are derived classes from base class Sensor.
Sensor has a common function, lets say void calibrate();
Each derived class inherits this calibrate function and shares this code from the base class.
Inheritance vs Composition
Inheritance models an ‘is-a’ relationship but creates tight coupling. Composition models a ‘has-a’ relationship, which is more flexible
What is encapsulation?
A technique of hiding implementation details
Abstraction vs Encapsulation?
Abstraction focuses on what the system does.
Encapsulation focuses on what is hidden and protected.
class GPIO {
public:
void set(); // abstraction
private:
uint32_t ODR; // encapsulation
};
set(); is the abstraction that sets a pin to high or low.
ODR is encapsulated by being set to private in the GPIO class.
A PIE lock in
Abstraction → what an object does
Polymorphism → runtime behavior
Inheritance → reuse/extend
Encapsulation → hide how an object is implemented
MPU vs MCU
MPU is a processor implemented on a single IC, with no direct interface with external peripherals.
MCU contains a MPU, Memory, timer, ADC/DAC, DMA controller, and GPIO on one IC.
Rules of Interrupts
Keep short
No blocking
No malloc
No printf
ISR vs RTOS Task (thread)
ISRs are immediate, have no blocking, and use minimal logic.
Tasks are scheduled, can block, and contain heavy logic.
SPI
Serial Peripheral Interface
Synchronous (uses shared clock signal)
SPI uses 4 wires (MOSI, MISO, SCK, SS)
Full duplex
Uses more pins, used for flash memory, SD cards
I2C
Inter-Intergrated Circuit
Synchronous
I2C uses 2 wires (SDA and SCL)
Half-Duplex
Generally slower, used for sensors, connecting many devices
UART
Asynchronous
Slow
Full Duplex
Used typically for debugging
CAN (Controller Area Network)
Asynchronous
Half Duplex
each CAN message has its own priority
DMA
Direct Memory Access: allows peripherals to transfer large blocks of data directly to/from main memory without involving the CPU
Reduces latency & CPU load
Process vs. Thread
A process is an instance of a program. Processes do not share a memory space by default.
A thread is a unit of execution within a process. Threads within a process share the same address space.
HAVE DIRECT ACCESS TO MEMORY in embedded applications
What is a context switch?
when the OS stops one running thread and resumes another, saving the thread’s context and restoring a new one
during context switch TCB holds the stack pointer. CPU registers are stored onto the stack
What are CPU registers?
storage locations inside the processor, holds the live working state of the program.
What is PC?
Program Counter, a CPU register that stores where the program was executing
What is the SP?
Stack pointer, a CPU register that points to the top of the stack.
Where are the CPU registers saved?
In RTOS, they are saved in that task’s dedicated stack (in RAM). Too much memory usage from a thread can result in a stack overflow.
Why is context switching expensive?
CPU Overhead (saving/restoring registers)
Cache misses (CPU caches contain old thread data, cache lines must be reloaded from RAM)
Why does the overhead of context switching matter in embedded?
Too many context switches causes missed deadlines, jitter, and increased power consumption
Stack vs TCB
Stack: “Everything the task needs to resume execution”
TCB: “Everything the scheduler needs to manage the task”
Running task state
Task is currently executing on CPU
Ready task state
Task is able to run, but is not currently executing
Blocked task state
Task cannot run until an event occurs
(waiting for delay, mutex, interrupt)
Suspended task state
Task is explicitly stopped, won’t run again unless resumed manually
Deleted task state
Task is destroyed and memory is freed
Yielded vs Preempted
A yielded task voluntarily gives up the CPU, yielded task goes into Ready state.
Preempted task is forcibly interrupted when a higher priority task is Ready (or ISR is triggered), the preempted task goes into the Ready state and higher priority task runs.
When does a full context save occur?
When the CPU switches from one task to another.
Interrupt vs Task context switch
Interrupts cannot block and switch tasks directly, does not fully save context. Preempts the currently running task
RTOS vs Baremetal
Bare-metal is for simple, resource-constrained tasks
RTOS is used for complex systems needing multitasking and scheduling, offering structure but with overhead
What is priority based scheduling?
Every task has a priority, the highest priority task always runs
What is preemption?
A running task is forcibly stopped, it occurs when a higher priority task become ready.
What is the tick interrupt?
A hardware timer interrupt, unblocks tasks whose delay expired
Time slicing
tasks of equal priority get short fixed durations to run (in round robin fashion) to give the illusion of concurrency
What is a mutex?
mutual exclusion used to prevent multiple threads from simultaneously accessing a shared resource
What is priority inversion?
a high-priority task gets delayed by a lower-priority task holding a needed shared resource. soln is priority inheritance
Ex:
Low-priority task holds mutex
High-priority task blocks on mutex
Medium-priority task preempts low
What is a race condition?
a bug where the outcome of a program depends on the unpredictable timing of multiple threads accessing a shared resource
Race condition exmaple.
Bank transaction, when two threads access the same account. Account has $100. Thread 1 withdraws $50. Thread 2 withdraws $100 and intervenes due to timing, reads the original balance before Thread 1 updates it. Thread 1 writes $50 to the balance. Thread 2 overwrites $0 to the balance. Final balance ends in $0, but balance should be -$50.
How to fix race condition?
Use a mutex, ensuring ONLY one thread can access a shared resource during the critical section.
What is a deadlock?
When tasks are permanently stuck waiting on each other, none can continue. Occurs when all four Coffman conditions are met: mutual exclusion, hold and wait, no preemption, and circular wait.
Deadlock Example
Task A holds Mutex 1 → waiting for Mutex 2
Task B holds Mutex 2 → waiting for Mutex 1
How to prevent deadlock?
Break ANY ONE condition:
Enforce mutex order (break circular wait)
Don’t hold multiple locks (break hold & wait)
Use timeouts (break no preemption logically)
Reduce shared resources
What is an atomic operation?
An operation that completes fully without being interrupted.
When are atomic operations used?
Mutex is too slow, as it involves the scheduler and a possible context switch.
Use for small critical sections, such as a simple counter.
Atomics work because there is no blocking, it executes immediately, and interrupts are disabled briefly (ISR safe, ISR cannot run in the middle of an atomic operation).
Fixed Priority Scheduling
a CPU scheduling method where each task gets a static, unchanging priority; the scheduler always runs the highest-priority ready task, preempting lower-priority ones if a higher-priority task arrives
What version of C++ and why?
I use C++17 because it provides modern language features that improve safety and performance.
Favorite feature:
Guaranteed copy elision, it removes unnecessary object copies, improving performance without changing code
Why use static in embedded?
Preserve state of variables between function calls
Another files cannot access static global variables
Semaphore vs Mutex
Mutexes protect shared data; semaphores signal events.
importance of modern C++
high performance, low-level control, and strong type safety
Array
a data structure that stores elements of the same type sequentially and is contiguous in memory