Skip to main content

24 docs tagged with "interrupts"

View all tags

Buses & I/O — Overview

A CPU, RAM, storage, and peripherals are separate physical chips — a bus is the shared electrical

Deferred Work

"Keep your ISRs short" is the most repeated piece of firmware advice and the least actionable, because it never says short compared to what. The useful form is a consequence of how the NVIC works rather than a style preference: every microsecond a handler runs is a microsecond added to the worst-case latency of every interrupt at the same or a less urgent priority. A 200 µs handler is not "a bit slow". It is a 200 µs latency tax levied on most of the system, paid every time that handler runs, and it does not appear in any register you can read.

Exceptions and the Vector Table

On most processors, getting from "an interrupt line went high" to "my C function is running" involves software: a dispatcher reads a status register, works out which source fired, and calls the right handler. Cortex-M does none of that. The hardware reads a table of function pointers at a known address, indexes it by exception number, and branches — having already pushed the registers a C function is allowed to clobber. Your handler is an ordinary function with an ordinary prologue, and it starts running a fixed and small number of cycles after the event.

Hard IRQ Context and Its Rules

What a handler may not do, why each rule follows from the context, and the pressure that creates the rest of the folder.

Interrupt Affinity

/proc/interrupts read column by column, MSI-X vectors per queue, and why pinning an interrupt near its consumer matters.

Interrupt Controllers

The hardware between a device asserting a line and a CPU taking an interrupt: PIC, APIC, MSI, and Arm's GIC.

Interrupt Latency

Ask what the interrupt latency of a Cortex-M4 is and you get "12 cycles", which is true and almost never the number you need. Twelve cycles is what the processor contributes when the memory is instant, nothing else is running, and the exception arrives at a convenient moment. The number that decides whether your product works is the one measured from the event at the pin to the first instruction of your handler that does something about it — and on a real board, at a real clock, with the rest of your firmware present, that number is dominated by things the core designer had no say in.

ISR-Safe APIs

Every kernel object in the previous six pages — the ready lists, the delayed list, each queue's two event lists, each mutex's holder field — is an ordinary linked list in RAM, and the kernel keeps it consistent by the only means a single-core Cortex-M offers: it masks interrupts around the update. That is the entire content of taskENTER_CRITICAL(). So a kernel API is not "thread-safe code" in the hosted sense; it is code that assumes nothing else on this core is running while it edits the list.

Polling, Interrupt, or DMA

There are exactly three ways to get a byte out of a peripheral register and into your program's memory. The CPU can ask repeatedly until the answer is yes. The peripheral can raise a line that makes the CPU stop what it was doing. Or a second bus master can do the load and the store on the CPU's behalf and tell it afterwards. Every driver you will ever write picks one of these, and the choice is made badly far more often than it is made wrong — badly, meaning by reflex rather than from a budget.

Priorities and Nesting

Every interrupt on a Cortex-M comes out of reset at priority 0 — the most urgent level there is. A program that enables six interrupts and never calls NVIC_SetPriority has six handlers that all sit at the top, none of which can pre-empt any other, serviced in exception-number order when several arrive at once. That configuration is not "no priority scheme". It is a specific, and usually wrong, priority scheme: it says every interrupt in the system is equally urgent and none may interrupt another, which means the worst-case latency of your fastest deadline is the sum of every other handler's execution time.

Softirqs

The fixed set, why it is fixed, the budget that stops it starving everything else, and the si column in top.

The NVIC

The vector table answers where. The Nested Vectored Interrupt Controller answers whether, when, and in what order — and it is the only part of the exception model you actively program. Every interrupt line on the chip arrives at the NVIC; the NVIC decides whether that line is enabled, records it as pending if it is not yet serviceable, compares its priority against whatever the processor is currently doing, and hands the winner to the core.

Threaded IRQs

A quick primary handler plus a schedulable thread, and why PREEMPT_RT makes nearly every handler threaded.

Timekeeping and Clocksources

How a clocksource is chosen, what each CLOCK* actually measures, and the lockless read path behind clockgettime.

Workqueues

Deferred work in process context, so it may sleep — plus the cancel-versus-free lifetime bug everyone writes once.

Writing Interrupt Handlers in C

An interrupt handler is the only function in your program that nothing calls. You write it, you never reference it, and yet it runs — sometimes millions of times a second, at a moment you did not choose, on top of whatever the main program happened to be doing. That inversion is the whole difficulty. Every rule below follows from it: you cannot pass arguments to something nobody calls, you cannot return a value to nobody, and you cannot assume anything about the state of the code you interrupted.