Ich versuche, einen einfachen Round-Robin-Scheduler für den Cortex-M mit dem CodeSourcery GCC-Toolchain zu schreiben. Mein Scheduler verwendet den SysTick, um nach Ablauf eines Zeitscheibens einen Interrupt auszulösen, und der Kontextwechsel findet im ISR statt. Um die Dinge einfach zu halten, verwende ich nur den Haupt-Stack-Zeiger (MSP) für alles.
Ich stecke fest bei der Bestimmung, wie das Laden des neuen Kontexts auf dem Cortex-M3 gehandhabt werden soll. Laut dem Cortex-M3 Technical Reference Manual (TRM) drückt der Prozess die PC, LR und Statusregister beim Eintritt in das ISR auf den aktuellen Stapel.
Wenn ich den Rest der Register drücke, um den Kontext der aktuellen Aufgabe zu speichern und einen neuen SP-Wert aus dem Steuerblock der nächsten Aufgabe zu laden, wie würde ich den Rest ihres Kontextes wiederherstellen?
Nach meinem Verständnis muss ich die Register, die ich drücke (sagen wir {r4-r11}), wieder herausnehmen und der Prozessor wird den Rest automatisch herausdrücken (einschließlich der Rückgabeadresse der neuen Aufgabe (LR) und Statusregister), wenn das ISR zurückkehrt. Ich nehme also an, dass ich nach Abschluss der Aufgabe einfach ein BX
ausführen muss, um die Aufgaben zu wechseln?
Hier steht, was im TRM steht:
Ausnahmerückgaben erfolgen, wenn eine der folgenden Anweisungen einen Wert von 0xFFFFFFFX in den PC lädt, wenn 1) POP/LDM, das das Laden des PC umfasst 2) LDR mit dem PC als Ziel 3) BX mit einem beliebigen Register.
Wie gehe ich vor, um den EXC_RETURN-Wert zu laden? Sollte ich ihn einfach auf den Stapel drücken (wie es angeblich hier macht)? Angenommen, ich habe die Register, die ich über Software gedrückt habe, wieder herausgenommen, wie geht der Cortex dann vor, um die Register, die er gespeichert hat, herauszudrücken? Im Allgemeinen, wie stellt man den Kontext einer Aufgabe wieder her?
Ich habe versucht, das TRM und andere ARM-Referenzen zu lesen, aber sie scheinen unklar zu sein.