← Back

This preview is the content that will print. Choose “Save as PDF” in your browser’s print dialog to make a PDF.

Metatransformer report

Interrupts and cooperative scheduling

Practice · 60 minutes · Keep interrupt service bounded and move substantial work into a scheduled main context so latency remains explainable.

Text report: images and diagrams are omitted, and links to project files are inactive. Keep the exported project alongside this PDF for wiring diagrams, models, and linked files.

Learning outcomes

  • Partition event capture from deferred processing, estimate utilization and worst-case latency, and diagnose interrupt overload or shared-state races.

Prerequisites

  • programming-state
  • data-structures
  • timers-pwm

Concepts

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.

Worked example

Problem

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.

Steps

  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.

Result

The two ISRs consume about 8.76% of one CPU second under the stated rates, leaving 91.24% nominally for other execution.

Sanity check

Both loads are below 10% individually and their time totals, 87,600 µs, are 0.0876 of 1,000,000 µs.

Check your understanding

A GPIO interrupt currently parses JSON and prints a message before returning. Events are being lost. What is the best redesign?

A. Increase the JSON document size inside the ISR B. Capture a compact event or increment a counter in the ISR, then parse and print in scheduled main code C. Disable all other interrupts permanently D. Add a blocking delay to ensure each message finishes

Your answer: ______________________________

Reasoning:



Answer key

ANSWER KEY — check only after attempting the question.

B. Capture a compact event or increment a counter in the ISR, then parse and print in scheduled main code

Compact capture shortens the preempting path and lets ordinary code handle variable-duration work. Larger parsing, permanent interrupt disabling, and delays all increase blind time. A queue still needs explicit capacity and overflow behavior, but it separates timing-critical capture from expensive processing.

Hands-on lab

Goal

Compare interrupt event capture with deferred reporting and expose the failure caused by slow ISR work.

Equipment

  • Microcontroller
  • button or signal jumper
  • serial console
  • logic analyzer optional

Procedure

  1. Configure a low-rate falling-edge interrupt that increments a counter and stores the latest timestamp.
  2. Every 100 ms in the main loop, copy and print the count plus elapsed time; document how the snapshot is protected.
  3. Generate ten deliberate edges with a jumper or debounced source and compare generated versus reported count.
  4. 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.
  5. Add a bounded event queue or counter overflow indicator and force its limit at a safe synthetic rate.

What to 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.

Transfer challenge

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.

Cautions

  • Use only logic-level sources sharing a valid ground; do not connect unknown camera flash, automotive, or appliance signals directly to a GPIO.

Evidence record

Learner: ____________________ Date: ____________________

Evidence artifact or file: ____________________________________________

ItemRecord
Prediction or expected result
Actual observation or measurement
Conditions and tools used
Difference from expectation
Next decision or follow-up

Notes:




Sources and references

  1. MicroPython RP2 quick reference (opens in a new tab)
  2. Arduino Blink Without Delay (opens in a new tab)