STM32 Software Interrupt auf Variable

OP #2170604
Lesenswert?

Hi, Jungs

kennt einer ne Möglichleit beim STM32 ein Flag oder eine Variable zu 
überwachen sodass falls sich diese ändert eine ISR gerufen wird?


Ich hatte schon das Software trigger interrupt register (NVIC_STIR)
gefunden allerding weiß ich nicht wie ich es anwenden soll und wie ich 
dem Register mitteile das er meine Variable überwachen soll.

Geht sowas überhaupt?

Falls jetzt fragen kommen warum ich sowas machen will:

In einer USART ISR schreibe ich in ein Array, sobald die Daten (eine 
definierte Zeichekette variabler Länge (<$>...<CR><LF>)) fertig sind 
müssen diese verarbeitet werden.
Wenn ich jetzt einfach nur eine Funktion rufe, welche die Daten 
verarbeitet, dann verpasse ich unter Umständen weitere Daten, weil die 
ISR noch nicht abgeschlossen ist. Darum will ich eine weitere ISR 
aufrufen, welche sich quasi unanhängig / parallel um die 
Datenverarbeitung kümmert. ohne die USART ISR zu blokieren.


Weitere Infos:
STM32F107
OpenOCD

Hoffe ihr könnt mir weiter helfen.

Gruß
Sascha
Persönliche Seite #2170613
Lesenswert?

Hi,

du kannst nen Watch setzen im Debugger.
Der CM3 hat eine DWT, dort kann der bis zu 4 Speicheradressen auf 
Änderung "beobachten".
Willst du auch noch nen Vergleich auf >, <, = machen, brauchts zwei 
dieser Einheiten pro Adresse.

Im Keil µVision, Command Window:
BS READ myVar;
BS WRITE myVar;
BS READWRITE myVar = 0x55;

Anderer Ansatz:
RTOS!

Gnu & OpenXXX kann ich leider nicht mit Antworten dienen ...


VG,
/th.
Gast #2170651
Lesenswert?

Sascha P. schrieb:
> In einer USART ISR schreibe ich in ein Array, sobald die Daten (eine
> definierte Zeichekette variabler Länge (<$>...<CR><LF>)) fertig sind
> müssen diese verarbeitet werden.

1. Das klingt, als ob das nicht in einer Schleife gemacht wird, sondern 
die Daten irgendwoher kommen.
2. 'Irgendjemand' muss doch das <CR><LF> anhängen, kann 'der' nicht die 
Sende-ISR freischalten?
Gast #2170752
Lesenswert?

Kannst du nicht einfach in der USART-ISR ein Flag setzen, sobald ein 
CR/LF erkannt wird?
Die Verarbeitungsfunktion wird dann aus dem Mainloop aufgerufen falls 
das Flag gesetzt ist. Dabei muss aber sichergestellt werden, dass der 
nächste USART-Interrupt nicht Teile des Arrays überschreibt, bevor die 
nicht fertig verarbeitet sind.
Gast #2170780
Lesenswert?

Irgendwie scheint das Konzept Murks zu sein.
Hänge zwischen ISR und AppCode einen SW-Ringpuffer. Wenn diene ISR <LF> 
erkennt, kann sie ja ein Flag setzen. Zwischendurch kommt ja immer dein 
AppCode dran, der dann auf das Flag pollt und es u.U. zurücksetzt.
Gast #2171001
Lesenswert?

Arne schrieb:
> Irgendwie scheint das Konzept Murks zu sein.

Ich wollt's so nicht sagen...

Es muss nicht unbedingt ein Ringpuffer sein.
Daten in 'Daten-Sammel-ISR' in Eingabepuffer schreiben. Wenn fertig, 
Fähnchen hissen. Im Mainloop Flagge auswerten. Interrupts sperren, Daten 
in Ausgabepuffer kopieren, 'USART-OUT-Interrupt freigeben, Interrupts 
freischalten.
OP #2171073
Lesenswert?

Hi Jungs,

danke schon mal für eure schnelle Rückmeldung.

Das ich nen Flag Pollen kann ist mir klar. Würde das aber gerne per ISR 
machen, da dann der Code etwas modularer ist.

Die Daten kommen von einem GPS Sensor (ST22), welcher jede Sekunde ein 
paar Datenpakete per UART aussendet.
Diese Datenpakete muss ich in einen Puffer schreiben. Das ist soweit 
klar.

Jetzt müssen diese Daten aber auch ausgewertet werden und das würde ich 
gerne durch eine neue ISR die auf ein FLAG reagiert machen.

Hintergrund des Ganzen ist das dort ein größeres Projekt hintersteckt 
und ich am Ende einen Speicherbereich zur Verfügung stellen muss, in 
welchem immer die aktuellen Daten ausgelesen werden können.
Wenn ich jetzt anfange Funktionen in die Main Routine einzubauen die die 
Daten auswerten, wird die Verwendung des Codes im Gesamtprojekt 
komplizierter. Das würde ich gerne vermeiden und daher aus der USART ISR 
die die Verarbeitung triggern.

Bzw. wenn euch FreeRTOS etwas sagt, dann würde ich gerne eine einzige 
Funktion bereitstellen, welche als Task gespawnt wird zur Verfügung 
stellen. Dieser Task wird beim Aufruf der Speicherbereich als Pointer 
übergeben. Weiter unten mal als Brainstorming zusammen geschrieben.

[c]
xTaskCreate(taskGPS......);


//folgende Funktion wird dann in der st22.c/h bereitgestellt.
void taskGPS(Skytraqdata * buff){
mach was
und noch mehr

}

[\c]

Hoffe ihr könnt euch ungefähr vorstellen was ich so machen muss/ will.
Vielleicht habt ihr ja noch ein paar weitere tips für mich.
Es gibt bestimmt ne sau einfach aber kluge und Resourcenschondende 
Variante. Diese muss nur erst noch gefunden werden :)

Gruß
Sascha
Gast #2171087
Lesenswert?

Sascha P. schrieb:
> Jetzt müssen diese Daten aber auch ausgewertet werden

Ja, und das ist das Hauptprogramm.
Man muss das ja nicht in die mainloop schreiben. Ich würde das auch 
nicht machen. Da kommt nur ein Funktionsaufruf rein, der abgearbeitet 
wird, wenn Daten angekommen sind, und das ganze bleibt schön 
übersichtlich.
Gast #2171265
Lesenswert?

Ok, ich habe keine Erfahrung mit einem RTOS.
Trotzdem verstehe ich nicht, wieso die Datenverarbeitung in einer ISR 
laufen soll. Die müsste ja dann mit sehr Priorität laufen, damit sie von 
zeitkritischen Interrupts unterbrochen werden kann. Und für die 
Modularität ist es auch egal, ob der Code in einer ISR oder einer 
normalen Funktion steht.
Gast #2171442
Lesenswert?

Flo G schrieb:
> Trotzdem verstehe ich nicht, wieso die Datenverarbeitung in einer ISR
> laufen soll. Die müsste ja dann mit sehr Priorität laufen, damit sie von
> zeitkritischen Interrupts unterbrochen werden kann.

Ich glaube, Interrupts sollte man möglichst überhaupt nicht 
unterbrechen.
In einer ISR setzt man am besten immer nur ein Flag. Höchstens mal ein 
Byte empfangen und in einen Puffer schreiben bzw. lesen und dann senden.

> Und für die
> Modularität ist es auch egal, ob der Code in einer ISR oder einer
> normalen Funktion steht.

Das meinte ich. Einfach Zeiger auf die Daten übergeben. Fertig. Läuft 
dann völlig für sich. Was sonst noch in der main() gearbeitet wird, 
stört die Funktion überhaupt nicht.
Gast #2171471
Lesenswert?

David R. schrieb:
> Anderer Vorschlag: Wie wäre es wenn du die Daten im Hintergrund per DMA
> direkt vom USART in den RAM scheffeln lässt?
scheffeln (mit welcher Methode auch immer) und wenn fertig ...
> Dann muss nur noch in unregelmäßigen abständen der STM über die Daten
> drüber schauen und nach dem bestimmten Zeichen suchen.
... lieber Bescheid sagen. Das ist nicht so anstrengend ;-)
Gast #2171492
Lesenswert?

Flo G schrieb:
> Trotzdem verstehe ich nicht, wieso die Datenverarbeitung in einer ISR
> laufen soll.
Ich auch nicht!
ISRs sollen nicht ohne Grund so kurz wie möglich sein. So einen Quark 
mit ISRs, die O(n^2) Code ausführen, habe ich allerdings schon sehen 
müssen. Entsprechend holprig lief das System.

> Die müsste ja dann mit sehr Priorität laufen, damit sie von
> zeitkritischen Interrupts unterbrochen werden kann.
Und sie muss mit niedrigerer Priorität laufen als die UART ISR, sonst 
gehen Zeichen verloren.

@Udo
> Ich wollt's so nicht sagen...
manchmal muss man die Dinge beim Namen nennen ;)

@Sascha
Wenn dir Ringpuffer zu kompliziert ist, dann lege zwei Puffer 
identischer Große an, die jeweils so groß sind, dass eine auszuwertende 
Nachricht komplett rein passt. Die ISR empfängt dann in die eine oder 
andere. Damit umgehst du die Ringpufferverwaltung.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren