Nö, du musst nur zusehen, das der SysTick eine noch höhere Priorität als
der Hardfault Handler hat, sonst hängts. Nicht, das du das nicht sowieso
wolltest, aber blinken tuts dann auch nicht.
Bei sowas würde ich auch keine delay-Funktion nutzen, die auf andere
ISRs angewiesen ist. Da würde ich tatsächlich mit roher CPU Gewalt
Rechenleistung für ein delay alà:
1
voiddelay(uint32_tDelaytime)
2
{
3
while(Delaytime)Delaytime--;
4
}
verbraten. Timing is hier sowieso nur von geringerer Präzision
notwendig.
Peter II schrieb:> und hoffen das der Compiler es nicht komplett entsorgt. Da sollte dann> noch ein volatile oder ähnliches rein.
Kann man ja machen, wenn es nicht auf Anhieb funktioniert...
Peter II schrieb:> Ingo L. schrieb:>> für ein delay alà:>> und hoffen das der Compiler es nicht komplett entsorgt. Da sollte dann> noch ein volatile oder ähnliches rein.
Und genau das sorgt bei unterschiedlichen optimierungsstufen für eine
seeeehr variable Durchlaufzeit. Viele Leute nutzen daher eine simple
Funktion, die eine passend berechnete Anzahl an __NOP(); für so 1us oder
10us enthält.
Für den OP noch der Hinweis, das man solche Schleifen im Hardfault gerne
mal mit Taste unterbrechbar haben will (um z.B. einen Reset auszulösen).
Dann muss man die 200ms unterteilen (z.B. 1ms Schritte), sonst muss der
Anwender die Taste lange gedrückt halten.
Walter T. schrieb:> "L_LOOPUS_%=: \n\t" \> "subs %0, %0, #1 \n\t" \> "bne L_LOOPUS_%= \n\t" \
Dafür hat der Gott der Unix-Assembler local labels erfunden:
Die Funktion delay_ms() basiert doch nicht auf Interrupts und auch nicht
auf dem System-Tick (solange es keine Eigenentwicklung ist) - oder habe
ich da etwas überlesen?
Die Prio vom HardFault und SysTick ist einstellbar.
Ich beziehe mich jetzt auf einen Cortex-M4, denn der verwendete
Controller wurde nicht genannt.
Walter T. schrieb:> Hallo zusammen,>> gibt es eigentlich einen Grund, der gegen einen delay in einer ISR> spricht?>>
1
> void HardFault_Handler(void)
2
> {
3
> // Sicheren Zustand herstellen
4
> GPIOA->MODER = 0;
5
> GPIOB->MODER = 0;
6
> GPIOC->MODER = 0;
7
> GPIOD->MODER = 0;
8
>
9
.
10
> setOutput(ERRORLED_GPIO, ERRORLED_Pin);
11
>
12
> while(1) {
13
> ERRORLED_GPIO->ODR ^= (uint32_t) ERRORLED_Pin;
14
> delay_ms(200);
15
> }
16
> }
17
>
>> Eigentlich müßte doch beim HardFault-Handler der Drops gelutscht sein> und mich delays nicht mehr interessieren.>> Viele Grüße> W.T.
Das ist keine ISR, sondern ein Fault-Handler. Falls der nur eine
Error-LED blinken lassen soll, warum nicht. Wenn er eine Situation
behandelt, für die es tatsächlich eine softwaretechinsche Lösung gibt,
dann würde man sicher kein delay() wollen. Die würde man dann aber eher
in UsageFault/MemoryManagementFault behandeln, im HardFault ist die
Fehlerursache gar nicht mehr ablesbar.
Hardfault ist so eine Art letztes Zucken, denn der kommt, wenn andere
Fehlersituationen nicht oder nicht ohne neu auftretende Fehler behandelt
werden. Da ist alles erlaubt. Zumal ein Hardfault eine kaum noch zu
unterbietende Prio hat.
Jörg W. schrieb:> Dafür hat der Gott der Unix-Assembler local labels erfunden:
Danke für den Hinweis! ARM-Assembler ist für mich eine Fremdsprache, die
ich nie ohne Wörterbuch in der Hand anfasse.
Walter T. schrieb:> Jörg W. schrieb:>> Dafür hat der Gott der Unix-Assembler local labels erfunden:>> Danke für den Hinweis! ARM-Assembler ist für mich eine Fremdsprache, die> ich nie ohne Wörterbuch in der Hand anfasse.
Die Sprache zu verstehen wäre aber Grundvoraussetzung, um die Auswirkung
verschiedener C-Konstrukte abschätzen zu können.
Plus so Feinheiten, daß ein Register in dem Befehl nachdem es geladen
wurde vielleicht noch nicht verfügbar ist und man deshalb besser 2
"C-Statement" verschränkt ausführt.
Jim M. schrieb:> Für den OP noch der Hinweis, das man solche Schleifen im Hardfault gerne> mal mit Taste unterbrechbar haben will (um z.B. einen Reset auszulösen).> Dann muss man die 200ms unterteilen (z.B. 1ms Schritte), sonst muss der> Anwender die Taste lange gedrückt halten.
Meine Reset-Taste benötigt immer gleich lang, egal was im Fault-Handler
läuft.
Walter T. schrieb:> ARM-Assembler ist für mich eine Fremdsprache
Wobei die Geschichte der local labels nicht so viel mit der
Architektur zu tun hat, sondern mit der Umgebung. Der hier verwendete
GNU Assembler hat seine historischen Wurzeln in den Unix-Assemblern,
die haben solche Labels halt seit jeher gekannt.
Die kann man im GNU Assembler dann unabhängig von der Architektur
nutzen, also sowohl auf ARM, AVR oder x86.
Andere ARM-Assembler haben dieses Feature möglicherweise nicht.
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang