You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: mdbook/src/15-interrupts/README.md
+12-11Lines changed: 12 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ The model of computation used by our NRF52833 is the one used by almost every mo
14
14
15
15
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.
16
16
17
-
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.
17
+
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.
18
18
19
19
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.
20
20
@@ -31,21 +31,20 @@ The ISR handler function is "special". The name `GPIOTE` is required here, indic
31
31
that this ISR should be stored at the entry for the `GPIOTE` interrupt in the interrupt table.
32
32
33
33
The `#[interrupt]` decoration is used at compile time to mark a function to be treated specially as
34
-
an ISR. (This is a "proc macro", in case you feel like exploring that concept.)
34
+
an ISR. (This is a "proc macro": you can read more about it in the [Rust book] if you wish.)
35
35
36
-
Marking a function with `#[interrupt]` implies several special things about the function:
36
+
Essentially, a "proc macro" translates source code into other source code. If you are curious as to what any particular macro use translates into,
37
+
you could expand that macro invocation. You can do this by using either the Tools in the [Rust Playground] or the "rust-analyzer: Expand macro" command in your IDE.
37
38
38
-
* The compiler will check that the function takes no arguments and returns no value. The CPU has no
39
-
arguments to provide to an ISR, and no place to put a return value from the ISR.
39
+
Marking a function with `#[interrupt]` implies several special things about the function:
40
40
41
-
* The compiler will place a vector to this function at the location in the interrupt table
42
-
implied by the function's name.
41
+
* The compiler will check that the function takes no arguments and returns no value (or never returns). The CPU has no
42
+
arguments to provide to an ISR, and no place to put a return value from the ISR. This is because interrupt handlers have their own call stack (at least *conceptually* if not always in practice).
43
43
44
-
*The function will be compiled to finishing by using a return-from-interrupt instruction rather
45
-
than the normal function return instruction.
44
+
*A vector to this function (that is a function pointer) will be placed at the location in the interrupt table
45
+
which corresponds to the function's name.
46
46
47
-
* Since the function finishes in a non-standard way, the compiler will understand not to allow
48
-
directly calling the ISR from normal code.
47
+
* The compiler will prevent directly calling the ISR from normal code.
49
48
50
49
There are two steps to configure the interrupt. First, the GPIOTE must be set up to generate an
51
50
interrupt when the pin connected to Button A goes from high to low voltage. Second, the NVIC must be
@@ -72,3 +71,5 @@ Normally, once an ISR is complete the main program continues running just as it
72
71
73
72
[NVIC and Interrupt Priority]: nvic-and-interrupt-priority.html
Copy file name to clipboardExpand all lines: mdbook/src/15-interrupts/nvic-and-interrupt-priority.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,6 +30,8 @@ Preemption allows processors to respond very quickly to critical events. For ex
30
30
31
31
If an equal-priority or lower-priority interrupt occurs during an ISR, it will be "pended": the NVIC will remember the new interrupt and run its ISR sometime after the current ISR completes. When an ISR function returns the NVIC looks to see if, while the ISR was running, other interrupts have happened that need to be handled. If so, the NVIC checks the interrupt table and calls the highest-priority ISR vectored there. Otherwise, the CPU returns to the running program.
32
32
33
+
Note that if interrupts are disabled entirely, all incoming interrupts will be pended. Pending interrupts will be handled once interrupts are enabled again.
34
+
33
35
In embedded Rust, we can program the NVIC using the [`cortex-m`] crate, which provides methods to
34
36
enable and disable (called `unmask` and `mask`) interrupts, set interrupt priorities, and trigger
35
37
interrupts from software. Frameworks such as [RTIC] can handle NVIC configuration for you, taking
0 commit comments