Day 4/30 : 100 Embedded C QNA
### **1. Basic Concepts**
1. **Explain the difference between volatile and const in Embedded C.**
- **Answer:** volatile informs the compiler that a variable can change unexpectedly (e.g., hardware registers, ISR-modified variables). It disables compiler optimizations like caching the value in a register. const indicates the variable is read-only (e.g., fixed configuration data). Combining them (`volatile const`) defines a read-only hardware register (e.g., volatile const uint32_t *REG = 0x40000000;).
2. **When would you use the restrict keyword?**
- **Answer:** restrict tells the compiler that a pointer is the sole reference to the memory it points to, enabling optimizations (e.g., loop vectorization). Example: DSP algorithms where input/output buffers don’t overlap:
```c
void multiply(int restrict a, int restrict b, int *restrict result, int size);
```
3. **How do you toggle the 5th bit of a register without affecting others?**
- **Answer:** Use XOR with a bitmask:
```c
REGISTER ^= (1 << 4); // Bit 4 is the 5th bit (0-indexed)
```
XOR toggles the bit, while AND/OR set/clear bits.
4. **What is endianness, and how does it affect data communication?**
- **Answer:** Endianness defines byte order in multi-byte data. Little-endian stores LSB at the lowest address (common in ARM). Big-endian stores MSB first (e.g., network protocols). Mismatched endianness corrupts data; use htonl()/`ntohl()` for conversion.
5. **Why use __attribute__((packed)) in structs?**
- **Answer:** It removes padding bytes to align structs with memory-mapped hardware or packed data formats (e.g., network packets). Risks include unaligned memory access (e.g., ARM crashes on unaligned uint32_t access).
6. **How to minimize interrupt latency?**
- **Answer:**
- Keep ISRs short (defer processing to main loop).
- Use higher-priority interrupts.
- Avoid blocking calls (e.g., printf, dynamic allocation).
- Enable compiler optimizations for ISRs (e.g., -O3).
7. **What is a watchdog timer (WDT)?**
- **Answer:** A hardware timer that resets the system if not refreshed periodically. Used to recover from software hangs. Example: Refresh the WDT in a critical task loop.
8. **DMA vs CPU-Driven Data Transfer**
- **Answer:** DMA transfers data between peripherals and memory without CPU involvement, freeing the CPU for other tasks (e.g., ADC to buffer). CPU-driven transfers are simpler but waste cycles (e.g., polling UART).
9. **Name three power-saving modes in microcontrollers.**
- **Answer:**
- **Sleep:** CPU halted, peripherals active. Wakes via interrupt.
- **Stop:** Clocks stopped, RAM retained. Wakes via external event.
- **Standby:** Lowest power, RAM lost. Wakes via reset or external signal.
10. **How can compiler optimizations break hardware register access?**
- **Answer:** Compilers may optimize out "redundant" writes or cache reads. Example:
```c
uint32_t reg = (uint32_t)0x40000000;
*reg = 1; // Compiler might remove this "unused" write
```
Fix: Declare reg as volatile.
---
### **2. Pointers and Memory Management**
11. **When would you use a triple pointer (e.g., int ***arr)?**
- **Answer:** Rarely. Example: Dynamic 3D array allocation:
```c
int ***arr = malloc(10 sizeof(int*));
for (int i=0; i<10; i++) {
arr[i] = malloc(20 sizeof(int));
for (int j=0; j<20; j++) arr[i][j] = malloc(30 * sizeof(int));
}
```
12. **How to use function pointers in ISRs?**
- **Answer:** Assign a function pointer to handle ISRs dynamically:
```c
void (*ISR_Handler)(void) = default_handler;
void TIMER_ISR() { ISR_Handler(); } // Assign via ISR_Handler = custom_handler;
```
13. **What is memory alignment, and why does it matter?**
- **Answer:** Data aligned to natural boundaries (e.g., 4-byte int on 4-byte address). Misalignment causes bus errors on ARM or performance penalties (x86). Use __attribute__((aligned(8))) to enforce alignment.
14. **Are bit-fields portable?**
- **Answer:** No. Bit-field allocation depends on compiler implementation (e.g., order, padding). Avoid for cross-platform code.
15. **How to access memory-mapped I/O registers?**
- **Answer:** Use volatile pointers:
```c
volatile uint32_t const reg = (uint32_t)0x40020000;
*reg = 0xABCD; // Write to register
```
16. **Why avoid dynamic memory in embedded systems?**
- **Answer:** Heap fragmentation, non-deterministic timing (e.g., malloc delays), and memory leaks. Use static pools or RTOS memory managers.
17. **How to detect a dangling pointer?**
- **Answer:** Tools like static analyzers (e.g., Coverity), runtime checks (e.g., set pointers to NULL after free), or hardware MMU (detect invalid access).
18. **How to prevent memory fragmentation?**
- **Answer:** Use fixed-size memory pools (e.g., FreeRTOS’s pvPortMalloc), allocate upfront, or avoid dynamic allocation entirely.
19. **Is pointer arithmetic allowed on void*?**
- **Answer:** No. void* has no size, so cast to char* first:
```c
void *ptr = ...;
char p = (char)ptr + offset; // Valid
```
20. **How does restrict optimize code?**
- **Answer:** Compiler assumes no pointer aliasing, enabling reordering/vectorization. Example:
```c
void copy(int restrict dst, int restrict src, int size) {
for (int i=0; i<size; i++) dst[i] = src[i]; // Can be vectorized
}
```
---
### **3. Interrupts and ISRs**
21. **What makes code non-reentrant?**
- **Answer:** Use of static/global variables. Example: A function modifying a static buffer is unsafe if called from ISR and main loop.
22. **How to prevent race conditions in ISRs?**
- **Answer:** Use atomic operations, disable interrupts during critical sections, or RTOS primitives (e.g., queues):
```c
ATOMIC_BLOCK() { critical_code(); } // Macro to disable/enable interrupts
```
23. **How to share data between an ISR and main loop?**
- **Answer:** Use volatile for shared variables and disable interrupts during access:
```c
volatile bool flag = false;
void main() {
DISABLE_IRQ(); if (flag) { ... } ENABLE_IRQ();
}
```
24. **How to set ISR priorities in ARM Cortex-M?**
- **Answer:** Use the NVIC (Nested Vectored Interrupt Controller):
```c
NVIC_SetPriority(TIMER_IRQn, 0); // 0 = highest priority
```
25. **Why keep ISRs short?**
- **Answer:** Long ISRs block lower-priority interrupts and increase system latency. Defer processing using flags or RTOS queues.
26. **When to use volatile in ISRs?**
- **Answer:** For variables shared between ISRs and non-ISR code (e.g., status flags). Prevents compiler from caching stale values.
27. **How to enable nested interrupts?**
- **Answer:** Configure NVIC priorities and enable in the CPU’s control register (e.g., __enable_irq() in ARM).
28. **How to communicate between ISR and RTOS task?**
- **Answer:** Use RTOS primitives like queues, semaphores, or task notifications (e.g., xQueueSendFromISR() in FreeRTOS).
29. **How to debug ISRs?**
- **Answer:** Use logic analyzers, toggle GPIO pins on entry/exit, or trace tools (e.g., Segger SystemView).
30. **Pros/cons of disabling interrupts?**
- **Pros:** Atomic access to shared data.
- **Cons:** Increased interrupt latency, missed events.
---
### **4. Real-Time Operating Systems (RTOS)**
31. **What is priority inversion?**
- **Answer:** A low-priority task holds a resource needed by a high-priority task, causing the high-priority task to block. Mitigated by priority inheritance.
32. **Mutex vs. Semaphore**
- **Answer:** Mutex ensures exclusive access (lock/unlock). Semaphore signals availability (e.g., producer-consumer).
33. **How to prevent deadlocks?**
- **Answer:** Avoid nested locks, use timeouts, or enforce lock ordering.
34. **What is a memory pool?**
- **Answer:** Pre-allocated fixed-size blocks for dynamic allocation (avoids fragmentation).
35. **What is a task stack overflow?**
- **Answer:** Stack exceeds allocated memory, corrupting adjacent data. Detected via RTOS hooks or stack canaries.
36. **How to implement a watchdog in RTOS?**
- **Answer:** Dedicate a task to periodically check other tasks’ health and refresh the hardware WDT.
37. **What is tickless idle mode?**
- **Answer:** RTOS halts the system tick during idle to reduce power consumption.
38. **How to measure task execution time?**
- **Answer:** Use a hardware timer or RTOS profiling tools (e.g., uxTaskGetRunTimeStats() in FreeRTOS).
39. **What is a reentrant function?**
- **Answer:** Safe to call from multiple threads/ISRs (no static/global state).
40. **How to synchronize tasks across cores in an MCU?**
- **Answer:** Use inter-processor interrupts (IPIs) or shared memory with atomic operations.
---
### **5. Optimization**
41. **Space vs. Speed Optimization Trade-offs**
- **Answer:** Use lookup tables (speed) vs. on-the-fly computation (space). Depends on memory constraints.
42. **What is loop unrolling?**
- **Answer:** Reduce loop overhead by repeating code (e.g., for (i=0; i<100; i+=4) { ... }). Increases code size but reduces branches.
43. **When to use inline functions?**
- **Answer:** For small, frequently-called functions (avoids call overhead). Can increase code size.
44. **What is register allocation?**
- **Answer:** Compiler assigns variables to CPU registers (faster access). Use register keyword (limited effect).
45. **How to reduce power consumption in firmware?**
- **Answer:** Use low-power modes, clock gating, and peripheral sleep states.
46. **What is the purpose of -O0 vs. -O3?**
- **Answer:** -O0 disables optimizations (debugging). -O3 enables aggressive speed optimizations.
47. **How to optimize ISR latency?**
- **Answer:** Use vectorized interrupts, prioritize in NVIC, and avoid context switches.
48. **When to use assembly in Embedded C?**
- **Answer:** For cycle-critical code (e.g., DSP loops) or hardware-specific operations (e.g., WFI instruction).
49. **What is a memory-mapped file?**
- **Answer:** A file mapped to memory addresses (rare in embedded). Used in Linux for I/O.
50. **How to reduce binary size?**
- **Answer:** Remove unused code, use -ffunction-sections, and enable linker garbage collection.
---
### **6. Debugging and Testing**
51. **What is JTAG?**
- **Answer:** A hardware interface for debugging (breakpoints, memory inspection).
52. **How to debug a hard fault?**
- **Answer:** Check the stack frame, fault registers (e.g., SCB->CFSR in ARM), and trace using a debugger.
53. **What is a logic analyzer?**
- **Answer:** Captures digital signals (e.g., SPI, I2C) for timing analysis.
54. **How to use assert() in Embedded C?**
- **Answer:** Validate assumptions (e.g., assert(buffer != NULL)). Disable in production via NDEBUG.
55. **What is a semihosting?**
- **Answer:** Debugging technique where target code uses host I/O (e.g., printf via debugger).
56. **How to measure stack usage?**
- **Answer:** Fill stack with a pattern (e.g., 0xAA) and check max usage at runtime.
57. **What is a bus pirate?**
- **Answer:** A tool for debugging I2C/SPI/UART without a logic analyzer.
58. **How to test ISRs?**
- **Answer:** Trigger interrupts via software or hardware and validate responses.
59. **What is a core dump?**
- **Answer:** Snapshot of memory/registers at crash time. Analyze using addr2line or GDB.
60. **How to validate RTOS task scheduling?**
- **Answer:** Use trace tools (e.g., Percepio Tracealyzer) or toggling GPIO pins.
---
### **7. MISRA-C and Safety**
61. **What is MISRA-C?**
- **Answer:** A coding standard for safety-critical systems (e.g., Rule 1.1: No undefined behavior).
62. **Why ban recursion in MISRA-C?**
- **Answer:** Recursion can cause stack overflows (non-deterministic).
63. **How to comply with MISRA’s pointer arithmetic rules?**
- **Answer:** Use array indexing instead of pointer arithmetic (e.g., arr[i] vs *(arr+i)).
64. **What is a side effect in MISRA-C?**
- **Answer:** A change in state (e.g., modifying a global variable). Restricted in expressions.
65. **How to handle deviations from MISRA-C?**
- **Answer:** Document deviations with justifications (e.g., hardware access requires pointer casting).
66. **What is LDRA in static analysis?**
- **Answer:** A tool for MISRA compliance checking and code metrics.
67. **Why restrict function length in MISRA?**
- **Answer:** Shorter functions are easier to verify and test.
68. **What is a circular dependency?**
- **Answer:** Module A depends on B, and B depends on A. Banned in MISRA.
69. **How to enforce MISRA in a legacy codebase?**
- **Answer:** Incremental adoption using static analysis tools and team training.
70. **What is ISO 26262?**
- **Answer:** Functional safety standard for automotive systems (relies on MISRA-C).
---
### **8. Peripherals and Protocols**
71. **How to configure a UART?**
- **Answer:** Set baud rate, parity, stop bits, and enable interrupts/DMA.
72. **SPI vs. I2C**
- **Answer:** SPI is full-duplex, faster, uses 4 wires. I2C is half-duplex, slower, uses 2 wires.
73. **What is a ring buffer?**
- **Answer:** FIFO data structure for ISR-main loop communication (previles overwriting).
74. **How to handle I2C clock stretching?**
- **Answer:** Detect SCL held low by slave and pause communication.
75. **What is a PWM dead time?**
- **Answer:** Delay between turning off one MOSFET and turning on another (prevents shoot-through).
76. **How to debounce a button?**
- **Answer:** Use hardware RC filters or software timers (e.g., check state after 50ms).
77. **What is CAN bus arbitration?**
- **Answer:** Nodes transmit IDs; lower ID wins bus access (non-destructive arbitration).
78. **How to read an ADC in noise environments?**
- **Answer:** Use oversampling, averaging, or hardware filters.
79. **What is a timer capture mode?**
- **Answer:** Records the timestamp of an external event (e.g., rising edge).
80. **How to implement software I2C?**
- **Answer:** Bit-bang SDA/SCL with GPIO toggling and clock stretching handling.
---
### **9. Advanced C Concepts**
81. **What is a variadic function?**
- **Answer:** Accepts variable arguments (e.g., printf). Use va_list, va_start, va_arg.
82. **How to use #pragma once?**
- **Answer:** Header guard to prevent multiple inclusions (modern alternative to #ifndef).
83. **What is a linker script?**
- **Answer:** Defines memory regions and section placement (e.g., .text, .data).
84. **How to place code in RAM?**
- **Answer:** Use compiler-specific attributes (e.g., __attribute__((section(".ram_code")))).
85. **What is a weak symbol?**
- **Answer:** Allows overriding functions (e.g., __weak void handler() {}).
86. **How to implement a singleton in Embedded C?**
- **Answer:** Use static global variables and restrict access via functions.
87. **What is _Noreturn?**
- **Answer:** Indicates a function doesn’t return (e.g., main in bare-metal systems).
88. **How to use offsetof()?**
- **Answer:** Get byte offset of a struct member:
```c
struct s { int a; char b; };
size_t offset = offsetof(struct s, b); // Returns 4
```
89. **What is a trampoline function?**
- **Answer:** Small function that jumps to another (e.g., for ISR vector redirection).
90. **How to implement polymorphism in C?**
- **Answer:** Use structs with function pointers (e.g., VTable pattern).
---
### **10. Project-Specific Scenarios**
91. **How to reduce firmware boot time?**
- **Answer:** Skip self-tests, lazy initialize peripherals, and use quick clocks.
92. **How to secure firmware updates?**
- **Answer:** Use cryptographic signing (e.g., ECDSA), secure boot, and encrypted binaries.
93. **How to design a low-power sensor node?**
- **Answer:** Use sleep modes, wake on interrupt, and optimize ADC sampling.
94. **How to handle EEPROM wear leveling?**
- **Answer:** Distribute writes across sectors and use a journaling file system.
95. **How to validate RTOS task priorities?**
- **Answer:** Use rate monotonic analysis (RMA) or response-time analysis (RTA).
96. **How to detect stack overflow?**
- **Answer:** Use MPU to guard stack boundaries or fill stacks with canary values.
97. **How to implement a custom bootloader?**
- **Answer:** Reserve flash sectors, validate firmware CRC, and jump to application.
98. **How to optimize battery life in IoT devices?**
- **Answer:** Use deep sleep, reduce radio TX power, and batch sensor data.
99. **How to handle firmware rollbacks?**
- **Answer:** Store multiple firmware versions and validate via version checks.
100. **How to design a fault-tolerant system?**
- **Answer:** Use redundancy (e.g., dual MCUs), watchdog timers, and error-correcting code (ECC).
---
Junior Product Developer Intern At Teshuvah Bioinics| Ex-Vectorian | C, C++, Embedded C, I2C,SPI,UART, CAN
2moDefinitely worth reading