Skip to main content

Interview questions

Embedded engineer interview questions

Embedded engineers build software that runs close to hardware, often with strict limits on memory, power, latency and updateability. Interviews commonly cover C or Rust, real-time constraints, device drivers, debugging tools, firmware release safety and hardware-software tradeoffs.

Seniorities
juniormidseniorstaffprincipal

Most reported

Top embedded engineer interview questions

6 questions

Sorted by reported frequency. Click any question for the sample outline, follow-ups, and reference implementation.

As asked

A sensor produces data at irregular intervals and the device runs on battery. When would you use interrupts instead of polling, and what can go wrong?

Sample answer outline

Interrupts let the CPU sleep and react when the sensor signals data, which is often better for irregular events and power-sensitive devices. Polling can be simpler and more predictable when timing is fixed, the check is cheap, or the hardware interrupt line is unreliable. Keep interrupt service routines short: capture the event, clear the flag, and defer real work to the main loop or RTOS task. Discuss debouncing, missed interrupts, priority inversion, shared data races, and volatile or atomic access. Interviewers want practical embedded judgement, not a blanket rule that interrupts are always better.

Expect these follow-ups

  • How do you safely share data between an ISR and the main loop?
  • When can polling be more deterministic than interrupts?
  • How would you debug an interrupt storm in the field?
firmwareinterruptspower

As asked

Walk me through your decision process for choosing between interrupt-driven I/O and polling on a microcontroller. What factors push you toward one or the other, and can you give me a concrete example where you made that call?

Sample answer outline

A strong answer covers latency requirements, CPU utilization, and event frequency as the key factors. The candidate should explain that polling suits high-frequency, predictable events where the cost of the ISR entry/exit overhead exceeds the polling cost, while ISRs suit low-frequency or latency-critical events. They should mention the danger of blocking inside an ISR and give a concrete scenario such as a UART receive or a GPIO edge detection.

Expect these follow-ups

  • How do you handle ISR latency jitter on an ARM Cortex-M?
  • What happens if your ISR runs longer than the next interrupt period?
interruptsisrpollingcortex-mreal-time

As asked

What is priority inversion, and how does it manifest in an RTOS like FreeRTOS or Zephyr? Walk me through a real scenario and how you would prevent or recover from it.

Sample answer outline

The candidate should describe the classic scenario where a low-priority task holds a mutex needed by a high-priority task, and a medium-priority task preempts the low-priority one, effectively blocking the high-priority task indefinitely. They should mention priority inheritance as the primary mitigation and be aware of ceiling protocols. Bonus points for mentioning that FreeRTOS mutexes implement priority inheritance but binary semaphores do not.

Expect these follow-ups

  • Does FreeRTOS priority inheritance fully solve priority inversion? What are the limits?
  • How would you detect priority inversion on a live system without a JTAG debugger?
rtosfreertospriority-inversionmutexscheduling

As asked

Explain what the volatile keyword does in C, why it matters for embedded firmware, and give me two scenarios where omitting it would cause a real bug that the compiler would not warn you about.

Sample answer outline

The candidate should explain that volatile prevents the compiler from caching a variable in a register across reads, forcing every access to go to memory. Scenario 1: a memory-mapped peripheral register where the compiler might eliminate a read because it sees no writes in the C code. Scenario 2: a flag set inside an ISR and polled in main context, where the optimizer may hoist the read out of a loop. They should also mention that volatile does not imply atomicity.

Expect these follow-ups

  • Is volatile sufficient for sharing data between an ISR and a task on a single-core ARM? Why or why not?
  • What optimizer flags can make volatile bugs appear or disappear?
c-languagevolatilecompilerisrmemory-mapped-io

As asked

Implement a lock-free single-producer single-consumer ring buffer in C for passing bytes between a UART ISR (producer) and a main-loop consumer on a single-core Cortex-M. It must not use mutexes or disable interrupts.

Sample answer outline

The candidate should use separate head and tail indices with volatile qualifiers and ensure that the producer only writes head after writing data, and the consumer only writes tail after reading data. The key is that on a single-core system with a single producer and consumer, no locking is needed as long as head and tail each have a single writer. They should use a power-of-two buffer size and modulo-via-mask, and be careful that size checks use copies of the volatile indices to avoid re-reading a changing value mid-check.

Reference implementation (c)

C
#define BUF_SIZE 256  // must be power of two

typedef struct {
    uint8_t  data[BUF_SIZE];
    volatile uint32_t head;  // written only by producer (ISR)
    volatile uint32_t tail;  // written only by consumer (main)
} RingBuf;

void rb_push(RingBuf *rb, uint8_t byte);
int  rb_pop(RingBuf *rb, uint8_t *byte); // returns 1 if data available
uint32_t rb_used(const RingBuf *rb);

Expect these follow-ups

  • Why do you need volatile on head and tail here even though this is single-core?
  • How does this approach break on a multi-core system, and what is the fix?
ring-bufferisrlock-freeuartc-language

As asked

Tell me about a time you found a race condition in embedded firmware. How did you identify it, what was the impact, and what did you change to fix it?

Sample answer outline

A strong answer describes a specific incident: the setup (what the code was doing, why concurrency was involved), how the bug manifested (intermittent, hard to reproduce), the debugging approach (logic analyzer, added instrumentation, code inspection), the root cause (missing volatile, missing critical section, non-atomic read-modify-write), and the fix (interrupt disable, FreeRTOS mutex, LDREX/STREX). They should quantify the impact and mention what they added to prevent recurrence.

Expect these follow-ups

  • How did you test that your fix actually eliminated the race rather than just making it less frequent?
  • What code review or static analysis process would have caught this before it shipped?
behavioralrace-conditiondebuggingconcurrencystar

Also known as

embedded software engineer - firmware engineer - IoT engineer