Interrupts and cooperative scheduling
Keep interrupt service bounded and move substantial work into a scheduled main context so latency remains explainable.
- Partition event capture from deferred processing, estimate utilization and worst-case latency, and diagnose interrupt overload or shared-state races.
Understand
The working idea
An interrupt lets hardware tap the processor on the shoulder when an event occurs. It can capture a timestamp for a wheel edge or note that a byte arrived without making the main loop poll constantly. The interrupt service routine, or ISR, temporarily preempts ordinary code. That convenience creates a timing debt: while one ISR runs, lower-priority work may wait.
The robust pattern is “capture, signal, defer.” The ISR records the minimum data needed—perhaps a counter or timestamp—sets a flag, and returns. The main loop later copies that state and performs formatting, filtering, display updates, or communication. If events arrive at rate r and each ISR consumes execution time C, interrupt utilization is U = rC. At 2,000 events/s and 20 µs each, U = 0.04, or 4%. Average utilization is not enough: bursts, disabled-interrupt sections, priorities, and the longest non-preemptible work determine worst-case latency.
Shared data can change between two main-loop instructions. An increment or multi-byte timestamp may not be atomic on every processor. A brief documented critical section or a single-producer/single-consumer queue can create a consistent snapshot. The build decision for an encoder is often to count edges in the ISR and compute speed every 20 ms in the scheduler, not to print from each edge.
A common misconception is that interrupts make code instantaneous. They only change who waits. Long ISRs, dynamic allocation, blocking I/O, and serial prints can lose subsequent events or starve control work. Another failure is attaching a mechanical button interrupt without handling contact bounce, producing many edges per press. Use interrupts when latency or event capture justifies them; periodic polling is often simpler and more testable for slow human inputs. State an overflow policy when a queue cannot absorb a burst.
Follow the reasoning
Worked example
An encoder can produce 4,800 edges/s. Its ISR takes 12 µs, and a 1 ms timer ISR takes 30 µs each tick. Estimate total interrupt CPU utilization.
- 1
Encoder load = 4,800/s × 12 µs = 57,600 µs/s = 5.76%.
- 2
Timer load = 1,000/s × 30 µs = 30,000 µs/s = 3.00%.
- 3
Total nominal interrupt utilization = 8.76%, before entry overhead, bursts, or critical sections.
The two ISRs consume about 8.76% of one CPU second under the stated rates, leaving 91.24% nominally for other execution.
Sanity checkBoth loads are below 10% individually and their time totals, 87,600 µs, are 0.0876 of 1,000,000 µs.
Try it yourself
Independent check
Move to the bench
Compare interrupt event capture with deferred reporting and expose the failure caused by slow ISR work.
- Microcontroller
- button or signal jumper
- serial console
- logic analyzer optional
Experiment
- Configure a low-rate falling-edge interrupt that increments a counter and stores the latest timestamp.
- Every 100 ms in the main loop, copy and print the count plus elapsed time; document how the snapshot is protected.
- Generate ten deliberate edges with a jumper or debounced source and compare generated versus reported count.
- Introduce a deliberate fault by adding a conspicuously slow operation in the ISR only long enough for a controlled low-voltage test; observe missed events or latency, then remove it.
- Add a bounded event queue or counter overflow indicator and force its limit at a safe synthetic rate.
Observe
- Expected: the short ISR captures all slow deliberate edges and printing occurs on the scheduler’s cadence.
- Record actual generated and captured counts and timestamp spread; do not infer zero loss without comparing them.
- Expected fault signature: slow ISR work increases response latency and may reduce captured count; exact loss depends on hardware and rate.
Partition a camera-trigger input into ISR work, queued data, and main-loop processing, including what happens if triggers arrive faster than images can be handled.
- Use only logic-level sources sharing a valid ground; do not connect unknown camera flash, automotive, or appliance signals directly to a GPIO.
Keep evidence
Bench note
Record what you expected, what you actually measured or observed, and one difference worth investigating. This is self-reported evidence, not a certification.