Skip to content

Commit

Permalink
feat: finished critical-section docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin-Niederman committed Apr 25, 2024
1 parent 053bedd commit 66b4942
Showing 1 changed file with 27 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/vexide/technical/critical-section.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,33 @@ What this means is that nothing can interrupt the flow of our code and mess with

The first step that vexide takes when entering the critical section is checking if interrupts are already disabled.
```rust
let mut cpsr: u32;
asm!("mrs {0}, cpsr", out(reg) cpsr);
let masked = (cpsr & 0b10000000) == 0b10000000;
let mut cpsr: u32;
asm!("mrs {0}, cpsr", out(reg) cpsr);
let masked = (cpsr & 0b10000000) == 0b10000000;
```
This block of code moves the value of the ``cspr`` register into the cspr variable and then checks if the 7th bit is a 1.
If it is 1, IRQ interrupts are masked.
It is important to know if interrupts are masked because nested critical sections shouldn't re-enable interrupts if an inner section is exited.
It is important to know if interrupts are masked because nested critical sections shouldn't re-enable interrupts if an inner section is exited.

Next, we actually disable interrupts.
```asm
// Disable IRQs
cpsid i
// Synchronization barriers
dsb
isb
```
The synchronization barriers shown here are taken from the PROS FreeRTOS implementation.

When exiting the critical section, we first check if interrupts were disabled when the critical section was entered.
This is where checking the value of cspr register comes into play.
We run this assembly if the interrupts were disabled.
It re-enables IRQ interrupts
```asm
// Re-enable IRQs
cpsie i
// Synchronization barriers
dsb
isb
```
Again the sychronization barriers are taken from PROS.

0 comments on commit 66b4942

Please sign in to comment.