Skip to content

runtime: use MSP/PSP registers for scheduling on Cortex-M#741

Merged
deadprogram merged 1 commit into
devfrom
scheduler-msp-psp
Nov 23, 2019
Merged

runtime: use MSP/PSP registers for scheduling on Cortex-M#741
deadprogram merged 1 commit into
devfrom
scheduler-msp-psp

Conversation

@aykevl

@aykevl aykevl commented Nov 19, 2019

Copy link
Copy Markdown
Member

The Cortex-M architecture contains two stack pointers, designed to be used by RTOSes: MSP and PSP (where MSP is the default at reset). In fact, the ARM documentation recommends using the PSP for tasks in a RTOS.

This commit switches to using the PSP for goroutine stacks. Aside from being the recommended operation, this has the big advantage that the NVIC automatically switches to the MSP when handling interrupts. This avoids having to make every goroutine stack big enough that interrupts
can be handled on it.

Additionally, I've optimized the assembly code to save/restore registers (made possible by this change). For Cortex-M3 and up, saving all registers is just a single push instruction and restoring+branching is a single pop instruction. This results in a small code size improvement and probably a speed improvement as well (untested).

Sidenote: the fact that you can pop a number of registers and branch at the same time makes ARM not exactly a true RISC system. However, it's very useful in this case.

@deadprogram I think you may want to test this PR on some of your demos, to make sure it doesn't break anything important.

@aykevl

aykevl commented Nov 20, 2019

Copy link
Copy Markdown
Member Author

Tweaked the assembly a little bit to be a bit shorter (and possibly more efficient) on Cortex-M0.

The Cortex-M architecture contains two stack pointers, designed to be
used by RTOSes: MSP and PSP (where MSP is the default at reset). In
fact, the ARM documentation recommends using the PSP for tasks in a
RTOS.

This commit switches to using the PSP for goroutine stacks. Aside from
being the recommended operation, this has the big advantage that the
NVIC automatically switches to the MSP when handling interrupts. This
avoids having to make every goroutine stack big enough that interrupts
can be handled on it.

Additionally, I've optimized the assembly code to save/restore registers
(made possible by this change). For Cortex-M3 and up, saving all
registers is just a single push instruction and restoring+branching is a
single pop instruction. For Cortex-M0 it's a bit more work because the
push/pop instructions there don't support most high registers.

Sidenote: the fact that you can pop a number of registers and branch at
the same time makes ARM not exactly a true RISC system. However, it's
very useful in this case.
@deadprogram

Copy link
Copy Markdown
Member

Will start testing this over the next couple of days.

@deadprogram

Copy link
Copy Markdown
Member

Ended up having some time here at the airport to do some testing, and had several M0 and M4 boards with me. I have run this branch against several of my most complex demos and worked flawlessly.

Merging, great work @aykevl

@deadprogram deadprogram merged commit 3d3e481 into dev Nov 23, 2019
@aykevl aykevl deleted the scheduler-msp-psp branch November 23, 2019 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants