Die Cortex-M3-interrupts kann ich für die Allgemeine Arbeit?
Hätte ich einige code, der ausgeführt werden muss als das Ergebnis einer bestimmten unterbrechen geht aus.
Möchte ich nicht ausführen, es in den Kontext der interrupt selbst, aber auch ich möchte es nicht ausführen, die in-thread-Modus.
Möchte ich starten Sie es eine Priorität, die niedriger ist als die high-level-interrupt, die ausgefällt seinen Betrieb, sondern auch eine Priorität, die höher als thread-Ebene (und einige andere interrupts als auch).
Ich glaube, ich muss verwenden Sie eine der anderen interrupt-Handler.
Welche sind die besten zu verwenden, und was der beste Weg, um aufrufen?
Im moment Plane ich nur auf die Verwendung der interrupt-Handler für einige Peripheriegeräte, dass ich nicht mit Sie und rufen Sie Sie durch setzen von bits direkt durch die NVIC, aber ich hatte gehofft es gibt eine bessere, eine weitere offizielle Weg.
Dank,
Du musst angemeldet sein, um einen Kommentar abzugeben.
ARM Cortex unterstützt eine sehr spezielle Art von Ausnahme genannt PendSV. Es scheint, dass Sie könnte diese Ausnahme genau das, um Ihre Arbeit zu erledigen. Praktisch alle präemptiven RTOSes für ARM Cortex verwenden PendSV zur Umsetzung der Kontext-switch.
Machen, damit es funktioniert, müssen Sie priorisieren PendSV low (0xFF schreiben, um die PRI_14 registrieren Sie sich in der NVIC). Sollten Sie auch priorisieren alle IRQs über die PendSV (schreiben niedrigeren zahlen in der jeweiligen Priorität-Register des NVIC). Wenn Sie bereit sind zu verarbeiten, die gesamte Nachricht auslösen, die PendSV von der high-priority ISR:
Den ARM-Cortex-CPU wird dann beenden Sie Ihre ESR-und alle anderen ISRs, die eventuell verdrängt wurden, und schließlich wird es tail-Kette, um die PendSV Ausnahme. Dies ist, wo Sie Ihren code für die Analyse der Nachricht verwendet werden soll.
Bitte beachten Sie, dass PendSV könnte verdrängt werden durch andere ISRs. Das ist alles schön und gut, aber müssen Sie natürlich schützen Sie alle gemeinsam genutzten Ressourcen, die von einem kritischen Abschnitt des Codes (kurz deaktivieren und aktivieren von interrupts). In ARM Cortex deaktiviert interrupts, die von der Ausführung __asm("cpsid ich") und aktivieren Sie unterbricht durch __asm("cpsie ich"). (Die meisten C-Compiler bieten integrierte intrinsische Funktionen oder Makros für diesen Zweck.)
Sind Sie mit einem RTOS? In der Regel diese Art der Sache, die behandelt werden würde, indem er eine hohe Priorität thread, bekommt signalisiert, um einige Arbeit zu tun, die durch den interrupt.
Wenn Sie nicht mit einem RTOS, müssen Sie nur ein paar Aufgaben, und die Arbeit begann von der interrupt ist nicht zu ressourcenintensiv, könnte es am einfachsten sein, dass Ihre hohe Priorität Arbeit in den Kontext der interrupt-handler. Wenn diese Bedingungen nicht halten, dann die Umsetzung, was du redest, wäre der start eines basic-multitasking-Betriebssystem. Das kann ein Interessantes Projekt in seinem eigenen Recht, aber wenn Sie schauen, um nur Ihre Arbeit erledigen, möchten Sie vielleicht zu prüfen, ein einfaches RTOS.
Da Sie erwähnt, dass einige Einzelheiten über die Arbeit, die Sie tun, hier ist ein überblick darüber, wie ich behandelt habe ein ähnliches problem in der Vergangenheit:
Für die Handhabung von empfangenen Daten über eine UART-eine Methode, die ich verwendet habe, wenn es mit einem einfacheren system, das nicht die volle Unterstützung für Multitasking (ie., die Aufgaben sind rund robined ich na einfach
while
Schleife) ist, um eine shared queue für Daten, die aus den empfangenen UART. Wenn ein UART-interrupt ausgelöst wird, das Lesen der Daten von der UART ist RDR (Receive Data Register) und in die queue gestellt. Der trick, um den Umgang mit diesem in der Weise, dass die queue-Zeiger nicht beschädigt ist, um gezielt die Warteschlange Zeiger flüchtig, und stellen Sie sicher, dass nur der interrupt-handler ändert der Zeiger tail und dass nur die 'Vordergrund' Aufgabe, das Lesen von Daten aus der Warteschlange geändert, der Kopf-Zeiger. Ein high-level-übersicht:Produzent (der UART-interrupt-handler):
queue.head
undqueue.tail
in einheimischen;queue.tail
Zeiger). Wickeln Sie es an den Anfang der Warteschlange, Puffer, wenn Sie schon erhöht, nach dem Ende der Warteschlangen-Puffer.local.tail
undlocal.head
- wenn Sie gleich sind, wird die Warteschlange voll ist, und Sie haben zu tun, was die Fehlerbehandlung sinnvoll ist.local.tail
PunkteVerbraucher (Vordergrund 'task')
queue.head
undqueue.tail
in einheimischen;local.head
==local.tail
die queue leer ist; zurückkehren zu lassen, die nächste Aufgabe zu tun, einige arbeitenlocal.head
local.head
und wickeln Sie es, wenn nötig;queue.head
=local.head
Stellen Sie sicher, dass
queue.head
undqueue.tail
sindvolatile
(oder schreiben Sie diese bits in Assembler), um sicherzustellen, gibt es keine Sequenzierung Probleme.Jetzt nur noch darauf achten, dass deine UART empfangenen Daten-queue ist groß genug, dass Sie ' ll halten alle bytes werden konnte empfangen, bevor der Vordergrund-task bekommt eine chance, zu laufen. Der Vordergrund-task muss ziehen Sie die Daten aus der Warteschlange in einen eigenen Puffer aufbauen, die Nachrichten zu geben, auf die 'message processor' Aufgabe.
Den "offiziellen Weg" oder eher die konventionelle Methode ist die Verwendung eines prioritätsbasierten präemptiven multi-tasking-scheduler und die "latente interrupt-handler' Muster.
Was Sie fordern ist ziemlich einfach, auf dem Cortex-M3. Sie benötigen, um das RÜHREN zu registrieren, damit Sie auslösen können, die low-priority ISR mit der software. Wenn der high-priority ISR gemacht wird mit dem kritischen Sachen, nur es löst das low-priority-interrupt-und-Ausfahrten. Der NVIC wird dann tail-Kette in den low-priority-handler, wenn es nichts mehr wichtiges passiert.
Überprüfen Sie Ihre Prozessor-Dokumentation. Einige Prozessoren unterbrechen, wenn Sie schreiben, das bit, die Sie in der Regel klar innerhalb der interrupt. Ich bin derzeit mit einem SiLabs c8051F344 und in dem Datenblatt, Abschnitt 9.3.1:
"Software simulieren kann ein interrupt durch Einstellung von interrupt-pending-flag auf logisch 1. Wenn interrupts aktiviert sind, für die Flagge, eine interrupt-Anforderung erzeugt wird und die CPU-Vektor in den ISR-Adresse im Zusammenhang mit der interrupt-pending-flag."