Verwenden Sie ein RTOS? Im Allgemeinen würde diese Art von Sache gehandhabt werden, indem man einen Thread mit hoher Priorität hat, der signalisiert wird, etwas Arbeit durch den Interrupt zu machen.
Wenn Sie kein RTOS verwenden, haben Sie nur wenige Aufgaben, und die Arbeit, die durch den Interrupt ausgelöst wird, ist nicht zu ressourcenintensiv. Es kann am einfachsten sein, Ihre Arbeit mit hoher Priorität im Kontext von der Unterbrechungshandler. Wenn diese Bedingungen nicht erfüllt sind, dann wäre das Implementieren, von dem Sie sprechen, der Beginn eines grundlegenden Multitasking-Betriebssystems selbst. Das kann ein interessantes Projekt sein, aber wenn Sie nur Arbeit erledigen wollen, sollten Sie ein einfaches RTOS in Betracht ziehen.
Da Sie einige Besonderheiten über die Arbeit erwähnt Sie tun, ist hier ein Überblick darüber, wie ich ein ähnliches Problem in der Vergangenheit behandelt haben:
Für die Handhabung empfangenen Daten über eine UART eine Methode, die ich habe verwendet, wenn es sich um ein einfacheres System handelt, das keine volle Unterstützung für das Tasking hat (dh die Tasks sind in einer einfachen while
-Schleife round-robined), um eine gemeinsame Warteschlange für Daten zu haben, die vom UART empfangen werden. Wenn ein UART-Interrupt ausgelöst wird, werden die Daten vom RDR (Receive Data Register) des UART gelesen und in die Warteschlange gestellt. Der Trick, dies so zu behandeln, dass die Warteschlangenzeiger nicht beschädigt sind, besteht darin, die Warteschlangenzeiger vorsichtig flüchtig zu machen und sicherzustellen, dass nur der Interrupt-Handler den Endzeiger und nur die Vordergrundaufgabe, die Daten liest, modifiziert Aus der Warteschlange wurde der Kopfzeiger geändert. Ein High-Level-Übersicht:
Vergewissern Sie sich, dass queue.head
und queue.tail
volatile
sind (oder diese Bits in der Montage schreiben), um sicherzustellen, dass keine Sequenzierung Probleme gibt.
Jetzt stellen Sie nur sicher, dass Ihre UART empfangen Datenwarteschlange groß genug ist, dass es alle Bytes enthalten wird, die empfangen werden konnten, bevor die Vordergrundaufgabe eine Chance bekommt, zu laufen. Die Vordergrundaufgabe muss die Daten aus der Warteschlange in ihre eigenen Puffer ziehen, um die Nachrichten aufzubauen, die der Aufgabe "Nachrichtenprozessor" übergeben werden sollen.
Danke, Miro! Ich habe überall nach Informationen darüber gesucht, wie ich den PendSV-Interrupt auslösen kann, und hier habe ich ihn endlich gefunden! Auch wenn ich mein Cortex M3 r1p1 Technisches Referenzhandbuch sorgfältiger gelesen hätte, hätte ich es auf der Seite gefunden, die das Interrupt Control State Register beschreibt: http://infocenter.arm.com/help/topic/com.arm .doc.ddi0337e/DDI0337E_cortex_m3_r1p1_trm.pdf –
Aus meiner Sicht verwenden fast alle RTOS auf CortexM3 den Systick Timer Interrupt (45 dezimal, 2D hex), um ihren Scheduler zu starten. Dann ist der PendSV der Weg, um eine Art besonderen "Syscall" zu initiieren? Hoffe ich verstehe das. –
@WarrenP: PendSV wird verwendet, um den Kontextwechsel tatsächlich zu behandeln. Der System-Tick wird zum Round-Robin-Task verwendet - sys tick setzt wiederum PendSV. –