0% found this document useful (0 votes)
2 views22 pages

Embedded Questions

Embedded questions

Uploaded by

ktest0157
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views22 pages

Embedded Questions

Embedded questions

Uploaded by

ktest0157
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

EMBEDDED SYSTEMS

INTERVIEW ANSWER BIBLE


100 Questions · Complete Answers · TI / Qualcomm / ARM Ready
Based on the roadmap of a student who cracked Texas Instruments

Section Topics Questions

1. C Programming Pointers, Memory, DS, Recursion Q1–Q20

2. Embedded C volatile, static, ISR, Bit ops, Padding Q21–Q40

3. Operating Systems Scheduling, Threads, Sync, Memory Q41–Q60

4. Computer Architecture Pipeline, Cache, DMA, Interrupts Q61–Q80

5. Microcontrollers GPIO, SPI, I2C, UART, ADC, PWM Q81–Q100

Embedded Interview Answer Bible — 100 Questions Page 1


SECTION 1: C PROGRAMMING
Q1. Difference between array and pointer?
An array is a contiguous block of memory with a fixed size known at compile time. A pointer is a variable that
stores a memory address.
• Array name decays to pointer to first element but is NOT a pointer — it's a fixed address
• sizeof(array) gives total size; sizeof(pointer) gives 4 or 8 bytes
• Arrays cannot be reassigned; pointers can point anywhere
• int arr[5] → arr is fixed; int *p = arr → p can be changed
int arr[5] = {1,2,3,4,5};
int *p = arr;
p++; // valid — p now points to arr[1]
// arr++; → ERROR — cannot modify array name
■ TI loves: 'arr is not a pointer — it cannot be incremented'

Q2. Explain pointer arithmetic.


Pointer arithmetic moves the pointer by multiples of the pointed-to type's size, not by bytes.
int *p; // p+1 moves by sizeof(int) = 4 bytes
char *c; // c+1 moves by sizeof(char) = 1 byte
double *d; // d+1 moves by sizeof(double) = 8 bytes

int arr[] = {10,20,30};


int *p = arr;
printf("%d", *(p+2)); // prints 30
■ Rule: p+n moves the address by n × sizeof(*p) bytes

Q3. What is a dangling pointer?


A pointer that points to memory that has already been freed or gone out of scope. Accessing it is undefined
behavior.
int *p = malloc(sizeof(int));
*p = 10;
free(p);
// p is now a dangling pointer
*p = 20; // UNDEFINED BEHAVIOR
p = NULL; // fix: always NULL after free
■ Fix: always set pointer to NULL after free()

Q4. What is a wild pointer?


A pointer declared but never initialized. It points to a random/garbage memory address.
int *p; // wild pointer — uninitialized
*p = 10; // CRASH / undefined behavior

int *p = NULL; // safe — always initialize


■ Wild = uninitialized. Dangling = freed/out-of-scope. Both are dangerous.

Q5. Difference between malloc and calloc?


malloc calloc

Arguments malloc(size) calloc(n, size)

Initialization Not initialized (garbage) Zero-initialized

Embedded Interview Answer Bible — 100 Questions Page 2


Use case Raw buffer Arrays needing zero-init

Performance Slightly faster Slightly slower (zeroing cost)

Q6. What happens during free()?


free() returns the allocated memory block back to the heap allocator. It does NOT zero the memory or change the
pointer value. The pointer becomes dangling after free().
• Memory is returned to heap — OS may not reclaim immediately
• Pointer still holds old address (now invalid)
• Double free() is undefined behavior and can cause heap corruption
• Always set pointer to NULL after free()

Q7. Difference between stack and heap?


Stack Heap

Allocation Automatic (compiler) Manual (malloc/free)

Size Limited (~1-8 MB) Limited by RAM

Speed Very fast (just SP move) Slower (allocator overhead)

Lifetime Function scope Until free() called

Fragmentation None Possible

Thread Per-thread Shared across threads

Q8. Explain function pointers.


A function pointer stores the address of a function. It allows calling functions dynamically at runtime — used
heavily in embedded for callbacks, ISR tables, and dispatch tables.
// Syntax: return_type (*ptr_name)(param_types)
void (*fp)(int) = &my;_function;
fp(42); // calls my_function(42)

// ISR table example (embedded use):


void (*isr_table[8])(void) = {isr0, isr1, isr2, ...};
isr_table[irq_num](); // dynamic dispatch
■ Key use in embedded: interrupt vector tables, state machines, callback drivers

Q9. What are static variables?


static has two meanings depending on context:
• Inside function: variable persists across function calls (stored in .data/.bss, not stack)
• At file scope: variable/function is private to that translation unit (not visible outside)
void counter() {
static int count = 0; // initialized only once
count++; // persists between calls
printf("%d", count); // 1, 2, 3...
}
■ static local = persistent lifetime. static global = file scope only.

Q10. Explain recursion internally.


Each recursive call creates a new stack frame containing: return address, local variables, and parameters. Stack
grows with each call and unwinds on return.
int fact(int n) {
if (n == 0) return 1; // base case

Embedded Interview Answer Bible — 100 Questions Page 3


return n * fact(n-1); // recursive call → new stack frame
}

• Stack overflow occurs if recursion is too deep (no base case or large n)
• Each frame takes memory — embedded systems prefer iteration over recursion
• Tail recursion can be optimized by compiler to avoid extra frames

Q11. Why are arrays passed as pointers?


Arrays decay to a pointer to their first element when passed to functions. C does not pass arrays by value because
copying could be huge. The function receives a pointer, not a copy.
void foo(int *arr, int n) { ... }
// OR equivalently:
void foo(int arr[], int n) { ... } // same thing

int a[10];
foo(a, 10); // passes &a;[0]
■ sizeof(arr) inside function gives pointer size (4 or 8), NOT array size. Always pass size separately.

Q12. What is segmentation fault?


A segfault occurs when a program accesses memory it's not allowed to — either unmapped memory, read-only
memory, or NULL dereference. The OS sends SIGSEGV.
• Dereferencing NULL pointer
• Accessing freed memory (dangling pointer)
• Stack overflow (array out of bounds)
• Writing to read-only memory (.text segment)

Q13. Explain memory leak.


Memory leak occurs when dynamically allocated memory is never freed, causing the heap to grow until the system
runs out of memory. Critical in embedded systems with limited RAM.
void leak() {
int *p = malloc(100);
// forgot to call free(p)
return; // memory is leaked
}
■ In embedded: even small leaks are fatal. Use static allocation or memory pools where possible.

Q14. What is undefined behavior?


Undefined behavior (UB) is code whose behavior the C standard does not define. The compiler is free to do
anything — crash, produce wrong output, or silently work.
• Signed integer overflow
• Accessing out-of-bounds array index
• Dereferencing NULL/dangling pointer
• Using uninitialized variable
• Modifying string literal
■ UB is especially dangerous in embedded — wrong behavior in safety-critical firmware can be catastrophic.

Q15. Explain const correctness.


const tells the compiler a value should not be modified. Helps catch bugs and enables optimizations.
const int x = 5; // x cannot be modified
const int *p = &x; // pointer to const int — *p cannot change
int * const p2 = &y; // const pointer — p2 cannot change

Embedded Interview Answer Bible — 100 Questions Page 4


const int * const p3 = &x; // both const
■ In embedded: const variables can be placed in ROM/Flash instead of RAM — saves precious RAM.

Q16. Difference between char *p and char p[]?


char *p = "hello"; // pointer to string literal (READ-ONLY memory)
char p[] = "hello"; // array on stack — modifiable copy

*p = 'H'; // UNDEFINED BEHAVIOR — string literal is read-only


p[0] = 'H'; // OK — modifying stack copy
■ char *p points to .rodata (read-only). char p[] creates a writable copy on the stack.

Q17. What happens in buffer overflow?


Writing beyond the allocated buffer overwrites adjacent memory — can corrupt return addresses, other variables,
or cause security vulnerabilities.
char buf[8];
strcpy(buf, "this_is_too_long"); // OVERFLOW — writes past buf
// Adjacent stack memory corrupted → crash or hijack
■ Critical in embedded firmware — buffer overflows can corrupt registers, stack frames, and cause silent failures.

Q18. Difference between pass-by-value and pass-by-reference?


C only has pass-by-value. Pass-by-reference is simulated using pointers.
void byVal(int x) { x = 10; } // modifies local copy only
void byRef(int *x) { *x = 10; } // modifies original via pointer

int a = 5;
byVal(a); // a still 5
byRef(&a;); // a now 10

Q19. Explain typedef.


typedef creates an alias for an existing type. Improves readability and portability.
typedef unsigned int uint32_t; // portable type
typedef struct { int x; int y; } Point; // struct alias
typedef void (*ISR)(void); // function pointer alias

uint32_t reg = 0xDEADBEEF;


ISR isr_handler = my_isr;
■ Embedded: typedef is used heavily for register-width types (uint8_t, uint32_t) for portability.

Q20. What is volatile?


volatile tells the compiler NOT to optimize accesses to a variable — read it from memory every time, don't cache in
register. Used when variable can change outside normal program flow.
• Hardware registers — value changes due to hardware
• ISR-shared variables — modified in interrupt context
• Multi-threaded shared variables
volatile uint32_t *reg = (uint32_t *)0x40020000;
*reg = 0x01; // always written to hardware
uint32_t val = *reg; // always read from hardware, not cached

volatile int flag = 0; // set in ISR, read in main loop


■ Without volatile, compiler may optimize away repeated reads/writes — catastrophic for hardware registers.

Embedded Interview Answer Bible — 100 Questions Page 5


SECTION 2: EMBEDDED C
Q21. Why use volatile for hardware registers?
Hardware registers change value independently of program flow — due to hardware events, peripheral state
changes, or DMA. Without volatile, the compiler may cache the register value in a CPU register and never re-read
from memory, causing stale values.
volatile uint32_t *STATUS = (uint32_t *)0x40000000;
while (*STATUS == 0) {} // Without volatile: infinite loop!
// Compiler caches STATUS=0 in register
// With volatile: re-reads every iteration

Q22. Explain memory-mapped I/O.


In memory-mapped I/O, peripheral registers are mapped to specific addresses in the CPU's memory address
space. You read/write peripherals using regular memory load/store instructions via pointers.
// GPIO Port A output data register at 0x40020014
#define GPIOA_ODR (*((volatile uint32_t *)0x40020014))
GPIOA_ODR |= (1 << 5); // Set pin 5 HIGH
GPIOA_ODR &= ~(1 << 5); // Set pin 5 LOW
■ Must always use volatile pointer for memory-mapped registers to prevent compiler optimization.

Q23. What is an ISR?


Interrupt Service Routine — a function called by hardware when an interrupt event occurs. The CPU saves its
current state, executes the ISR, then resumes normal execution.
• Must be fast — no blocking, no malloc, minimal processing
• Must have specific attributes (e.g., __attribute__((interrupt)) on ARM)
• Shared variables with main must be volatile
• Keep ISR short — set a flag, do work in main loop
volatile int flag = 0;
void __attribute__((interrupt)) UART_IRQHandler(void) {
flag = 1; // set flag, do real work in main
UART->SR &= ~RXNE; // clear interrupt flag
}

Q24. Why should ISRs be short?


• Long ISRs block other interrupts (if not nested) — increases interrupt latency
• No OS scheduler runs inside ISR — can't call blocking functions
• Stack space is limited — deep function calls inside ISR can overflow
• Timing-critical systems (RTOS) require deterministic ISR exit time
■ Pattern: Set a flag in ISR → process in main loop. Called 'deferred processing' or 'bottom half'.

Q25. Explain reentrancy.


A function is reentrant if it can be safely interrupted mid-execution and called again (from ISR or another thread)
without corrupting results. Reentrant functions use only local variables and parameters — no static or global state.
// Non-reentrant — static variable is shared
int bad_counter() { static int n = 0; return ++n; }

// Reentrant — only local variables


int add(int a, int b) { return a + b; }

Q26. What is a race condition?

Embedded Interview Answer Bible — 100 Questions Page 6


A race condition occurs when two or more execution contexts (threads, ISR + main) access shared data
concurrently and the result depends on timing/order of access.
// Main loop:
flag = 1;
// ISR fires HERE — sees flag = 1 unexpectedly
flag = 2;
// Result depends on when ISR fires — race condition
■ Fix: use atomic operations, disable interrupts around critical section, or use mutex/semaphore.

Q27. What is an atomic operation?


An atomic operation completes entirely without interruption — cannot be context-switched or interrupted midway.
On most architectures, single machine instruction operations (read/write of aligned word) are atomic.
// Single byte write — atomic on most architectures
volatile uint8_t flag = 1;

// Multi-step — NOT atomic


uint32_t val = reg;
val |= (1 << 5);
reg = val; // 3 steps — ISR can interrupt between them

// Fix: disable interrupts


__disable_irq();
reg |= (1 << 5); // read-modify-write atomically
__enable_irq();

Q28. Explain struct padding.


The compiler adds padding bytes between struct members to ensure each member is aligned to its natural
alignment boundary. This improves memory access performance on most architectures.
struct Example {
char a; // 1 byte + 3 padding bytes
int b; // 4 bytes (must be 4-byte aligned)
char c; // 1 byte + 3 padding bytes
};
// sizeof = 12, not 6!

// Optimized order:
struct Better {
int b; // 4 bytes
char a; // 1 byte
char c; // 1 byte + 2 padding
};
// sizeof = 8

Q29. Why does alignment matter?


• Misaligned access is slow (extra bus cycles) or causes hardware fault on strict architectures
• ARM Cortex-M may generate HardFault on unaligned 32-bit access
• Compilers align struct members by default for performance
• Network/protocol structs must match exact wire format — use packed

Q30. What is a packed structure?


A packed struct removes padding — members are packed tightly. Used for protocol headers, network packets, or
memory-mapped register maps where exact byte layout matters.

Embedded Interview Answer Bible — 100 Questions Page 7


struct __attribute__((packed)) Packet {
uint8_t header; // 1 byte
uint32_t data; // 4 bytes (normally padded, now packed)
uint8_t checksum; // 1 byte
};
// sizeof = 6, not 12
■ Warning: packed structs may cause misaligned accesses — can be slow or fault on strict architectures.

Q31. Difference between static and extern?


Keyword Scope Lifetime Use case

static (local) Function only Program lifetime Persistent local variable

static (global) File only Program lifetime Private global — not visible outside file

extern Across files Program lifetime Declare variable defined in another file

Q32. Explain the linker's role.


The linker combines object files (.o) into a final executable. It resolves symbol references between files, assigns
final memory addresses, and produces the memory layout defined by the linker script.
• Symbol resolution: matches function calls to definitions across files
• Relocation: assigns absolute addresses to symbols
• Section merging: combines .text, .data, .bss sections
• In embedded: linker script defines Flash/RAM regions precisely

Q33. What happens during preprocessing?


The preprocessor (cpp) runs before compilation and handles directives starting with #:
• #include — inserts content of header file
• #define — text substitution (macros)
• #ifdef/#ifndef — conditional compilation
• #pragma — compiler-specific hints
■ Output of preprocessing is a .i file — pure C with all macros expanded and includes pasted in.

Q34. Difference between macro and inline function?


Macro (#define) Inline function

Type checking None — text substitution Full type checking by compiler

Debugging Hard — no stack frame Debuggable

Side effects Dangerous (double eval) Safe

Scope Global after definition Can be file-scoped

Return value Expression only Full function semantics

Q35. What is conditional compilation?


#ifdef DEBUG
printf("value = %d\n", val); // only compiled in debug builds
#endif

#if defined(STM32F4)
#include "stm32f4xx.h"
#elif defined(MAX32690)
#include "max32690.h"
#endif
■ Used heavily in embedded to support multiple hardware targets from one codebase.

Embedded Interview Answer Bible — 100 Questions Page 8


Q36. Why are macros dangerous?
#define SQUARE(x) x*x
SQUARE(3+1) → 3+1*3+1 = 7 (not 16!)

// Fix: always parenthesize


#define SQUARE(x) ((x)*(x))

// Side effect danger:


#define MAX(a,b) ((a)>(b)?(a):(b))
MAX(i++, j++) // i++ or j++ evaluated TWICE!
■ Prefer inline functions over macros. If using macros, always parenthesize all arguments and the whole expression.

Q37. Explain bit masking.


Bit masking uses bitwise operators to manipulate individual bits in a register or variable without affecting other bits.
uint32_t reg = 0;

// Set bit 5: reg |= (1 << 5)


// Clear bit 5: reg &= ~(1 << 5)
// Toggle bit 5: reg ^= (1 << 5)
// Check bit 5: if (reg & (1 << 5))

// Set bits 3:1 (mask 0b00001110):


reg |= 0x0E;
// Clear bits 3:1:
reg &= ~0x0E;

Q38. Write code to set the 5th bit.


uint32_t reg = 0;
reg |= (1U << 5); // sets bit 5 (0-indexed)
// reg = 0b00100000 = 0x20
■ Use 1U (unsigned) not 1 to avoid signed shift issues. Always use the |= pattern to preserve other bits.

Q39. Write code to clear the 3rd bit.


uint32_t reg = 0xFF;
reg &= ~(1U << 3); // clears bit 3
// reg = 0b11110111 = 0xF7

// Toggle bit 3:
reg ^= (1U << 3);

Q40. Explain endianness.


Endianness defines the byte order in which multi-byte values are stored in memory.
• Little-endian: LSB at lowest address (ARM Cortex-M default, x86)
• Big-endian: MSB at lowest address (network byte order)
uint32_t val = 0x12345678;
// Little-endian memory: [78][56][34][12]
// Big-endian memory: [12][34][56][78]

// Check at runtime:
uint16_t x = 1;
bool little = *(uint8_t*)&x; == 1;
■ TI LOVES this — DMA transfers, protocol parsing, and network stacks all need endianness awareness.

Embedded Interview Answer Bible — 100 Questions Page 9


SECTION 3: OPERATING SYSTEMS
Q41. Difference between process and thread?
Process Thread

Memory Own address space Shares process address space

Resources Own file handles, heap Shares heap, file handles

Stack Own stack Own stack (shared heap)

Communication IPC (pipes, sockets) Shared memory directly

Overhead High (context switch) Low (context switch)

Crash impact Isolated Can crash whole process

Q42. What is context switching?


Context switching is the process of saving the current execution state (registers, PC, SP, flags) and restoring
another task's saved state, allowing the CPU to switch between tasks.
• Triggered by: timer interrupt, system call, voluntary yield
• Saves: PC, SP, general registers, status flags
• In RTOS: done by scheduler on every tick or yield
• Cost: register save/restore + possible cache flush — avoid excessive switching

Q43. Explain scheduling algorithms.


• FCFS (First Come First Served): non-preemptive, simple, convoy effect
• Round Robin: each task gets fixed time slice (quantum), then preempted
• Priority Scheduling: highest priority runs first; can cause starvation
• Preemptive: running task can be interrupted by higher priority task
• Non-preemptive: task runs until it voluntarily yields or blocks
• EDF (Earliest Deadline First): used in real-time systems
■ RTOS like FreeRTOS uses preemptive priority scheduling with round-robin for equal-priority tasks.

Q44. What is deadlock?


Deadlock is a situation where two or more tasks are permanently blocked, each waiting for a resource held by the
other.
// Task A holds Mutex1, waits for Mutex2
// Task B holds Mutex2, waits for Mutex1
// → Both wait forever = DEADLOCK

Q45. Conditions for deadlock?


All four conditions (Coffman conditions) must hold simultaneously:
• Mutual Exclusion: resource can only be held by one task
• Hold and Wait: task holds a resource while waiting for another
• No Preemption: resource cannot be forcibly taken away
• Circular Wait: circular chain of tasks each waiting for next
■ Break any ONE condition to prevent deadlock. Common fix: always acquire locks in same order (breaks circular wait).

Q46. Explain semaphore.


A semaphore is a signaling mechanism with a counter. Two operations: wait (P) decrements counter — blocks if 0;
signal (V) increments counter — wakes blocked task.
• Binary semaphore (0 or 1): for signaling between ISR and task

Embedded Interview Answer Bible — 100 Questions Page 10


• Counting semaphore: tracks available resources (e.g., buffer slots)
• Unlike mutex: semaphore can be signaled from ISR or different task
// ISR signals semaphore:
void UART_IRQ() { xSemaphoreGiveFromISR(sem, &woken;); }
// Task waits for data:
void task() { xSemaphoreTake(sem, portMAX_DELAY); }

Q47. Difference between mutex and semaphore?


Mutex Semaphore

Purpose Mutual exclusion Signaling / resource count

Ownership Owned by one task No ownership concept

ISR use Cannot give from ISR Can signal from ISR

Priority inheritance Supported (FreeRTOS) Not supported

Initial value 1 (unlocked) 0 (wait for signal)

Use case Protect shared resource Event signaling

Q48. What is starvation?


Starvation occurs when a low-priority task never gets CPU time because higher-priority tasks always preempt it.
The low-priority task is perpetually blocked even though it's not deadlocked.
■ Fix: aging — gradually increase priority of waiting tasks over time.

Q49. Explain priority inversion.


Priority inversion occurs when a high-priority task is indirectly blocked by a low-priority task holding a shared
resource, while a medium-priority task runs instead.
Low priority task L holds Mutex M
High priority task H waits for Mutex M
Medium priority task X preempts L (since X > L)
Result: H waits while X runs — H's priority is "inverted" to below X
■ Fix: Priority Inheritance — temporarily boost L's priority to H's level while L holds the mutex. FreeRTOS mutexes support
this.

Q50. What is paging?


Paging divides physical memory into fixed-size frames and virtual address space into same-size pages. The OS
maps virtual pages to physical frames via a page table, allowing non-contiguous physical allocation and memory
isolation between processes.
■ Embedded systems often don't have MMU/paging — they use flat physical address space.

Q51. What is virtual memory?


Virtual memory gives each process the illusion of a large, contiguous, private address space larger than physical
RAM. Pages not in RAM are stored on disk (swap) and loaded on demand (page fault). Enabled by MMU
hardware.
■ Most microcontrollers (Cortex-M) don't have virtual memory — they have MPU (Memory Protection Unit) instead.

Q52. Difference between user mode and kernel mode?


• User mode: restricted — cannot access hardware directly, limited instructions
• Kernel mode: privileged — full hardware access, all instructions allowed
• Switching: happens via system call, interrupt, or exception
• Purpose: protection — user code crash cannot corrupt kernel
• ARM: User mode = Thread mode; Kernel = Handler mode (on interrupt)

Embedded Interview Answer Bible — 100 Questions Page 11


Q53. What is interrupt latency?
Interrupt latency is the time between when an interrupt signal is asserted and when the first instruction of the ISR
executes. Critical in real-time systems.
• Components: interrupt detection + context save + ISR entry
• Factors: CPU pipeline flush, instruction in progress, interrupt masking
• ARM Cortex-M: as low as 12 cycles (with FPU) to enter ISR
• Minimize by: keeping ISRs short, minimizing interrupt disable time

Q54. Explain IPC mechanisms.


• Pipes: unidirectional byte stream between related processes
• Message queues: structured messages, sender/receiver decoupled
• Shared memory: fastest IPC — processes map same physical memory
• Semaphores: synchronization between processes
• Sockets: network or local communication
• RTOS equivalent: queues, mailboxes, event flags

Q55. What is shared memory?


Shared memory maps the same physical memory region into multiple process address spaces — fastest IPC since
no data copying. Requires synchronization (mutex/semaphore) to prevent race conditions.

Q56. Explain cache coherence.


In multi-core systems, each core has its own cache. Cache coherence ensures all cores see a consistent view of
memory — if Core 1 updates a value, Core 2's cache must be invalidated or updated.
■ Embedded: relevant in multi-core MCUs and DMA — DMA writes to RAM may not invalidate CPU cache. Must
flush/invalidate cache explicitly.

Q57. Difference between polling and interrupts?


Polling Interrupts

CPU usage Wastes CPU checking CPU free until event

Latency Depends on poll rate Low and deterministic

Power High (CPU always busy) Low (CPU can sleep)

Complexity Simple to implement ISR + sync needed

Use case High-rate, predictable events Async, infrequent events

Q58. What is a real-time OS?


An RTOS is an OS that guarantees tasks will execute within defined time bounds (deadlines). Deterministic
scheduling is its core property — response time is predictable.
• Hard real-time: deadline miss = system failure (airbags, pacemakers)
• Soft real-time: deadline miss = degraded performance (video streaming)
• Examples: FreeRTOS, Zephyr, ThreadX, VxWorks
• Features: preemptive scheduler, inter-task sync, deterministic ISR latency

Q59. Difference between hard and soft real-time systems?


• Hard RT: missing a deadline causes catastrophic failure — aircraft, medical devices, ABS brakes
• Soft RT: missing deadline degrades performance but system continues — video calls, music streaming
• Firm RT: deadline misses are tolerable but result is useless — stock trading systems

Q60. Why does deterministic timing matter?

Embedded Interview Answer Bible — 100 Questions Page 12


In embedded control systems, the physical world doesn't wait. A motor controller must update PWM within
microseconds. An airbag must deploy within milliseconds. Non-deterministic timing means unpredictable physical
behavior — potentially dangerous in safety-critical systems.

Embedded Interview Answer Bible — 100 Questions Page 13


SECTION 4: COMPUTER ARCHITECTURE
Q61. Explain instruction pipeline.
Pipelining overlaps execution of multiple instructions by dividing execution into stages. ARM Cortex-M has a 3-5
stage pipeline.
• Stages: Fetch → Decode → Execute → Memory → Writeback
• While instruction N is executing, instruction N+1 is being decoded, N+2 is being fetched
• Ideal throughput: 1 instruction per clock cycle
■ Pipeline increases throughput but doesn't reduce latency of a single instruction.

Q62. What are pipeline hazards?


• Data hazard: instruction needs result of previous instruction not yet written back
• Control hazard: branch instruction — don't know next PC until branch resolved
• Structural hazard: two instructions need same hardware resource simultaneously
• Solutions: stalls (bubbles), forwarding (bypass), branch prediction, out-of-order execution

Q63. What causes cache misses?


• Compulsory miss: first access to a memory location — cold miss
• Capacity miss: working set larger than cache size
• Conflict miss: multiple addresses map to same cache set
• Poor spatial locality: jumping around memory non-sequentially
• Poor temporal locality: accessing data once and not reusing
■ TI sample problem: row-major access has good spatial locality → fewer cache misses vs column-major.

Q64. Difference between SRAM and DRAM?


SRAM DRAM

Storage Flip-flops (6 transistors) Capacitor + transistor (1T1C)

Speed Very fast (1-10 ns) Slower (50-100 ns)

Cost Expensive Cheap

Refresh Not needed Needs periodic refresh

Use Cache, TCM in MCUs Main RAM in computers

Power Higher static Lower per bit

Q65. Explain DMA.


Direct Memory Access allows peripherals to transfer data to/from memory without CPU involvement. A DMA
controller handles the transfer while CPU executes other code.
// Without DMA: CPU copies 1000 bytes one-by-one
for(int i=0; i<1000; i++) RAM[i] = UART_DR;

// With DMA: one setup call, DMA does the transfer


DMA_Config(src=UART_DR, dst=buf, count=1000);
DMA_Start();
// CPU is FREE to do other work
// DMA fires interrupt when complete

Q66. Why does DMA improve performance?


• CPU is free for computation while DMA handles bulk data transfer
• Especially valuable for: ADC sampling, UART RX, SPI bulk transfer, camera data

Embedded Interview Answer Bible — 100 Questions Page 14


• Reduces interrupt overhead — one interrupt at end vs per-byte interrupt
• Enables zero-copy architectures — data goes directly to final buffer
■ TI LOVES DMA questions. Know: DMA channels, priority, burst mode, circular mode, cache coherence issues with DMA.

Q67. Explain memory hierarchy.


Memory hierarchy organizes storage by speed, size, and cost:
• Registers: fastest, ~1 cycle, bytes (CPU internal)
• L1 Cache: ~4 cycles, KB range, per-core
• L2 Cache: ~12 cycles, MB range
• RAM (SRAM/DRAM): ~100 cycles, GB range
• Flash/Storage: ms range, GB-TB
■ Embedded MCU equivalent: Registers > Tightly Coupled Memory (TCM) > SRAM > Flash

Q68. What is cache locality?


• Temporal locality: recently accessed data likely to be accessed again soon → cache keeps it
• Spatial locality: data near recently accessed data likely to be accessed → cache loads cache lines
• Cache line: typically 32-64 bytes loaded at once
• Code implication: sequential array access >> random pointer chasing

Q69. Difference between Harvard and Von Neumann architecture?


Von Neumann Harvard

Memory buses Single shared bus Separate instruction + data buses

Bottleneck Von Neumann bottleneck No bus contention

Flexibility Self-modifying code possible Cannot modify code easily

Speed Slower (shared bus) Faster (parallel access)

Use x86 PCs Most microcontrollers (AVR, ARM Cortex-M)

Q70. Explain branch prediction.


Branch prediction allows the CPU to speculatively execute instructions past a branch before knowing the actual
branch outcome. If prediction is correct, no stall. If wrong, pipeline must flush speculative work.
■ Implication: avoid unpredictable branches in tight embedded loops — hurts pipeline performance.

Q71. What is MMU?


Memory Management Unit — hardware that translates virtual addresses to physical addresses and enforces
memory access permissions. Required for virtual memory and process isolation. Most Cortex-M MCUs use MPU
(Memory Protection Unit) instead of full MMU.

Q72. Difference between physical and virtual address?


• Physical address: actual location in RAM/Flash hardware
• Virtual address: address seen by process — translated by MMU
• Translation: MMU uses page tables to map virtual → physical
• Embedded MCUs: typically flat physical addressing (no virtual memory)

Q73. Explain TLB.


Translation Lookaside Buffer — a small, fast cache for page table entries. When CPU needs to translate a virtual
address, it first checks TLB. TLB hit: fast translation. TLB miss: must walk page table in RAM — slow. TLB is
flushed on context switch.

Q74. What is bus arbitration?

Embedded Interview Answer Bible — 100 Questions Page 15


When multiple masters (CPU, DMA, multiple cores) want to use the same bus simultaneously, bus arbitration
decides who gets access. Common schemes: round-robin, fixed priority, first-come-first-served.
■ In embedded: DMA vs CPU arbitration matters — DMA may steal bus cycles from CPU, increasing memory access latency.

Q75. Explain interrupt vector table.


The interrupt vector table (IVT) is an array of function pointers stored at a fixed memory location. When an interrupt
fires, hardware looks up the corresponding ISR address from the IVT and jumps to it.
// ARM Cortex-M: IVT at 0x00000000 by default
// Entry 0: Initial Stack Pointer
// Entry 1: Reset Handler
// Entry 2: NMI Handler
// Entry n: IRQ(n-16) Handler

// In startup code:
void (*isr_vectors[])(void) __attribute__((section(".isr_vector"))) = {
(void*)&_estack,
Reset_Handler,
NMI_Handler,
HardFault_Handler,
...
};

Q76. What is throughput vs latency?


• Latency: time from request to response for a SINGLE operation
• Throughput: number of operations completed per unit time
• Example: DMA transfer of 1000 bytes — latency = time for that one transfer; throughput = bytes/second
• Pipeline improves throughput, not latency of individual instruction

Q77. Explain clock skew.


Clock skew is the difference in arrival time of the same clock signal at different points in a circuit due to different
wire lengths, loads, or buffer delays. In synchronous digital systems, clock skew can cause setup/hold time
violations and data corruption.

Q78. Why are caches smaller but faster?


• SRAM (cache) uses 6 transistors per bit — fast but expensive and large
• DRAM (RAM) uses 1 transistor + capacitor per bit — dense but slow
• Physical proximity to CPU — cache is on-chip, RAM is off-chip
• Smaller capacity → simpler addressing → lower access time
• Tradeoff: cost per bit vs speed

Q79. What limits CPU frequency scaling?


• Power: P = C × V² × f — power grows with frequency squared
• Heat: higher frequency → more switching → more heat
• Memory wall: RAM speed hasn't kept up with CPU speed
• Signal integrity: at high frequencies, trace lengths cause timing issues
• Leakage current: even idle transistors leak more at high voltage/temp

Q80. Explain speculative execution.


CPU executes instructions before knowing if they will be needed (speculative), to keep pipeline full. Results are
discarded if speculation was wrong. Examples: branch prediction, out-of-order execution, prefetching.
■ Spectre/Meltdown vulnerabilities exploited speculative execution to leak memory across security boundaries.

Embedded Interview Answer Bible — 100 Questions Page 16


SECTION 5: MICROCONTROLLERS & INTERFACES
Q81. Explain GPIO internally.
GPIO (General Purpose Input/Output) pins are controlled by registers. Internally each pin has: direction register
(input/output), output data register, input data register, and alternate function register.
// Typical register-based GPIO control:
#define GPIOA_MODER (*((volatile uint32_t*)0x40020000)) // mode
#define GPIOA_ODR (*((volatile uint32_t*)0x40020014)) // output data
#define GPIOA_IDR (*((volatile uint32_t*)0x40020010)) // input data

// Set PA5 as output:


GPIOA_MODER |= (1 << 10); // bits [11:10] = 01
// Set PA5 HIGH:
GPIOA_ODR |= (1 << 5);
// Read PA0:
uint32_t val = GPIOA_IDR & (1 << 0);

Q82. What are pull-up resistors?


Pull-up resistors connect a pin to VCC through a resistor, ensuring a defined HIGH state when nothing else drives
the pin. Pull-down connects to GND for defined LOW state.
• Floating pin: undefined state, susceptible to noise — must pull up or down
• Internal pull-up: most MCUs have software-configurable internal pull-ups
• Button circuit: button to GND + pull-up → reads HIGH normally, LOW when pressed
• I2C: requires external pull-up resistors on SDA and SCL lines

Q83. Explain timer interrupts.


A hardware timer counts clock cycles. When it reaches a configured value, it fires an interrupt, resets, and
continues counting. Used for periodic tasks, timeouts, PWM generation, and delays.
// Configure TIM2 for 1ms interrupt at 72MHz clock:
TIM2->PSC = 71; // prescaler: 72MHz/72 = 1MHz
TIM2->ARR = 999; // auto-reload: 1MHz/1000 = 1kHz = 1ms
TIM2->DIER |= (1<<0); // enable update interrupt
TIM2->CR1 |= (1<<0); // enable timer

void TIM2_IRQHandler() {
TIM2->SR &= ~(1<<0); // clear interrupt flag
// do 1ms periodic work here
}

Q84. Difference between polling and interrupt-driven systems?


Already covered in Q57. Embedded context addition:
• Interrupt-driven is preferred for most embedded applications — saves power
• Polling justified for: very high-frequency events where ISR overhead dominates
• UART @ 9600 baud — interrupt driven. ADC @ 1MSPS — DMA/polling may be better
• Hybrid: use interrupt to wake from sleep, then poll in active mode

Q85. Explain PWM generation.


PWM (Pulse Width Modulation) generates a digital signal that switches between HIGH and LOW at a fixed
frequency, with a variable duty cycle to control average power/voltage.
• Frequency = 1/Period (set by Timer ARR register)

Embedded Interview Answer Bible — 100 Questions Page 17


• Duty Cycle = (ON time / Period) × 100%
• Use cases: motor speed control, LED brightness, servo position, DAC substitute
// 1kHz PWM, 50% duty cycle on TIM3 CH1:
TIM3->PSC = 71; // 1MHz timer clock
TIM3->ARR = 999; // 1kHz frequency
TIM3->CCR1 = 500; // 50% duty cycle
TIM3->CCMR1 |= (6<<4); // PWM mode 1
TIM3->CCER |= (1<<0); // enable channel

Q86. What is a watchdog timer?


A watchdog timer is a hardware timer that resets the MCU if firmware fails to 'kick' (reload) it within a set time
period. Detects firmware hangs, infinite loops, or deadlocks.
// Initialize watchdog for 1 second timeout
IWDG->KR = 0x5555; // enable write
IWDG->PR = 4; // prescaler
IWDG->RLR = 0xFFF; // reload value
IWDG->KR = 0xCCCC; // start watchdog

// In main loop — must kick before 1 second:


IWDG->KR = 0xAAAA; // kick/reload watchdog
■ Never kick the watchdog in an ISR — defeats the purpose. Only kick in main loop when system is healthy.

Q87. Explain ADC quantization.


ADC (Analog-to-Digital Converter) converts a continuous analog voltage to a discrete digital value. Quantization is
the process of mapping the continuous range to discrete levels.
• Resolution: N-bit ADC has 2^N discrete levels (12-bit → 4096 levels)
• LSB = Vref / 2^N (voltage per digital step)
• Quantization error: maximum ±0.5 LSB
• Sampling rate must be ≥ 2× signal bandwidth (Nyquist theorem)
// 12-bit ADC, Vref=3.3V:
// LSB = 3.3/4096 = 0.806mV
// Digital value 2048 → 2048 × 0.806mV = 1.65V

Q88. What determines ADC resolution?


• Number of bits: more bits → smaller voltage step → finer resolution
• Reference voltage (Vref): lower Vref → smaller step for same bit count
• SNR (Signal-to-Noise Ratio): noise limits effective resolution
• ENOB (Effective Number of Bits): actual vs theoretical resolution accounting for noise

Q89. Explain DAC operation.


DAC (Digital-to-Analog Converter) converts a digital value to an analog voltage. Output voltage = (digital_value /
2^N) × Vref. Used for audio output, signal generation, and setting analog reference levels.

Q90. Difference between SPI and I2C?


SPI I2C

Wires 4 (MOSI, MISO, CLK, CS) 2 (SDA, SCL)

Speed Up to 50+ MHz 100kHz/400kHz/1MHz/3.4MHz

Devices One CS per slave Multiple slaves (7-bit address)

Duplex Full duplex Half duplex

Hardware No ACK required ACK/NACK per byte

Embedded Interview Answer Bible — 100 Questions Page 18


Complexity Simple protocol More complex (addressing, ACK)

Distance Short (same PCB) Short (same PCB)

Use case High speed: displays, Flash Multiple slow devices: sensors

Q91. Explain UART framing.


UART (Universal Asynchronous Receiver/Transmitter) sends data asynchronously as a serial bit stream with a
defined frame format:
• Start bit: always 0 (line goes LOW) — signals start of frame
• Data bits: 5-9 bits, LSB first typically
• Parity bit (optional): even/odd error detection
• Stop bit(s): always 1 (line HIGH) — 1 or 2 bits
• Baud rate: both sides must agree (e.g., 115200 baud = 115200 bits/sec)
Frame: [START=0][D0][D1][D2][D3][D4][D5][D6][D7][STOP=1]
// 8N1 format: 8 data, no parity, 1 stop bit (most common)

Q92. Why is SPI faster than I2C?


• SPI is synchronous — dedicated clock line, no bit-banging needed
• SPI has dedicated MOSI and MISO — full duplex simultaneous TX+RX
• I2C has bus overhead: START/STOP conditions, address byte, ACK per byte
• I2C open-drain lines + pull-ups limit rise time → limits speed
• SPI push-pull outputs → faster edge transitions → higher clock speed

Q93. What is clock stretching in I2C?


Clock stretching allows a slave device to hold the SCL line LOW to pause the master when the slave is not ready
to receive/send data. The master must wait until SCL is released. Used when slave needs more processing time
between bytes.

Q94. Explain bootloader.


A bootloader is a small program stored at the beginning of Flash memory that runs first on MCU reset. It checks for
update conditions, can erase/reprogram the application Flash via UART/USB/CAN, then jumps to the main
application.
// Bootloader flow:
// 1. Power on → execute bootloader at 0x08000000
// 2. Check: is BOOT pin HIGH? Is UART data available?
// 3. If yes: receive new firmware, write to Flash
// 4. Jump to application:
void jump_to_app(uint32_t addr) {
uint32_t sp = *(uint32_t*)addr;
uint32_t pc = *(uint32_t*)(addr+4);
__set_MSP(sp);
((void(*)(void))pc)();
}

Q95. What happens during MCU reset?


• PC set to Reset_Handler address from vector table
• Stack pointer loaded from vector table entry 0
• Peripherals reset to default state
• Startup code runs: initialize .data (copy from Flash to RAM), zero .bss
• SystemInit() called: configure clocks, PLL
• main() called

Embedded Interview Answer Bible — 100 Questions Page 19


Q96. Explain brownout condition.
A brownout occurs when supply voltage drops below a threshold (but doesn't reach 0V). MCU behavior becomes
unreliable — registers may corrupt, Flash writes may fail. BOR (Brownout Reset) circuit detects this and holds
MCU in reset until voltage recovers.
■ Critical for battery-powered embedded systems — must configure BOR threshold appropriately.

Q97. What is debounce?


Mechanical switches bounce — rapidly oscillate between open/closed for 1-50ms when pressed. Without
debouncing, firmware sees multiple press events. Debouncing filters these spurious transitions.
• Hardware debounce: RC filter + Schmitt trigger
• Software debounce: read pin, wait 10-50ms, read again — if still same, accept
• Interrupt debounce: disable interrupt for 50ms after first trigger
// Software debounce:
bool read_button() {
if(GPIO_Read(BTN_PIN) == 0) { // button pressed
delay_ms(20); // wait
if(GPIO_Read(BTN_PIN) == 0) // still pressed
return true;
}
return false;
}

Q98. Explain low-power modes.


• Sleep mode: CPU stopped, peripherals running, fast wake
• Deep sleep/Stop mode: CPU + most clocks stopped, GPIO state retained, slower wake
• Standby mode: nearly all powered off, only RTC + backup RAM, slowest wake
• RAM retention: some modes power off RAM — must handle state carefully
• Wake sources: RTC alarm, external interrupt, WDT
■ TI interviews: always discuss power consumption tradeoffs. Active vs sleep current matters for battery life.

Q99. What happens during interrupt servicing?


• Hardware detects interrupt signal
• CPU finishes current instruction (mostly)
• CPU pushes context onto stack: PC, LR, R0-R3, R12, xPSR (ARM Cortex-M)
• CPU loads ISR address from vector table
• ISR executes
• ISR returns: CPU pops saved context, resumes interrupted code
■ ARM Cortex-M automatically saves/restores R0-R3, R12, LR, PC, xPSR — 'exception frame'. No manual save needed for
these.

Q100. Design firmware for a sensor node with low power and periodic communication.
This is the key 'design thinking' question. Walk through the architecture:
• Power strategy: sleep in deep sleep mode, wake via RTC every N seconds
• Sensor: wake, power-on sensor, wait stabilization time (~10ms)
• ADC: read sensor data via DMA for efficiency
• Processing: filter/average readings in RAM
• Communication: wake radio (BLE/LoRa), transmit packet, wait ACK, sleep radio
• Error handling: watchdog timer, retry on TX failure, store-and-forward if offline
• Power budget: calculate active time × active current + sleep time × sleep current

Embedded Interview Answer Bible — 100 Questions Page 20


while(1) {
Enter_Deep_Sleep(); // RTC wakes every 10s
// --- woken up ---
Sensor_PowerOn();
delay_ms(10); // sensor stabilization
data = ADC_Read_DMA(); // DMA transfer, CPU free
data = Filter(data); // moving average
Radio_Wake();
Radio_Transmit(data);
Radio_Sleep();
Sensor_PowerOff();
} // loop back to deep sleep
■ Key insight to say: 'I minimize active time and maximize sleep time. Every ms of active time costs microjoules. The goal is
duty cycle < 1% for months of battery life.'

Embedded Interview Answer Bible — 100 Questions Page 21


THE EMBEDDED MINDSET
→ Think at hardware level — know what physically happens when software runs

→ Understand timing — every microsecond matters in real-time systems

→ Reason about memory — stack, heap, Flash, RAM, registers

→ Understand concurrency — ISR vs main, mutex vs semaphore, race conditions

→ Write safe low-level code — volatile, const, bounds checking, watchdog

→ Debug systematically — oscilloscope, JTAG, printf, logic analyzer

Interviewers LOVE candidates who explain:

"What physically happens inside hardware when software executes."

Good Luck — Stay Hungry. Always.

Embedded Interview Answer Bible — 100 Questions Page 22

You might also like