Skip to main content

Embedded engineer role-specific interview questions

29 questions on role-specific for embedded engineer candidates. Expect prompts such as “ISR vs polling: when to choose each” and “Explain priority inversion and how to prevent it”, each with a worked answer outline and the follow-ups interviewers push on.

Questions

Showing 1 to 25 of 29 role-specific questions (page 1 of 2).

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

On an ARM Cortex-M microcontroller running FreeRTOS, how do you detect a task stack overflow before it corrupts memory silently? Walk me through the hardware and software mechanisms available.

Sample answer outline

A strong answer covers FreeRTOS stack overflow hooks (configCHECK_FOR_STACK_OVERFLOW modes 1 and 2), the stack canary watermark approach, and the MPU stack guard region available on Cortex-M3/M4/M7. The candidate should also mention the CONTROL register and the PSP/MSP split, and how the MPU can trap writes below the stack bottom. They should note that mode 1 only catches overflow at context switch time, while an MPU guard catches it immediately.

Expect these follow-ups

  • What does the HardFault handler look like when the MPU catches a stack overflow?
  • How do you size each task's stack in production?
cortex-mfreertosstack-overflowmpudebugging

As asked

Describe how you would set up a DMA transfer to move data from an SPI peripheral to SRAM on an STM32. What are the main pitfalls, especially around cache coherency and buffer alignment?

Sample answer outline

A strong answer covers configuring the DMA channel for peripheral-to-memory, setting the correct data width and burst size, enabling the DMA complete interrupt, and starting the peripheral. On Cortex-M7 with D-Cache, the candidate must invalidate the cache line for the destination buffer before reading it in software, and ensure the buffer is 32-byte aligned to avoid partial cache-line collisions. They should also mention double-buffering to avoid tearing.

Expect these follow-ups

  • How does STM32 HAL handle cache coherency in HAL_SPI_Receive_DMA, and what can go wrong if you do not call SCB_InvalidateDCache_by_Addr?
  • What happens if your DMA destination buffer is not 32-byte aligned on a Cortex-M7?
dmastm32spicache-coherencycortex-m7

As asked

How do you design a watchdog timer strategy for a safety-critical embedded system with multiple RTOS tasks? A simple kick-in-main-loop approach is not acceptable here.

Sample answer outline

The candidate should describe a per-task heartbeat bitmap or counter that a dedicated watchdog task checks before kicking the hardware WDT. Each task must set its bit within a deadline; if any task misses its window, the watchdog task stops kicking and the hardware resets. They should mention windowed watchdogs, the importance of not kicking from an ISR, and handling the case where the watchdog task itself hangs.

Expect these follow-ups

  • How do you test that your watchdog strategy actually resets the device when a task hangs?
  • What does the startup code need to do with the watchdog before RTOS scheduling begins?
watchdogrtossafetyfreertosreliability

As asked

You are seeing intermittent UART framing errors and overrun errors on an STM32 in production. The baud rate is correct. Walk me through your systematic debug process.

Sample answer outline

A strong answer starts with checking the actual baud rate on a logic analyzer or oscilloscope, then looks at the overrun status register to distinguish framing (wrong stop bit) from overrun (RXNE not cleared in time). The candidate should check the ISR latency budget, consider switching to DMA receive, verify that the UART clock source is not affected by PLL changes at runtime, and check for noise on the RX line. They should mention that STM32 UART overrun disables further reception until the ORE bit is cleared.

Expect these follow-ups

  • How does enabling DMA for UART receive change the latency budget for handling incoming bytes?
  • If framing errors only appear at high baud rates, what hardware-level cause would you suspect?
uartstm32debuggingdmaserial-communication

As asked

A slave device on your I2C bus is clock-stretching for longer than your master expects, causing timeouts. How do you diagnose this and what are your options for fixing it without changing the slave hardware?

Sample answer outline

The candidate should start by confirming the stretch duration on an oscilloscope, then check the slave datasheet for the maximum stretch time for each command. Options include increasing the master timeout, reducing the I2C clock frequency, switching to a polling model instead of DMA for the master, or splitting long transfers into smaller chunks with delays. They should also mention checking that pull-up resistors are sized correctly for the bus capacitance.

Expect these follow-ups

  • How does bus capacitance affect the maximum safe I2C clock rate?
  • What happens on most STM32 I2C peripherals if SCL is held low for too long?
i2cclock-stretchingdebuggingstm32peripheral

As asked

Explain the role of a linker script in an embedded firmware build. Walk me through how you would place a time-critical function in SRAM instead of Flash on a Cortex-M device.

Sample answer outline

The candidate should explain .text, .data, .bss sections and the VMA/LMA distinction. To place a function in SRAM, they should describe creating a custom section in the linker script (e.g. .ramfuncs), adding the AT() LMA specifier to point load address to Flash, writing startup code to copy it during boot, and using __attribute__((section(".ramfuncs"))) on the function. They should mention that the XN bit must not be set on that SRAM region in the MPU.

Expect these follow-ups

  • Why would a function need to run from SRAM rather than Flash?
  • How do you verify at build time that the ramfuncs section did not overflow SRAM?
linker-scriptcortex-mmemorygccsram

As asked

How do you choose the RTOS tick rate (configTICK_RATE_HZ in FreeRTOS) for a battery-powered IoT device, and what are the power and timing tradeoffs of going too high or too low?

Sample answer outline

A strong answer notes that a higher tick rate gives finer delay resolution but increases the time the CPU spends in the tick ISR and wake-from-sleep overhead. For a battery device, the candidate should mention tickless idle mode where the RTOS programs a one-shot timer to skip ticks during deep sleep, making the nominal tick rate matter less for power. They should also note that software timers and timeouts expressed in ticks are capped at 1/configTICK_RATE_HZ resolution.

Expect these follow-ups

  • How does FreeRTOS tickless idle interact with vTaskDelay accuracy?
  • What peripheral do you use to implement tickless idle on an STM32?
freertosrtospower-managementtickless-idletiming

As asked

Walk me through designing a bootloader for over-the-air firmware updates on a Cortex-M device. What do you need to guarantee so that a power failure mid-flash cannot brick the device?

Sample answer outline

The candidate should describe a dual-bank or A/B partition scheme where the running image and the incoming image live in separate flash regions. The bootloader validates the new image with a CRC or cryptographic signature before committing, writes a flag in a dedicated persistent state region only after the full write is verified, and only jumps to the new image after a successful boot count. They should mention that EEPROM emulation in flash must handle the update flag atomically.

Expect these follow-ups

  • How do you prevent a rollback to a compromised firmware version?
  • What is the vector table relocation process when jumping from the bootloader to the application?
bootloaderotaflashcortex-mreliability

As asked

A sensor you are bringing up over SPI returns garbage data. MOSI, MISO, SCK, and CS all look correct on the logic analyzer. How do you determine whether this is a CPOL/CPHA mismatch, and how do you fix it without oscilloscope access to the sampling edge?

Sample answer outline

The candidate should explain the four SPI modes (0 to 3) defined by CPOL and CPHA, check the sensor datasheet for which mode it requires, and verify the master configuration register. On a logic analyzer they can look at whether data is captured on the rising or falling edge and whether the clock idles high or low. They should try all four modes systematically if the datasheet is ambiguous and mention that the SPI clock frequency must also be within the sensor's spec.

Expect these follow-ups

  • What is the difference between SPI Mode 0 and Mode 3 in terms of the idle clock state?
  • How would you detect a bit-shift error (off-by-one in the bit stream) on a logic analyzer capture?
spicpolcphadebuggingperipheral

As asked

On a single-core ARM Cortex-M4 without hardware atomics, how do you safely share a 64-bit counter between an ISR and the main context without using an RTOS mutex?

Sample answer outline

The candidate should explain that a 64-bit write on Cortex-M4 is two 32-bit bus transactions and is not atomic. The correct approach is to disable the relevant interrupt (or use PRIMASK to disable all interrupts) around the read/write in the main context. They should mention the LDREX/STREX exclusive access instructions available on M3/M4 for 32-bit values and that these do not help for 64-bit without wrapping both words. They should also discuss why a mutex is heavy and an interrupt mask is the minimal fix.

Expect these follow-ups

  • Would the same approach work on a Cortex-M0? What is missing?
  • How do you write a portable critical section macro that works on both FreeRTOS and bare-metal builds?
atomicscortex-misrcritical-sectionconcurrency

As asked

Describe the difference between Sleep, Stop, and Standby modes on an STM32L4. In a design that needs to wake on a UART byte every few seconds, which mode do you use and what do you need to configure to make that work?

Sample answer outline

The candidate should explain that Sleep keeps the CPU clock off but peripherals running; Stop shuts down most clocks but keeps SRAM and register content; Standby cuts almost everything and loses SRAM. For UART wake, they should describe using the LPUART1 peripheral which can run from the LSE or LSI in Stop mode, configure the wake-on-start-bit feature, and ensure the USART clock source is independent of the main PLL. They should mention that on wake from Stop the HSI or MSI restores and the application must re-lock the PLL if needed.

Expect these follow-ups

  • How long does it take to exit Stop mode and resume the main PLL on an STM32L4?
  • What happens to the SysTick counter when you enter Stop mode?
power-managementstm32low-powerlpuartsleep-modes

As asked

Your firmware hits a HardFault on a Cortex-M4. You have a JTAG debugger connected. Walk me through exactly how you find the faulting instruction and determine whether it was a bus fault, memory management fault, or usage fault.

Sample answer outline

The candidate should describe reading the CFSR (Configurable Fault Status Register), HFSR (HardFault Status Register), BFAR, and MMFAR registers. From the stacked PC on the exception frame they can find the faulting instruction. They should explain what BFSR IBUSERR vs PRECISERR vs IMPRECISERR mean, how to decode the stacked registers in the HardFault handler, and mention enabling the separate fault handlers (MemManage, BusFault, UsageFault) by setting SHCSR bits to avoid them escalating to HardFault.

Expect these follow-ups

  • What does IMPRECISERR indicate and why is it harder to debug than PRECISERR?
  • How do you write a HardFault handler that prints the stacked PC over a UART without using the stack?
hardfaultcortex-mdebuggingcfsrjtag

As asked

What are the pitfalls of using integer literals directly in bit manipulation on embedded targets, and how do you write portable, safe register manipulation macros in C?

Sample answer outline

The candidate should mention the dangers of signed integer overflow when shifting into the sign bit (1 << 31 on a 32-bit int is undefined behavior), the use of 1UL or UINT32_C(1) for unsigned 32-bit shifts, and the importance of masking before ORing into a register. They should show the read-modify-write pattern and explain why it matters for volatile registers. Bonus for mentioning that some registers are write-only and reading them returns undefined data.

Expect these follow-ups

  • Why is REG |= (1 << 31) undefined behavior in C?
  • How does __IO from CMSIS handle the volatile qualifier for peripheral registers?
c-languagebit-manipulationundefined-behaviorregisterscmsis

As asked

How do you write and run unit tests for embedded C firmware on a host machine, given that the code reads hardware registers directly? Walk me through your approach and toolchain.

Sample answer outline

The candidate should describe abstracting hardware access behind a HAL or function-pointer interface so that tests can substitute mock implementations. They should mention running the tests with a standard gcc on Linux or Windows, using frameworks like Unity, CppUTest, or Cmocka, and mocking the CMSIS register headers with simple uint32_t variables. They should also mention code coverage with gcov and integration into a CI pipeline that runs without target hardware.

Expect these follow-ups

  • How do you test timing-dependent code like debouncing logic without real hardware?
  • What is hardware-in-the-loop testing and when does it replace host-side unit tests?
unit-testingcmockaunityhost-testingci

As asked

You are parsing a big-endian network protocol payload on a little-endian ARM Cortex-M. What are the common bugs you see and how do you handle byte-order conversion correctly and efficiently?

Sample answer outline

The candidate should describe the bug pattern of casting a byte pointer directly to a multi-byte struct on a misaligned little-endian target, producing wrong values. The correct approach is to reconstruct multi-byte fields from individual bytes with explicit shifts, or use be32toh / ntohl style macros. On ARM, the REV instruction compiles from __REV(x) in CMSIS and is a single cycle. They should warn against using packed structs with pointer casts because of strict aliasing violations and alignment faults.

Expect these follow-ups

  • What is strict aliasing and how does it interact with type-punning in embedded C?
  • How does compiler flag -fno-strict-aliasing change the picture, and why is it a last resort?
endiannesscortex-mprotocol-parsingc-languagealignment

As asked

FreeRTOS ships five heap implementations (heap_1 through heap_5). How do you choose between them for a long-running system, and how do you detect and mitigate heap fragmentation at runtime?

Sample answer outline

The candidate should describe the progression: heap_1 (no free, deterministic), heap_2 (best-fit, no merge), heap_3 (wraps malloc/free), heap_4 (first-fit with merge, good for most use cases), heap_5 (non-contiguous regions). For long-running systems they should recommend heap_4 or heap_5 and suggest static allocation of long-lived objects to avoid fragmentation. Runtime monitoring via xPortGetFreeHeapSize and xPortGetMinimumEverFreeHeapSize can track headroom. They should also mention avoiding dynamic allocation after init.

Expect these follow-ups

  • How do you eliminate heap fragmentation entirely for a deterministic safety-critical system?
  • What is the cost of heap_4 allocation in the worst case and why?
freertosheapfragmentationmemory-managementrtos

As asked

You are reading a 12-bit ADC on an STM32 connected to a noisy analog sensor. The raw readings vary by 50 LSBs even when the input is static. Walk me through both hardware and firmware approaches to reduce this noise.

Sample answer outline

The candidate should describe hardware options (RC low-pass filter on the input, separate AVDD decoupling, PCB layout to keep analog traces away from switching lines) and firmware options (hardware oversampling and decimation available on STM32, software averaging with a rolling mean or moving average, and IIR low-pass filtering). They should mention the tradeoff between filter depth and update latency and that the STM32 ADC has a built-in hardware oversampling unit that can shift results up to 8 effective bits.

Expect these follow-ups

  • How does the STM32 ADC oversampling unit work and what bit depth can you achieve?
  • What is the quantization noise floor for a 12-bit ADC at 3.3V and how does oversampling improve it?
adcnoisefilteringstm32signal-processing

As asked

Your firmware crashes roughly once every 8 hours in the field. You cannot reproduce it on the bench. Walk me through your strategy for root-causing this without being present when it happens.

Sample answer outline

The candidate should describe adding a fault handler that writes the stacked PC, registers, and CFSR to a persistent area (RTC backup registers or non-volatile flash) before resetting, then reading this on next boot to reconstruct the crash context. They should also mention a RAM log ring buffer, adding assertions near suspected race conditions, enabling the CRC check on .text to detect flash corruption, and using a watchdog with cause logging. They should acknowledge that intermittent crashes often point to race conditions on shared data or rare ISR timing interactions.

Expect these follow-ups

  • How do you preserve a crash log across a hard reset on an STM32?
  • What assertion strategy helps catch corruption before the actual crash?
debuggingcrash-analysishardfaultloggingreliability

As asked

You want to use printf for debug output on an STM32 without a host file system. What are your options, what are the code-size and timing costs of each, and how do you disable it all for a release build?

Sample answer outline

The candidate should describe retargeting _write (Newlib) or fputc (MicroLib) to redirect to UART or SWO (Trace), the use of SWO ITM printf which has near-zero CPU overhead, and the ARM Semihosting approach which halts the CPU and is unsuitable for standalone operation. They should mention that Newlib printf with float support adds significant code size and recommend a lightweight alternative like tinyprintf. For release builds, defining printf as an empty macro or using a compile-time log level guard removes all calls.

Expect these follow-ups

  • What is SWO output and how does it differ from UART for debug logging?
  • How do you measure the actual UART transmission time for a printf call and why does it matter for real-time tasks?
printfdebuggingnewlibswocode-size

As asked

A firmware build starts crashing only after adding a new feature. The device has 256KB RAM and no MMU. How do you investigate memory pressure?

Sample answer outline

Start from the linker map to see static RAM, stack, heap, and section growth before debugging randomly. Add stack high-water marks, heap allocation tracing if a heap exists, and guard patterns around buffers to catch overflow. Reproduce under worst-case task scheduling and input sizes because embedded failures often depend on timing. Consider moving constant data to flash, reducing buffer sizes, using static allocation, or splitting features behind compile-time flags. Candidates often focus on CPU debugging and miss that the crash is a layout or stack collision problem.

Expect these follow-ups

  • How do you size task stacks in an RTOS?
  • When would you ban dynamic allocation after startup?
  • What clues in a hard fault point to stack corruption?
memorylinker-mapdebugging

As asked

On an ARM Cortex-M, why might the compiler or the processor reorder writes to memory-mapped peripheral registers, and what do you use to prevent it?

Sample answer outline

The candidate should explain two distinct reordering concerns. First, the C compiler can reorder volatile accesses to different objects because C does not guarantee ordering between separate volatile variables; a compiler-level barrier such as asm volatile('' ::: 'memory') prevents this. Second, on Cortex-M3 and above, a write buffer can allow a Device-region write to be outstanding while subsequent instructions execute; however, the ARM architecture guarantees that Device memory (the default attribute for the peripheral address space at 0x40000000 to 0x5FFFFFFF) is already strongly ordered relative to other Device accesses on the same bus, so a DMB is not needed between two ordinary peripheral register writes on the same bus. A DSB is needed when the CPU must wait for a peripheral write to complete before proceeding (for example, before entering a sleep mode or before a subsequent DMA transfer reads a register the CPU just wrote). An ISB is needed after changing MPU or SCB settings so the pipeline is flushed. Cortex-M0 and M0+ have no write buffer and are fully in-order, so this concern does not apply to them.

Expect these follow-ups

  • Give me a concrete example where DMB is needed between two peripheral register writes.
  • What is the difference between DSB and ISB on Cortex-M?
cortex-mmemory-barriersdsbdmbcompiler

As asked

Explain the CAN bus error state machine: error active, error passive, and bus-off. When does a node enter bus-off, and how does it recover? What firmware actions should you take when you detect bus-off?

Sample answer outline

The candidate should describe the Transmit Error Counter (TEC) and Receive Error Counter (REC), how each error frame increments them, the thresholds for error passive (TEC or REC >= 128) and bus-off (TEC >= 256). Recovery from bus-off requires 128 occurrences of 11 consecutive recessive bits. In firmware, they should enable the bus-off interrupt, log the event, optionally attempt automatic recovery, and notify the application layer. They should also mention that STM32 bxCAN has an auto bus-off recovery option.

Expect these follow-ups

  • What conditions on the physical layer cause TEC to increment rapidly?
  • How would you test bus-off recovery in a lab environment?
can-buserror-handlingbus-offstm32networking