All jobs / Embedded / hardware

RTOS interview questions

RTOS questions a Embedded / hardware can be asked, from first job to senior. Open one to see the strongest answer and why it works.

  1. When do you reach for a mutex, and when for a binary semaphore?

    The strongest answer: A mutex protects shared data — it has an owner who must give it back, and it can lend priority to whoever is blocked; a binary semaphore signals an event from an ISR or a task to a task

    Why it works: Exactly — ownership and priority inheritance are what make a mutex the right tool for shared data.

    • Mutex guards data; semaphore signals events.
    • A mutex has an owner; give it back.
    • Only a mutex can inherit priority.
    • Signal from an ISR with a semaphore.
  2. When do you pick an RTOS over a main-loop, and when not?

    The strongest answer: RTOS when I have concurrent deadlines I cannot honestly interleave — main-loop when the work is a simple sequence I can bound

    Why it works: Exactly. Concurrency you can name. Fashion and logos are not deadlines.

    • RTOS for named concurrent deadlines.
    • Main-loop when the sequence is boundable.
    • Not a fashion pick.
    • Not a logo pick.
  3. A UART interrupt needs to hand a byte to a task through an RTOS queue. What must the ISR do differently?

    The strongest answer: Call the FromISR version of the queue API, which never blocks, and pass the higher-priority-task-woken flag to the yield macro so the woken task runs as the ISR exits

    Why it works: Right — no blocking, and the yield is what makes the handoff prompt instead of waiting for the next tick.

    • ISRs use the FromISR calls and never block.
    • Send with the FromISR variant.
    • Pass the woken flag to the yield.
    • Keep the interrupt priority RTOS-callable.
  4. Average loop time is fine; the plant oscillates. What did you miss?

    The strongest answer: Jitter and worst case — I budget max, not mean, and I look at interrupts that steal the edge

    Why it works: Exactly. Control cares about the late one. Averages hide the thief.

    • Budget worst-case, not mean.
    • Find IRQs that steal the edge.
    • Do not hide jitter in an average.
    • Do not blame the plant first.
  5. A task should sample every 10 ms. It sleeps for 10 ms at the end of each pass, and over minutes the period slips.

    What is wrong?

    The strongest answer: A plain delay counts from the moment you call it, so the work time is added to every period; the delay-until form sleeps to an absolute next-wake time and holds the period

    Why it works: Right — delay-until anchors to the previous wake time, so jitter stops accumulating into drift.

    • Anchor a period to absolute time.
    • A plain delay measures from now.
    • Delay-until holds a fixed period.
    • Drift ruins filters and timestamps.
  6. Two tasks write a global “state” byte. What is the grown-up move?

    The strongest answer: A queue or a critical section I can name — I do not add a delay to “let the other one finish”

    Why it works: Exactly. A real exclusion. Volatile is visibility, not a lock. Sleeps and prints are folklore.

    • Queue or named critical section.
    • No luck delays.
    • volatile ≠ exclusion.
    • Printf ≠ a lock.
  7. A low-priority task holds a lock a high-priority task needs. What do you name?

    The strongest answer: Priority inversion — I want inheritance or a ceiling, or I redesign the lock, I do not raise everything to max

    Why it works: Exactly. Name it, then inheritance/ceiling/redesign. Max-priority-everything is a busy-loop OS.

    • Name inversion.
    • Inheritance, ceiling, or redesign.
    • Do not flatten every priority.
    • Do not sleep-turn-take.
  8. One task corrupts another’s stack. What do you add besides “be careful”?

    The strongest answer: MPU regions or separate privilege, plus a watermark — careful is not a boundary

    Why it works: Exactly. Hardware boundaries. Merging and enlarging hide the thief.

    • MPU or privilege split.
    • Keep watermarks.
    • Careful ≠ a boundary.
    • Do not merge smashers.
  9. You have a 2 ms control deadline. What number do you present?

    The strongest answer: Worst-case with the IRQs you allow, not a mean from a happy bench — and what you disable to hold it

    Why it works: Exactly. Deadline is a max. Host cycle counts are a different CPU.

    • Present worst-case, allowed IRQs.
    • Say what you disable to hold it.
    • Means are not the deadline.
    • Host cycle counts are not the chip.
  10. A low-priority logger never runs. What do you check before “buy a faster MCU”?

    The strongest answer: Whether high tasks never block — starvation — I add a bound or a budget, I do not raise the logger to max

    Why it works: Exactly. Starvation is a priority story. VIP loggers and ISR logs steal the plant.

    • Check starvation before a faster MCU.
    • Bound the high tasks.
    • Do not VIP the logger.
    • Do not log from an ISR.
  11. Two teams share one firmware, each has added mutexes, and you have now had two hangs that reproduce about once a week.

    What policy do you put in place?

    The strongest answer: One documented lock order everybody takes locks in, short critical sections, no blocking call while holding a lock, and a review rule that any new lock joins the order

    Why it works: Exactly — circular wait is the condition you can design away, and a written order plus a review rule is how it stays away.

    • Remove circular wait by design.
    • Write one global lock order.
    • No blocking calls while holding a lock.
    • Every new lock joins the order.
  12. What does a staff engineer pin on the wall for a control product?

    The strongest answer: A worst-case budget with owners for each steal — I do not keep it in one person’s head

    Why it works: Exactly. Owned steals. Slogans and invented percentiles are décor.

    • Worst-case budget, named owners.
    • Not a demo mean.
    • Not a slogan.
    • No invented deadline percentile.