Forum: Compiler & IDEs C routine abbrechen nach Timeout


von frager (Gast)


Lesenswert?

Hallo,

ich habe eine Frage, kann ich eine C routine nach Timeout abbrechen?

Beispiel:

void function1()
{
    u8 result = callfunctionOnOtherCore();
    berechnung();
}

d.h. wenn die Funktion: callfunctionOnOtherCore() innerhalb 100µs kein 
Ergebnis liefert, soll sie abgebrochen werden und mit 
berechnung-Funktion weiter fortgesetzt werden?

zur Info: die Funktion: callfunctionOnOtherCore liegt auf einem anderen 
Kern.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Nein, das kann nur Deine "auf einem anderen Kern liegende" Funktion 
selber, oder gegebenenfalls das Betriebssystem, das Du verwendest, um 
Funktionen auf "andere Kerne" zu verteilen.

C weiß nichts von Kernen, und C kann keine Funktionen "abbrechen".

von (prx) A. K. (prx)


Lesenswert?

frager schrieb:
> zur Info: die Funktion: callfunctionOnOtherCore liegt auf einem anderen
> Kern.

Die Antwort hängt - wie so oft - vom Kontext ab, in dem das stattfindet. 
Bei den üblichen Betriebssystemen vgl. Windows/*ix ist das meist kein 
Problem, egal auf welchem Core. "Meist" deshalb, weil ein 
Thread/Prozess, der in einem Device Driver hängt, nicht immer 
abschiessbar ist.

Bei Bare Metal Programmierung ist das ebenfalls möglich und in Form von 
Watchdogs auch recht verbreitet. Aber der sauberste und einzig sichere 
Ausweg aus der als Folge möglichen Ressourcenkrise (z.B. I2C/... Status 
bleibt mittendrin hängen) ist ein Reset, weshalb Watchdogs üblicherweise 
damit operieren. Ohne Reset kann es funktionieren, oder kann alles 
durcheinander bringen, je nachdem wo abgebrochen wurde.

Wer also in Bare Metal Programmierung so ein Problem hat, der schreibt 
die betreffende Funktion so, dass sie selbst ihre Laufzeit kontrolliert 
und ggf. abbricht. Das ist sehr verbreitet und unterhalb der Axt "Reset" 
der sinnvollste Weg.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

A. K. schrieb:
> frager schrieb:
>> zur Info: die Funktion: callfunctionOnOtherCore liegt auf einem anderen
>> Kern.
>
> Die Antwort hängt - wie so oft - vom Kontext ab, in dem das stattfindet.
> Bei den üblichen Betriebssystemen vgl. Windows/*ix ist das meist kein
> Problem, egal auf welchem Core.

Naja, sagen wir mal so: Es gibt einen Weg, das zu machen, aber es ist 
selten eine gute Idee, weil es sehr schnell zu Ressourcen-Lecks und 
Deadlocks führt.

> Wer also in Bare Metal Programmierung so ein Problem hat, der schreibt
> die betreffende Funktion so, dass sie selbst ihre Laufzeit kontrolliert
> und ggf. abbricht. Das ist sehr verbreitet und unterhalb der Axt "Reset"
> der sinnvollste Weg.

Das ist nicht nur auf Bare Metal so.

von Peter D. (peda)


Lesenswert?

Unter C kann man vor dem Aufruf der Funktion einen setjmp() setzen und 
dann aus dem Timerinterrupt longjmp() ausführen.

Z.B. mit dem AVR-GCC geht das, ob die ungenannte Architektur das auch 
kann.

von (prx) A. K. (prx)


Lesenswert?

Peter Dannegger schrieb:
> Unter C kann man vor dem Aufruf der Funktion einen setjmp() setzen und
> dann aus dem Timerinterrupt longjmp() ausführen.

Aber ob und was das an Chaos anrichtet hängt von der Funktion ab und wo 
sie genau unterbrochen wurde.

von voll easy (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Unter C kann man vor dem Aufruf der Funktion einen setjmp() setzen
> und
> dann aus dem Timerinterrupt longjmp() ausführen.
>
> Z.B. mit dem AVR-GCC geht das, ob die ungenannte Architektur das auch
> kann.

Wenn ich extern mit einem Timerinterrupt überwache brauche ich nur ein 
Label oder eine Adresse für den PC. Ich muss mir aber vorm 
Unterprogrammaufruf noch den Stackpointer merken.

von (prx) A. K. (prx)


Lesenswert?

voll easy schrieb:
> Wenn ich extern mit einem Timerinterrupt überwache brauche ich nur ein
> Label oder eine Adresse für den PC. Ich muss mir aber vorm
> Unterprogrammaufruf noch den Stackpointer merken.

Und alle im Aufrufer genutzten und bei einem Aufruf bewahrten Register 
(callee-saved), so die Plattform welche hat. Womit du circa bei setjmp 
angekommen bist.

von voll easy (Gast)


Lesenswert?

A. K. schrieb:
> setjmp

... und wenns den nicht gibt?

Dann macht mans zu Fuß und juut isses ...

Mit nem externen Timeout ists easy!

von (prx) A. K. (prx)


Lesenswert?

voll easy schrieb:
> Dann macht mans zu Fuß und juut isses ...

Kann hässliche Schmutzeffekte geben, wenn zwischen main() und dem Caller 
Variablen in Registern liegen. Die sind dann u.U. voll easy weg.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Unter C kann man vor dem Aufruf der Funktion einen setjmp() setzen und
> dann aus dem Timerinterrupt longjmp() ausführen.

Und was soll das bringen?  Der Interrupt bzw. longjmp müsste ja auf dem 
anderen Core ausgelöst werden.  Willst du den anderen Core anhalten 
oder ein Hardware-Interrupt triggern, der im anderen Core eine IRQ 
auslöst?

von Falk B. (falk)


Lesenswert?

@Johann L. (gjlayde) Benutzerseite

>Und was soll das bringen?  Der Interrupt bzw. longjmp müsste ja auf dem
>anderen Core ausgelöst werden.  Willst du den anderen Core anhalten
>oder ein Hardware-Interrupt triggern, der im anderen Core eine IRQ
>auslöst?

Das ist die Kernfrage!

SCNR

von (prx) A. K. (prx)


Lesenswert?

Wenn function1() auf Core A liegt und callfunctionOnOtherCore() auf Core 
B, dann ist das kein normales C. Oder callfunctionOnOtherCore() liegt 
doch auf Core A, wedelt aber mit dem Zauberstab um eine Funktion auf B 
auszulösen. Ohne die Mechanik dieser Magie zu kennen ist dann eine 
Antwort nicht möglich.

Wenn andererseits function1() bereits auf Core B läuft, dann geht 
setjmp/longjmp, indem man einen Interrupt auf Core B auslöst.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.