HireHireInterview Quizzes › Embedded / Firmware Engineer

Embedded / Firmware Engineer Interview Questions

Think you're ready? These are the questions that actually decide Embedded / Firmware Engineer interviews. Warm up on Easy — then face the Hard round, where 95% of candidates crumble. 30 questions across 3 levels, instant score, completely free.

30Questions
3Difficulty levels
95%Fail the hard round
FreeInstant score
Easy
Warm-up · 10 Qs
Medium
Practical · 10 Qs
Hard
Brutal · 10 Qs
⚡ Take the Embedded / Firmware Engineer quiz — get your score →

The Embedded / Firmware Engineer interview questions

Below are the real questions, grouped by difficulty. Expand any one to reveal the correct answer and why — or take the timed quiz for a score you can share. Can you clear the Hard round?

Easy round 10 questions

In C, what is the primary purpose of the `volatile` keyword when accessing a hardware register?
  • A. It prevents the compiler from optimizing away or caching reads/writes, forcing actual memory access each time ✓
  • B. It places the variable in read-only flash memory
  • C. It makes the variable atomic across multiple threads
  • D. It allocates the variable on the heap instead of the stack
Correct answer: A. `volatile` tells the compiler the value may change outside program flow (e.g., hardware), so every access must hit actual memory rather than a cached register copy.
An ISR (interrupt service routine) sets a flag that the main loop polls. Which qualifier should the shared flag have to be reliable?
  • A. const
  • B. volatile ✓
  • C. static only
  • D. register
Correct answer: B. The flag is modified asynchronously by the ISR, so `volatile` prevents the compiler from optimizing the main loop's polling reads into a single cached value.
In an I2C bus, what is the role of the pull-up resistors on the SDA and SCL lines?
  • A. They actively drive the lines high for faster edges
  • B. They pull the open-drain lines to logic high when no device is pulling them low ✓
  • C. They limit current to protect the microcontroller only
  • D. They provide the clock signal for the bus
Correct answer: B. I2C uses open-drain outputs that can only pull low, so external pull-ups return the lines to the high state, enabling wired-AND behavior.
Which communication protocol is full-duplex and uses separate MOSI and MISO lines plus a chip-select?
  • A. I2C
  • B. UART
  • C. SPI ✓
  • D. CAN
Correct answer: C. SPI is a full-duplex synchronous protocol with dedicated MOSI, MISO, SCLK, and per-slave chip-select (SS) lines.
A 10-bit ADC has a reference voltage of 3.3 V. What is the approximate voltage resolution (LSB size) per code?
  • A. 3.22 mV ✓
  • B. 12.9 mV
  • C. 0.33 mV
  • D. 32.2 mV
Correct answer: A. A 10-bit ADC has 1024 codes, so resolution = 3.3 V / 1024 ≈ 3.22 mV per step.
In a microcontroller startup, what is the primary responsibility of the startup code before `main()` runs?
  • A. Initialize peripherals like UART and SPI
  • B. Copy initialized data to RAM, zero the .bss section, and set up the stack pointer ✓
  • C. Load the application from external flash over the network
  • D. Configure the RTOS scheduler and create tasks
Correct answer: B. The startup (crt0) code initializes the C runtime: sets the stack pointer, copies .data from flash to RAM, and clears the .bss section before calling main().
Why is a watchdog timer commonly used in embedded firmware?
  • A. To generate accurate PWM signals for motor control
  • B. To reset the system automatically if the firmware hangs and fails to periodically 'kick' it ✓
  • C. To measure elapsed CPU cycles for profiling
  • D. To provide a low-power sleep timer for the RTC
Correct answer: B. A watchdog timer resets the MCU if software fails to refresh it within a timeout, recovering the system from hangs or lockups.
In an RTOS, what problem does a priority-inheritance mutex specifically address?
  • A. Deadlock between two tasks holding two mutexes
  • B. Priority inversion, where a high-priority task waits on a resource held by a low-priority task ✓
  • C. Stack overflow in low-priority tasks
  • D. Race conditions in interrupt handlers
Correct answer: B. Priority inheritance temporarily raises the priority of a low-priority task holding a mutex to that of the waiting high-priority task, preventing unbounded priority inversion.
For a UART configured at 9600 baud, 8 data bits, no parity, 1 stop bit (8N1), how many bits are transmitted per byte on the wire?
  • A. 8 bits
  • B. 9 bits
  • C. 10 bits ✓
  • D. 11 bits
Correct answer: C. Each frame is 1 start bit + 8 data bits + 0 parity + 1 stop bit = 10 bits per byte.
What is the main advantage of using DMA to transfer data from a peripheral to memory?
  • A. It encrypts the data during transfer
  • B. It moves data without CPU involvement, freeing the CPU for other work ✓
  • C. It guarantees the data is error-free via built-in CRC
  • D. It reduces the peripheral's power consumption to zero
Correct answer: B. DMA offloads bulk data movement from the CPU, allowing transfers to proceed in the background while the CPU performs other tasks.

Medium round 10 questions

You declare a global flag `int flag;` that is set inside an ISR and polled in your main `while` loop. On `-O2` the main loop never sees the update, though it works on `-O0`. What is the correct fix?
  • A. Declare the flag as `volatile int flag;` ✓
  • B. Declare the flag as `static int flag;`
  • C. Add a `__attribute__((packed))` to the flag
  • D. Move the flag into the ISR's local scope
Correct answer: A. `volatile` tells the compiler the variable can change outside normal program flow, preventing it from caching the value in a register across the loop.
A 16 MHz microcontroller drives a UART at 9600 baud 8N1. Roughly how long does it take to transmit a single byte (including start and stop bits)?
  • A. About 1.04 ms ✓
  • B. About 104 us
  • C. About 8.3 us
  • D. About 10.4 ms
Correct answer: A. One 8N1 frame is 10 bits, and at 9600 baud each bit is ~104 us, so 10 bits take about 1.04 ms.
You need to read a 16-bit ADC over I2C where the value is split across two 8-bit registers, high byte first. Which expression correctly reconstructs the value from `hi` and `lo` (both `uint8_t`)?
  • A. `((uint16_t)hi << 8) | lo` ✓
  • B. `hi | (lo << 8)`
  • C. `(hi << 8) + (lo << 8)`
  • D. `(uint16_t)(hi + lo)`
Correct answer: A. The high byte must be shifted left by 8 and OR-ed with the low byte, and casting `hi` to 16-bit prevents the shift from overflowing an 8-bit promotion edge case.
Your firmware uses a hardware watchdog timer with a 2-second timeout. What is the primary purpose of periodically 'kicking' (feeding) it in your main loop?
  • A. To automatically reset the MCU if the firmware hangs or stops executing normally ✓
  • B. To keep the CPU clock synchronized with the RTC
  • C. To reduce power consumption during idle periods
  • D. To flush the UART transmit buffer on a fixed interval
Correct answer: A. A watchdog resets the system if it isn't fed within its timeout, recovering from lockups or infinite loops.
You want a GPIO input pin connected to a mechanical push button (button pulls the line to GND when pressed) to read a stable HIGH when not pressed, without adding an external resistor. What should you configure?
  • A. Configure the pin as input with the internal pull-up enabled ✓
  • B. Configure the pin as input with the internal pull-down enabled
  • C. Configure the pin as open-drain output driven HIGH
  • D. Configure the pin as floating input and read it twice
Correct answer: A. An internal pull-up holds the line HIGH when the button is open and lets it go LOW when the button connects the pin to ground.
In an SPI transaction, what is the role of the chip-select (CS/SS) line when a master communicates with one of several slaves on a shared bus?
  • A. It selects which slave is active, and each slave ignores clock/data unless its CS is asserted ✓
  • B. It provides the clock signal that all slaves synchronize to
  • C. It carries the acknowledge bit back from the addressed slave
  • D. It sets the SPI mode (CPOL/CPHA) for the selected slave
Correct answer: A. SPI slaves only respond when their individual chip-select line is asserted (usually active-low), so CS chooses the target device.
A bare-metal button read shows multiple spurious presses for a single physical push. What is the standard firmware technique to fix this?
  • A. Debounce the input by requiring the level to remain stable for a few milliseconds before accepting it ✓
  • B. Increase the GPIO drive strength on the input pin
  • C. Enable an internal pull-down and read the pin faster
  • D. Route the button through the ADC instead of a digital GPIO
Correct answer: A. Mechanical contacts bounce for a few milliseconds, so debouncing (in software or hardware) filters out the transient transitions.
In a linker script / startup context, which memory segment holds initialized global variables whose values must be copied from flash to RAM at startup?
  • A. .data ✓
  • B. .bss
  • C. .text
  • D. .rodata
Correct answer: A. `.data` holds initialized globals; their initial values live in flash and startup code copies them to RAM, while `.bss` (zero-initialized) is just cleared.
You use a hardware timer to generate a periodic 1 kHz interrupt for a control loop. Inside the ISR you currently do a full sensor read, a floating-point PID calculation, and a UART debug print. What is the best practice fix?
  • A. Keep the ISR minimal (e.g. set a flag or timestamp) and do the heavy work in the main loop ✓
  • B. Raise the ISR priority to the highest level so it always finishes
  • C. Disable all other interrupts for the duration of the ISR
  • D. Move the UART print earlier so it runs before the PID math
Correct answer: A. ISRs should be short and deterministic; long work (especially blocking UART) belongs in the main context, triggered by a flag the ISR sets.
In an RTOS, a low-priority task holds a mutex that a high-priority task needs, and a medium-priority task keeps preempting the low-priority one, so the high-priority task is blocked indefinitely. What is this problem called, and what feature addresses it?
  • A. Priority inversion, addressed by priority inheritance on the mutex ✓
  • B. Deadlock, addressed by disabling preemption globally
  • C. Starvation, addressed by round-robin time slicing only
  • D. Race condition, addressed by making the variable volatile
Correct answer: A. This is classic priority inversion, and priority inheritance temporarily boosts the mutex holder's priority so it can release the lock quickly.

Hard round 10 questions

An ISR sets a shared 32-bit `volatile uint32_t event_flags` and the main loop does `if (event_flags & 0x2) { event_flags &= ~0x2; }`. On a Cortex-M4 the flag is occasionally lost even though the variable is `volatile`. What is the precise root cause?
  • A. `volatile` does not force the variable into a CPU register, so the compiler re-reads stale memory
  • B. The main loop's `event_flags &= ~0x2` is a non-atomic read-modify-write; an ISR firing between the load and store overwrites the ISR's newly-set bit ✓
  • C. Cortex-M4 lacks cache coherency, so the ISR write never reaches the main-loop's view of memory
  • D. `volatile` disables the write buffer, so the store is dropped under back-to-back interrupts
Correct answer: B. The `&=` compiles to load-modify-store; if the ISR runs between the load and the store, its bit set is clobbered when the stale-modified value is written back, which volatile cannot prevent.
A high-priority task H is blocked waiting on a mutex held by a low-priority task L, while a medium-priority task M (which never touches the mutex) is CPU-bound and keeps preempting L. H misses its deadline. Under a priority-inheritance mutex, what specifically happens to break this?
  • A. L's priority is temporarily raised to H's priority while it holds the mutex, so M can no longer preempt L, letting L finish and release quickly ✓
  • B. M is temporarily demoted below L until the mutex is released
  • C. H's priority is lowered to L's so all three tasks run round-robin
  • D. The scheduler boosts M to H's priority to flush it out of the critical section faster
Correct answer: A. Priority inheritance raises the mutex holder (L) to the priority of the highest waiter (H) for the duration it holds the lock, so intermediate task M can no longer preempt it and the unbounded inversion is bounded.
On a Cortex-M7 with D-cache enabled, the CPU fills a TX buffer in a cacheable region, then starts a memory-to-peripheral DMA from that buffer. The peripheral transmits stale bytes. Assuming write-back caching, what is the correct fix?
  • A. Invalidate the cache lines covering the buffer before starting the DMA
  • B. Clean (flush) the cache lines covering the buffer before starting the DMA, ensuring the buffer is cache-line aligned and padded ✓
  • C. Disable interrupts around the DMA start to prevent reordering
  • D. Insert a DSB barrier before the DMA start; the barrier flushes dirty lines
Correct answer: B. For CPU→peripheral transfers the dirty CPU-written data sits in cache, so you must clean/flush those lines to main memory before the DMA reads them; alignment/padding avoids corrupting adjacent data on partial lines.
After a crash with no debugger attached, you recover from RAM: LR (EXC_RETURN) = 0xFFFFFFFD, and the stacked frame shows PC pointing into a valid function but the fault was a precise BusFault. What does EXC_RETURN 0xFFFFFFFD tell you about where to read the stacked registers?
  • A. The exception used the FPU extended frame; read from MSP
  • B. Return to Thread mode using the Process Stack Pointer (PSP), so the stacked R0-R3, R12, LR, PC, xPSR are on the PSP ✓
  • C. Return to Handler mode using MSP; the frame is on the MSP
  • D. The value is invalid; EXC_RETURN must be 0xFFFFFFF9 for a valid frame
Correct answer: B. EXC_RETURN 0xFFFFFFFD means return to Thread mode with PSP and the basic (non-FP) frame, so the stacked exception context must be read from the PSP, not the MSP.
A single-producer/single-consumer lock-free ring buffer uses `head` (written by ISR producer) and `tail` (written by task consumer). On a weakly-ordered Cortex-A core, the consumer sometimes reads a slot before the producer's data write is visible. Where must a barrier go, and why?
  • A. The producer must write the data slot, then execute a write barrier (DMB), then publish the incremented `head`, so data is visible before the index that exposes it ✓
  • B. Only the consumer needs a barrier, after reading `head`
  • C. Barriers are unnecessary if `head` and `tail` are `volatile`
  • D. Wrap both index updates in a spinlock; barriers cannot help SPSC buffers
Correct answer: A. The producer must ensure the data store is globally visible before the head-index store that publishes it, which requires a write barrier between the payload write and the index update on a weakly-ordered core.
You must clear bit 3 of a peripheral control register that also has a write-1-to-clear (W1C) interrupt-status field in the same 32-bit word. Doing `REG |= (1<<3)` on the whole word is dangerous. Why?
  • A. `|=` is atomic so it is actually safe here
  • B. The read-modify-write reads the currently-set W1C status bits and writes them back as 1, inadvertently clearing pending interrupt flags ✓
  • C. Writing to a control register always triggers a bus fault on partial words
  • D. The compiler will optimize away the load since the register is not volatile
Correct answer: B. A read-modify-write reads any currently-asserted W1C status bits as 1 and writes them back, which acknowledges/clears those interrupts as an unintended side effect; such registers need field-isolated or byte-wise access per the datasheet.
A firmware image does OTA via A/B partitions. After flashing slot B and rebooting into it, the device must decide whether the update is good. Which mechanism gives atomic rollback if slot B boots but fails a health check?
  • A. Erase slot A immediately after flashing B so there is no ambiguity
  • B. Boot B with a one-shot 'trial' flag; B must actively confirm (set 'confirmed') within a health window, else the bootloader reverts to A on the next reset ✓
  • C. Compute a CRC of B before boot; if it matches, mark B permanent
  • D. Copy B over A during boot so both slots are identical
Correct answer: B. A trial/pending flag that the new image must explicitly confirm after passing health checks lets the bootloader automatically fall back to the known-good slot if the confirmation never arrives, giving atomic rollback.
A battery sensor node wakes every second to sample and drains far faster than budgeted. Measured current in 'sleep' is ~1.2 mA instead of the expected few µA. Which cause is most consistent with this symptom?
  • A. The core enters WFI but a peripheral clock (e.g., a running timer or unstopped ADC/UART) and its clock domain were left ungated, keeping a high-power domain active ✓
  • B. WFI is the wrong instruction; WFE would reach a deeper mode
  • C. The MCU cannot reach stop mode because interrupts are globally disabled
  • D. Flash wait states are too high, increasing active current
Correct answer: A. A residual ~1 mA floor during 'sleep' typically means a peripheral/clock domain (timer, ADC, UART, or an unstopped oscillator) was not gated, so the part never truly entered the low-power state despite executing WFI.
Two tasks each need mutex A and mutex B. Task1 locks A then B; Task2 locks B then A. Occasionally the system hangs with both blocked. Besides using timeouts, what is the canonical structural fix?
  • A. Convert both mutexes to counting semaphores with count 2
  • B. Enforce a global lock-ordering discipline so every task always acquires A before B ✓
  • C. Raise Task1's priority above Task2 so it always wins
  • D. Disable preemption while any mutex is held
Correct answer: B. A circular wait requires two tasks to acquire the same locks in opposite orders; imposing a single consistent global acquisition order eliminates the cycle and thus the deadlock by construction.
A task set on a single core has periods/WCETs: T1(P=10,C=3), T2(P=15,C=4), T3(P=30,C=8), scheduled rate-monotonic (shorter period = higher priority). Total utilization U = 0.3+0.267+0.267 = 0.834. What can you conclude about schedulability?
  • A. U < 1 so it is definitely schedulable under RMS
  • B. U = 0.834 exceeds the n=3 Liu-Layland bound (~0.780), so the sufficient test fails; schedulability is inconclusive and needs an exact response-time analysis ✓
  • C. U > 0.780 so it is definitely NOT schedulable
  • D. RMS cannot schedule three tasks; use EDF
Correct answer: B. The Liu-Layland utilization bound is only sufficient, not necessary; since U exceeds the ~0.78 bound for 3 tasks you cannot conclude either way and must run an exact response-time (worst-case) analysis.

Prep for another role

Questions are original, written and independently verified for HireHire's role interview quizzes. They reflect the kind of knowledge Embedded / Firmware Engineer interviews test, not any specific company's questions. HireHire maps live tech & IT jobs across India, updated regularly. Last updated: July 2026.