Core Topics route · TFA-103

Interrupts, Timing & Concurrency

Reason about asynchronous events, deadlines and shared state without allowing race conditions or hidden timing assumptions to govern the design.

Intermediate7 min reading + 25 min practiceWorked example

← Back to the learning library

Before you begin: TFA-102 and basic understanding of interrupt handlers and an RTOS.

Reading time and practice time are estimates. Examples use fictional products and illustrative engineering values, not approved product limits.

Learning objectives

By the end of this module, you should be able to:

  • Set clear responsibilities and budgets for interrupt handlers.
  • Recognise races, deadlocks, starvation and priority inversion.
  • Select communication and synchronisation mechanisms deliberately.
  • Measure and justify worst-case timing behaviour.

Lesson 1

1. Interrupts capture urgency, not application logic

An interrupt service routine should acknowledge the source, capture the minimum volatile information and defer substantial work. Long handlers increase latency for other interrupts and make worst-case response difficult to bound. Calling a general-purpose driver, formatter or allocator from an ISR can introduce hidden blocking or non-reentrancy.

Record which APIs are interrupt-safe and which interrupt priority levels may call operating-system services.

Lesson 2

2. Shared state is a design decision

Whenever two execution contexts access the same mutable object, define how atomicity and ordering are achieved. Volatile tells a compiler that a value can change unexpectedly; it does not make a compound operation atomic and does not establish inter-core or task ordering.

Prefer message passing and single ownership. When sharing is unavoidable, use short critical sections, atomics or a well-defined lock. State the protected invariant, not merely the chosen primitive.

Lesson 3

3. Analyse the failure modes of synchronisation

  • Race: the result depends on interleaving.
  • Deadlock: contexts wait permanently for each other.
  • Starvation: a context never receives sufficient service.
  • Priority inversion: urgent work waits behind lower-priority ownership.

Consistent lock ordering, bounded hold times and priority-inheritance mechanisms address different problems; none is a universal cure.

Lesson 4

4. Timing evidence combines analysis and measurement

Define deadlines at the product boundary, allocate budgets to activities and measure on representative hardware under stress. Include interrupt nesting, cache effects, DMA, communication bursts and error paths. Average execution time is rarely the safety-relevant quantity; seek a defensible worst case with margin.

Lesson 5

5. Build an end-to-end response budget

A physical response includes sensor delay, interrupt latency, sample transfer, processing, scheduling interference and actuator delay. Measuring one function does not establish the complete deadline. Define the start and stop observation points before selecting instrumentation.

Suppose an illustrative response limit is 5 ms. Sensor conversion uses 0.8 ms, worst interrupt delay 0.2 ms, queue wait 1.0 ms, processing 0.6 ms and output settling 0.9 ms. The allocated total is 3.5 ms, leaving 1.5 ms for other interference and margin. This is a budget to verify, not proof that any component achieves it.

For fixed-priority tasks, consider execution time, blocking and interference from higher-priority work. Response-time analysis must match the actual scheduling model and assumptions. An average CPU-load graph cannot reveal the critical phasing of a rare interrupt burst.

Lesson 6

6. Distinguish atomicity, visibility and ownership

Atomicity means an operation cannot be observed partly completed. Visibility and ordering concern when one execution context observes another context’s updates. Ownership decides who is allowed to change an object. A design needs all three; choosing an atomic index does not automatically make every buffer operation safe.

A single-producer/single-consumer ring can be efficient if the producer writes the payload before publishing the new head and the consumer finishes reading before releasing space. The required ordering depends on compiler, CPU and memory system. Use the platform’s supported primitives and verify their interrupt and lock-free properties; do not assume a language atomic is suitable in every ISR.

DMA introduces another participant. On a cached system, a buffer may need cache maintenance, memory barriers or a non-cacheable region according to the processor contract. A mutex used by tasks does not stop DMA from modifying memory.

Lesson 7

7. Measure without hiding the problem

Instrumentation consumes time and may serialise otherwise concurrent operations. Compare a GPIO timing trace, hardware timer capture and software event trace where useful. Record clock configuration, optimisation, cache state, logging and debugger conditions with the measurement.

Failure mechanismTargeted experiment
Priority inversionHold a low-priority lock while urgent work becomes ready.
Queue overflowPause the consumer during maximum credible producer bursts.
Interrupt maskingTrigger the event at the longest protected region.
DMA coherencyExercise alternating buffers across cache-line boundaries.

Retain the worst observed value and the test conditions, but distinguish an observed maximum from an analytically justified upper bound. Explain what untested condition could make the result worse.

Decision guide

How should an ISR pass samples to processing?

MechanismAdvantageConstraint
Single-producer ring bufferLow overhead and preserves samples.Overflow policy and atomic indices required.
RTOS queueClear ownership and blocking semantics.Only use ISR-safe API; bounded capacity.
Shared latest valueVery simple when only newest value matters.Intermediate samples are deliberately lost.

Worked example

Worked example — 1 kHz sensor acquisition

Problem

An ADC interrupt produces a sample every millisecond while a task filters data and a communications task transmits summaries.

Engineering approach

The ISR timestamps and pushes each sample into a fixed ring buffer. The processing task owns the consumer index and detects overflow. It publishes a summary through a queue. The communications task never touches ADC state. Tests inject maximum communications traffic and delayed processing.

Result

Ownership is explicit, ISR time is bounded, overflow is observable and the sampling deadline can be verified independently of transmission load.

Engineering evidence

What should the work produce?

Execution-context table

Lists tasks, interrupts, priorities and call restrictions.

Shared-resource analysis

Identifies ownership, invariants and protection.

Timing budget

Allocates end-to-end deadlines to components.

Stress-test report

Records measured latency, jitter and margin.

Common failure patterns

What goes wrong?

  • Using volatile as a concurrency strategy.
  • Disabling interrupts around an unbounded operation.
  • Dynamic allocation inside timing-critical paths.
  • Reporting average timing when a deadline depends on the maximum.

Applied exercise · approximately 25 minutes

Size a sample queue and test the assumptions

A producer supplies 1,000 samples/s. The consumer may be unavailable for 12 ms, then processes at 2,000 samples/s. Assume an initially empty queue and a possible extra sample at the interval boundary.

  1. Calculate the backlog accumulated during the pause and choose a usable queue capacity with a stated margin.
  2. Estimate drain time while production continues.
  3. Specify what happens if a second pause occurs before the first backlog is cleared.
Review a suggested approach

The pause creates approximately 12 samples, or 13 with the stated boundary allowance. A usable capacity of 16 leaves three entries beyond that model; it is an illustrative choice, not a universal rule. A ring implementation that reserves an empty slot needs 17 storage entries to provide 16 usable entries.

Net draining is 1,000 samples/s because new samples still arrive. Clearing a backlog of 13 therefore takes about 13 ms. Repeated pauses can invalidate the empty-queue assumption. Define overflow detection and the required data-validity or safe-response policy, then stress the recurring pattern rather than testing one isolated pause.

Completion criteria

  • Capacity uses usable entries and includes the boundary assumption.
  • Drain time includes continued production.
  • Overflow is observable and has a defined product response.

This is a self-directed engineering exercise, not an accredited examination. Compare the rationale as well as the final answer.

Practical check

Questions for your next design review

  • Is every ISR short, bounded and limited to approved calls?
  • Is every shared mutable object identified?
  • Are queue-full and buffer-overrun behaviours specified?
  • Is lock ordering documented and checked?
  • Were timing measurements taken under credible worst-case load?
Key takeaway

Concurrency is manageable when execution contexts, ownership and deadlines are made explicit.

References and further reading

Educational guidance only. Apply the authorised standards editions, regulations and approved procedures relevant to your product and market. Linked publications support further study; the fictional exercises do not demonstrate compliance.