8 Essential Low-Level Questions for Embedded C Programmer Interviews

Introduction“Do you understand the interrupt mechanism of Cortex-M?”“How do you implement a memory pool in C?”“How is volatile used in embedded systems?”

If you are asked these questions in an interview and cannot answer, you may be eliminated immediately!Embedded development is different from regular software development; interviewers focus heavily on low-level skills..

Today, we reveal 8 frequently asked low-level technical questions to help you successfully pass the technical interview at major companies!

Question 1: How does the CPU load code from Flash and execute it?

Interviewer’s Focus

  • Understanding the boot process of embedded systems

  • Proficiency with linker scripts (.ld files)

Standard Answer

  1. After power-up, the CPU reads the SP (stack pointer) and PC (program counter) from a fixed address (usually 0x00000000).

  2. According to the linker script defined<span>.text</span> section, copy the code from Flash to RAM (some chips require this)

  3. Initialize the<span>.data</span> section (initialized global variables) and zero out the<span>.bss</span> section (uninitialized global variables)

  4. Jump to the<span>main()</span> function

Bonus Answer:“In STM32, the<span>SystemInit()</span> function initializes the clock before executing<span>main()</span>

Question 2: Why can’t an interrupt service routine (ISR) call printf?

Interviewer’s Focus

  • Understanding of reentrant functions and interrupt context

Standard Answer

  1. printf is not reentrant: It uses a static buffer internally, and calls from multiple tasks/interrupts can lead to data corruption

  2. Execution time is too long: It may block higher priority interrupts

  3. It may cause deadlock: If printf internally calls a system call that is masked by an interrupt

Correct Approach:

  • Set a flag in the ISR and handle it in the main loop

  • Use an RTOS message queue to pass data

Question 3: How to detect stack overflow in C?

Interviewer’s Focus

  • Practical experience with memory management

Standard Answer

Method 1: Fill with Magic Number

#define STACK_MAGIC 0xDEADBEEF  uint32_t stack_sentinel = STACK_MAGIC;  void check_stack() {      if (stack_sentinel != STACK_MAGIC) {          printf("Stack Overflow!");      }  }

Method 2: Use MPU (Memory Protection Unit)

  • Set a protected area at the stack boundary, triggering an exception on overflow

Bonus Answer:“FreeRTOS’s<span>uxTaskGetStackHighWaterMark()</span> can detect peak stack usage”

Question 4: What is the impact of structure alignment on embedded systems?

Interviewer’s Focus

  • Understanding of memory access efficiency

Standard Answer

  1. Performance Impact: Unaligned 32-bit access on Cortex-M0/M3 will trigger multiple memory operations

  2. Hardware Limitations: Some DMA controllers require 4/8-byte alignment

  3. Memory Savings: Using<span>#pragma pack(1)</span> to disable alignment can reduce space but decrease speed

Example:

struct __attribute__((packed)) SensorData {      uint8_t id;     // 1 byte      uint32_t value; // 4 bytes (would normally have 3 bytes padding)  };

Question 5: What is “bit-banding”? How to implement it in C?

Interviewer’s Focus

  • Mastery of special features in ARM architecture

Standard Answer

Bit-banding Feature:

  • ARM Cortex-M allows individual access to a specific bit through an alias address

  • Modifying one bit does not affect other bits in the same byte

Implementation Code:

#define BITBAND(addr, bit) ((0x42000000 + ((uint32_t)(addr)-0x40000000)*32 + (bit)*4))  *(volatile uint32_t *)BITBAND(&amp;GPIOA-&gt;ODR, 1) = 1; // Set PA1 individually

Question 6: Why should embedded systems avoid dynamic memory allocation?

Interviewer’s Focus

  • Understanding of real-time system stability

Standard Answer

  1. Memory Fragmentation: After long-term operation, it may be impossible to allocate contiguous memory

  2. Non-determinism: The execution time of malloc/free is unpredictable

  3. Safety Risks: Allocation failures may lead to system crashes

Alternative Solutions:

  • Static memory pools

  • Object pool pattern (e.g., CAN message buffers)

Question 7: Explain the role of the volatile keyword in the following code

volatile uint32_t *reg = (uint32_t *)0x40020800;

Interviewer’s Focus

  • Depth of understanding of compiler optimization

Standard Answer

  1. Prevents Optimization: Ensures that each access truly reads and writes the register

  2. Prevents Reordering: Guarantees that the operation order matches the code

  3. Applicable Scenarios:

  • Hardware registers

  • Multithreaded shared variables

  • Global variables modified by interrupts

Common Mistake:“volatile guarantees atomicity” (actually requires disabling interrupts or atomic instructions)

Question 8: How to implement a lightweight memory pool in C?

Interviewer’s Focus

  • Ability to implement memory management algorithms

Standard Answer

Core Idea:

  1. Pre-allocate a large block of memory

  2. Manage free blocks with a linked list

  3. Remove a node from the list when allocating, and insert it back when freeing

Code Framework:

typedef struct {      void *start_addr;      uint16_t block_size;      uint16_t total_blocks;      uint8_t *mem_map; // Bitmap to manage usage status  } mem_pool_t;  void mem_pool_init(mem_pool_t *pool);  void *mem_pool_alloc(mem_pool_t *pool);  void mem_pool_free(mem_pool_t *pool, void *ptr);  

Conclusion: The Knowledge System Behind the 8 Questions

Question Category Skills Assessed Further Learning Suggestions
Boot Process System Architecture Study bootloader implementation
Interrupt Management Real-time Control Learn RTOS scheduling principles
Memory Management Resource Optimization Master memory pool/garbage collection algorithms
Hardware Operations Low-level Drivers Read chip reference manuals

Start filling in the gaps now!

Interactive Topic:What other “killer questions” have you encountered in interviews? Feel free to discuss in the comments!

Leave a Comment