Timeout über Zeitkritische Funktion

OP #1518951
Lesenswert?

Hallo,

ich habe eine 'round robin with interrupts' Architektur und im Taskmode 
eine zeitkritische Funktion die aufgrund von Warteschleifen stecken 
bleiben kann und die ich daher mit einem Timeout versehen will. Wenn die 
Zeit abgelaufen ist, soll die Funktion einfach beendet werden.

Ich möchte aus zeitlichen Gründen nicht in jede Warteschleife einen 
Timeout einbauen und abfragen, sondern nur einen der über einen 
Timer-interrupt gesteuert wird. Der Timer wird normalerweise in 
regelmäßigen Abständen auf null gesetzt.

Ich habe mir Folgendes überlegt:
Ich markiere die Funktion als __attribute__((naked)) und rufe sie statt 
direkt über eine Assembler Routine auf. Diese Assembler Routine stellt 
wiederrum eine Adresse zur Verfügung, die angesprungen werden kann, wenn 
der Timeout Triggert. Es wird das Ende also von einer  also von einer 
Interrupt Routine angesprungen.

Die Interrupt Routine würde also den PC-wert aus dem Link Register 
manipulieren, so dass direkt an das Ende der Assembler Routine 
gesprungen wird.

Was haltet Ihr davon und hat jemand eine bessere Idee? Das Problem was 
ich sehe: Das Programm wird dadurch sehr verkompliziert, so dass eine 
Weiterentwicklung durch andere Entwickler erschwert wird (die 
höchstwahrscheinlich nur nebenbei programmieren).

Grüße
Daniel
#1519012
Lesenswert?

@  Daniel G. (motello)

>Was haltet Ihr davon

Nix. Klingt alles viel zu kompilziert nun nach Hackermist.

> und hat jemand eine bessere Idee? Das Problem was
>ich sehe: Das Programm wird dadurch sehr verkompliziert, so dass eine
>Weiterentwicklung durch andere Entwickler erschwert wird (die
>höchstwahrscheinlich nur nebenbei programmieren).

EBEN!

Mach es DIREKT RICHTIG!

Sprich, deine Funktion jedes Mal den Softwaretimer abfragen. Geht halt 
nicht anders. Ist auch OK. Vergiss das volatile nicht, siehe 
Interrupt.

MFG
Falk

P S Was muss denn das so furchtbar schnell abgearbeitet werden, dass 
eine einfach Variablenprüfung nicht drin ist?
OP #1519044
Lesenswert?

Es ist eine Schleife die einen knapp 500Byte Datenblock per 
EPP-Handshake ließt und per UDP verschickt. In jedem Handshake (1 Byte) 
sind zwei Schleifen drin, in die noch die Timeout-Flag-Abfrage rein 
müsste. Das läppert sich...

Ich habe noch andere Möglichkeiten der Optimierung (Cache Lockdown, das 
ganze in einen kleinen SRAM Bereich statt SDRAM verschieben, ich glaub 
ich mache es wirklich nicht.

Mir ist gerade beim schreiben noch eine bessere Idee gekommen: Ich 
könnte ein Register nutzen um das Flag zu speichern (auf das auch direkt 
die Interrupt routine zugreift und es ggf. ändert). Aber das wird wohl 
daran scheitern, dass man keine register in C (GCC) reservieren kann, 
oder?
#1519119
Lesenswert?

@Daniel G. (motello)

>sind zwei Schleifen drin, in die noch die Timeout-Flag-Abfrage rein
>müsste. Das läppert sich...

Probier es doch mal REAL aus, sprich Simulator und reale Anwendung. DANN 
reden wir weiter.

>daran scheitern, dass man keine register in C (GCC) reservieren kann,
>oder?

Theoretisch ja, praktisch wird das immer weniger möglich. Aber da du 
eine fetten 32 Bitter scheinbar hast, ist deine Befürchtung 
wahrscheinlich unbegründet.

MFG
Falk
#1519180
Lesenswert?

IMHO beißt sich bereits das

> zeitkritische Funktion die aufgrund von Warteschleifen stecken
> bleiben kann und die ich daher mit einem Timeout versehen will.

zeitkritische Funktionen und Warteschleifen passen nur selten zusammen. 
Wobei das Problem auf seiten der Warteschleifen liegt.
OP #1519270
Lesenswert?

Das ganze läuft längst REAL und ich habe auch bereits Messungen 
vorgenommen, zumindest an der ganzen Leseroutine. Damals hatte ich 
allerdings mehr als nur eine Flag-Abfrage drin sondern habe einen 
Timer-Wert gelesen, berechnet und verglichen. mit der Flag-Abfrage 
könnte ich es wirklich noch mal probieren. wenn das Flag im Cache liegt, 
hat es vielleicht gar nicht so große Auswirkungen.

Diese Routine ist mit der, die den Datenblock dann sendet (über 
Ethernet/UDP) die einzige Zeitkritische. Das ganze muss so schnell wie 
möglich sein, um eine DFT so schnell wie möglich zu ermöglichen um eine 
möglichst hohe Regelbandbreite zu erzielen. Jedenfalls sind die 
Anforderungen noch nicht klar, daher so schnell es geht :-)

Wie kann ich denn ein Register reservieren in C mit GCC?

Die Wartezeiten sind übrigens so gering, dass selbst ein einfacher 
Kontextswitch um etwas anderes zu machen, in den allermeisten Fällen 
länger dauern würde als das bisschen warten.
OP #1526929
Lesenswert?

Hallo,

habe Timeouts nun auf "herkömmlichem" Wege eingebaut. Durch geschicktes 
Abfragen hält sich die Geschwindigkeitseinbuße sehr in Grenzen: Der 
Timer wird nur selten zurückgesetzt und hat demnach eine höhere Zeit, 
was hier nicht stört. Das Timeout-flag wird nur abgefragt, wenn die 
Warteschleife überhaupt mal ausgeführt wird, was eher selten der Fall 
ist, weil die Wartebedingung meist nicht erfüllt wird.

So ist der Code schön lesbar und einheitlich geblieben :-) Die 
Weiterentwickler werden es danken. Danke für die Tipps!

Schöne Grüße und frohes fest!
Daniel

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