STM32 - HAL Delay gut?

Gast #7306923
Lesenswert?

Guten Abend ans Forum,

ich versuche mich gerade etwas an STM32 Controllern. Irgendwann kommt man ja an den Punkt, wo mehrere Sachen quasi-parallel laufen sollen.

Bisher verwende ich "HAL_Delay(1000)" um eine Sekunde zu warten. Mir war aus der AVR Welt noch bekannt, dass die Delay Sache den Controller komplett lahm legt (User Eingaben werden nicht erkannt etc).

Auf der Suche nach dem besseren Weg, bin ich auf die Implementierung von HAL_DELAY gestoßen.

Frage 1: Blockiert HAL_DELAY mein Hauptprogramm wie bei den AVRs? Nach meinem Verständnis hängt ja er ja blöd in der while Schleife rum und User Eingaben im Hauptprogramm gehen verloren. Liege ich richtig?

1
__weak void HAL_Delay(uint32_t Delay)
2
{
3
  uint32_t tickstart = HAL_GetTick();
4
  uint32_t wait = Delay;
5
  /* Add a freq to guarantee minimum wait */
6
  if (wait < HAL_MAX_DELAY)
7
  {
8
    wait += (uint32_t)(uwTickFreq);
9
  }
10
  while ((HAL_GetTick() - tickstart) < wait)
11
  {
12
  }
13
}

Wäre dann diese Art der Implementierung besser?

https://embeddedexpert.io/?p=246

Oder eine ganz andere?

Beste Grüße Max

Gast #7306942
Lesenswert?

Wäre dann diese Art der Implementierung besser?

Was erwartest du das dein Controller bei einem delay macht? IRQs werden weiterlaufen, aber sonst steht natuerlich alles wenn du kein Multitasking-OS verwendet.

Du kannst das hoechstens selbst entschaerfen in dem du dir ein, ein Ticker_Start() und eine Ticker_Ask(1000) programmierst.

Dann sowas:

Ticker_Start(); do { // Hier kannst du noch was machen }while(Ticker_Ask(1000);

Olaf

Gast #7307203
Lesenswert?

schau dir mal diese macros an:

1
/*
2
 *  These inlines deal with timer wrapping correctly. You are 
3
 *  strongly encouraged to use them
4
 *  1. Because people otherwise forget
5
 *  2. Because if the timer wrap changes in future you won't have to
6
 *     alter your driver code.
7
 *
8
 * time_after(a,b) returns true if the time a is after time b.
9
 *
10
 * Do this with "<0" and ">=0" to only test the sign of the result. A
11
 * good compiler would generate better code (and a really good compiler
12
 * wouldn't care). Gcc is currently neither.
13
 */
14
#define time_after(a,b)    \
15
  (typecheck(unsigned long, a) && \
16
   typecheck(unsigned long, b) && \
17
   ((long)((b) - (a)) < 0))
18
#define time_before(a,b)  time_after(b,a)

im linux code gibs da noch mehr.

oder du baust dir gleich einen SW-Timer auf! siehe als Idee z.B.: 'https://github.com/lmooml/SmartTimer/tree/master/smarttimer'

#7307221
Lesenswert?

Verzögerer schrieb:

while ((HAL_GetTick() - tickstart) < wait) { }

Warum warten, wenn man auch prüfen kann? Wirklich, bei 1000ms macht die main( while() ... ) doch viele Durchläufe. Also kann man doch mit HAL_GetTick() prüfen ob die Sekunde rum ist und dann darauf reagieren. Sollte diese eben nicht rum sein, kann man allen möglichen anderen Kram machen. Ok es kann passieren das man ein paar Millisekunden zu spät erkennt, dass die 1000ms rum sind, aber das muss man selber abschätzen wie wichtig das ist. Wenn die 1000ms wichtig sind sollte man eh auf Timer-Interrupt setzen.

#7307231
Lesenswert?

olaf schrieb:

Ein ungeschicktes Trollthema.

Denkbar, aber du darfst nicht vergessen das der Nachwuchs immer duemmer wird, was natuerlich daran liegt das wir vergessen haben wie dumm wir waren als wir angefangen haben. :-D

:-)

Es gibt Uncle Bob's Law: Die Anzahl der Entwickler verdoppelt sich alle 5 Jahre, siehe hier: https://www.linkedin.com/pulse/developer-ranks-double-every-5-years-andy-smith

Dadurch ergibt sich folgende Tabelle, quasi eine Erfahrungspyramide: 50 % der Entwickler haben weniger als 5 Jahre Erfahrung 75 % der Entwickler haben weniger als 10 Jahre Erfahrung 87,5 % der Entwickler haben weniger als 15 Jahre Erfahrung 93,75 % der Entwickler haben weniger als 20 Jahre Erfahrung ...

Je steiler das Wachstum desto größer das Problem.

Michael

Gast #7307365
Lesenswert?

Verzögerer schrieb:

ich versuche mich gerade etwas an STM32 Controllern. Irgendwann kommt man ja an den Punkt, wo mehrere Sachen quasi-parallel laufen sollen.

Bisher verwende ich "HAL_Delay(1000)" um eine Sekunde zu warten.

Anbei ein kleines Stück Quellcode mit dem man das Warten etwas besser organisieren kann, ohne dazu gleich irgendwelche Betriebssysteme aufzufahren, wie es dir bereits angeraten wurde. Ich hab das vor geraumer Zeit schon mal gepostet, aber das Suchen im Forum scheint eher unbeliebt zu sein.

Also, zum Prinzip: anstatt mit Warten die Zeit totzuschlagen kann man es auch andersherum machen: man stellt sich einen Wecker, der nach xxx Sekunden (oder Stunden oder Millisekunden) klingelt. Da kann man in der Zwischenzeit was anderes machen oder auf das Klingeln warten - je nach Gusto. Der Wecker ist hier der Interrupthandler des Timerticks und das Klingeln ist die Event-Verwaltung, genauer ein Event, der zur rechten Zeit in die Event-Warteschlange geworfen wird.

Das Beispiel in der ZIP-Datei ist ein Beispiel. Da kommen auch Event-Codes und Namen von Programmteilen und anderes Zeugs vor, was du vermutlich nicht brauchst. Du kannst es dir also nach deinem Bedarf zusammenkürzen und abändern nachdem du das eigentlich recht einfache Prinzip verstanden hast.

W.S.

Angehängte Dateien:
#7307412
Lesenswert?

und was soll so schlimm sein an der Nutzung eines OS? Für allgemeine Probleme kann man auch allgemeine Lösungen nehmen. Und Events und Timer sind so allgemein das jedes OS sowas an Grundausstattung hat. Mit Doku, entwickelt und getestet von großen Communities, ordentlich auf Git Servern abgelegt und nicht als undokumentierte Zip Brocken von einem Frickler über den Zaun geworfen. Und das ist auch der Grund warum so etwas nicht gefunden wird, ein Forum als Dateiablage ist einfach nur Scheiße.

Gast #7307445
Lesenswert?

und was soll so schlimm sein an der Nutzung eines OS?

Fuer sehr kleine Sachen ist ein OS oftmals uebertrieben weil es eine Sache ueberkompliziert oder manchmal auch etwas unmoeglich macht. Erst recht fuer einen Anfaenger. Auch das Debuggen komplexer Fehler kann da manchmal eine komplexe Freude sein die dich lange beschaeftigt.

Fuer sehr grosse komplexe Sachen ist es manchmal zwingend notwendig. Zum Beispiel wenn du den Code von einem Dutzend Programmierer in deinem System hast den du auch etwas getrennt halten willst.

Interessant ist der Zwischenbereich wo man sich nicht sicher ist was angemessen ist, da kann man dann trefflich streiten. :-)

Das Eventprinzip das Wolfgang oben nahelegt war auch die Grundlage der Palmpiloten.

Vorteil: Man konnte mit wenig Rechenleistung viel erreichen und hatte dabei noch eine lange Batterielebensdauer dessen Nutzung eine stete Freude war.

Nachteil: Eine Schwachkopfanwendung und dein ganzes System steht.

Olaf

#7307458
Lesenswert?

olaf schrieb:

Fuer sehr kleine Sachen ist ein OS oftmals uebertrieben weil es eine Sache ueberkompliziert oder manchmal auch etwas unmoeglich macht.

Man kann 'kleine' Sachen auch als Übung für größere sehen. Ohne Erfahrung gleich ein System mit zig Threads aufzusetzen kann natürlich auch reichlich schief gehen.

OS heißt ja nicht unbedingt für alles ein RTOS mit präemptiven Scheduler einzusetzen, das Event Prinzip habe ich hier auch schon X-mal gezeigt. Das RTOS mit PS hat einen Overhead alleine durch den Stackbereich je Thread, aber selbst auf 'kleinen' Cortex-M passt das schon.

Für lange Batterielebensdauer hilft auch ein tickless OS, und da wird es schon eine Spur komplexer sowas selber zu bauen.

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