Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion mdbook/src/15-interrupts/README.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should explain further about proc macros here; it's a complicated concept in its own right. Maybe link to the Book of Macros?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I think maybe link to the Macros section in the Rust Book (which then itself links to the Book of Macros)?

From skimming these just now, while the Book of Macros mentions ways to expand macros (like the Playground option), they don't mention the rust-analyzer command.

I think maybe it is worth mentioning briefly how to expand macros, so that someone reading this can get a quick understanding of roughly what the interrupts macro does without having to learn Macro syntax.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I edited that bit now, what do you think?

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The model of computation used by our NRF52833 is the one used by almost every mo

Everything about the computation the CPU is currently running is stored in the CPU registers. If the core is going to switch tasks, it must store the contents of the CPU registers somewhere so that the new task can use the registers as its own scratch-pad. When the new task is complete the CPU can then restore the register values and restart the old computation. Sure enough, that is exactly the first thing the core does in response to an interrupt request: it stops what it's doing immediately and stores the contents of the CPU registers on the stack.

The next step is actually jumping to the code that should be run in response to an interrupt. An Interrupt Service Routines (ISR), often referred to as an interrupt "handler", is a special function in your application code that gets called by the core in response to interrupts. An "interrupt table" in memory contains an "interrupt vector" for every possible interrupt: the interrupt vector indicates what ISR to call when a specific interrupt is received. We describe the details of ISR vectoring in the [NVIC and Interrupt Priority] section.
The next step is actually jumping to the code that should be run in response to an interrupt. An Interrupt Service Routine (ISR), often referred to as an interrupt "handler", is a special function in your application code that gets called by the core in response to interrupts. An "interrupt table" in memory contains an "interrupt vector" for every possible interrupt: the interrupt vector indicates what ISR to call when a specific interrupt is received. We describe the details of ISR vectoring in the [NVIC and Interrupt Priority] section.

An ISR function "returns" using a special return-from-interrupt machine instruction that causes the CPU to restore the CPU registers and jump back to where it was before the ISR was called.

Expand All @@ -33,6 +33,9 @@ that this ISR should be stored at the entry for the `GPIOTE` interrupt in the in
The `#[interrupt]` decoration is used at compile time to mark a function to be treated specially as
an ISR. (This is a "proc macro", in case you feel like exploring that concept.)

Essentially, a "proc macro" translates source code into other source code. If you are curious as to exactly what happens,
you could view the macro's definition. You can also expand any particular macro invocation using either the Tools in the [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024) or use the "rust-analyzer: Expand macro" command in your IDE.

Marking a function with `#[interrupt]` implies several special things about the function:

* The compiler will check that the function takes no arguments and returns no value. The CPU has no
Expand Down