Forum: Mikrocontroller und Digitale Elektronik STM32 ohne Loop


von Janosch (Gast)


Lesenswert?

Hallöchen,

Ich programmiere seit längerem kleinere Microcontroller-Projekte 
hauptsächlich mit Arduino. Ich kenne mich nicht so wirklich gut mit der 
genauen Funktion aus, aber so wie ich es verstanden habe, geht es bei 
den AT-Megas und ESP32/8266  nur mit einer Loop schleife.

Nun habe ich mich etwas mit STM32 beschäftigt, und bin auf interesannte 
Punkte gestossen. Beim SMT32 können ja Funktionen "selbständig" etwas 
machen, wie z.b. der ADC muss nicht dauernd abgefragt werden, sondern 
befüllt selbständig Variabeln. Auch beim ändern eines Pin-Levels kann 
eine Funktion direkt aufgerufen werden.

Da diese STM32 ja sehr viele Interrupt-Pins haben (z.b. 15 Stück statt 
1-2 beim AT-Mega) habe ich mich gefragt, ob es nun theoretisch möglich 
wäre, ein komplettes Programm ohne Loop und völlig ohne Zusammenhang zu 
erstellen. Also das wenn z.b. der "Button 1" gedrückt wird, führt dieser 
seinen zugewiesenen Code aus. Die anderen Button wissen davon z.b. 
garnichts.

Wäre soetwas möglich? Also z.b. eine Uhr oder eine Sensorauswertung 
komplett ohne Loop?

Und falls ja, kann mir jemand erklären, was in der Zeit wo "nichts" 
gemacht wird mit dem CPU passiert? Steht er still? Braucht er gleich 
viel Energie wie wenn er im Loop läuft?

Hoffentlich habe ich verständlich erklärt was ich meine.

Grüsse
Janosch

von Julius (Gast)


Lesenswert?

Du kannst den / fast jeden µC auch nach einer Aktion in den Sleep oder 
Stop setzen. Dann sinkt die Stromaufnahme je nach µC auf fast 0.

Die Loop musst Du trozdem rein machen, aber sie steht dann praktisch 
immer.

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Janosch schrieb:
> was in der Zeit wo "nichts"
> gemacht wird mit dem CPU passiert? Steht er still? Braucht er gleich
> viel Energie wie wenn er im Loop läuft?

Es gibt keine Befehl damit der Proccesor dauerhaft stillsteht.
Was du vermutlich meinst ist wenn due in C-Programierst quasi die main() 
zu verlassen. Das ist in der Regel undefiniertes verhalten. Von einfach 
wieder von vorne anfangen, einen Reset durchführen, sich solange im 
Speicher verlaufen bis was schlimmerse passiert, kann alles sein. Da 
must du einen genauen Blick in deinen Startupcode (ja, es gibt sowas wie 
eine leben vor der main:-) werfen um das abzuschätzen.

Bei ARM nehme ich als Funktionsrumpf gerne sowas (in Pseudocode)
1
main()
2
{
3
  Installiere_alles_moegliche();
4
5
  do
6
  {
7
   if (tuewas_eins_flag)
8
   {
9
     tuewas_eins();
10
     tuewas_eins_flag = 0;
11
   }
12
   if (tuewas_zwei_flag)
13
   {
14
     tuewas_zwei();
15
     tuewas_zwei_flag = 0;
16
   }
17
   __wfe (oder __wfi) 
18
   // Schlafen bis zum naechsten Event/interrupt
19
 }
20
 while (bis zum st. nimmerleis Tag);
21
22
}
23
24
irgend_ein_irq()
25
{
26
  // z.B. alle 100ms um eine Anzeige via main zu aktuallisieren
27
  tuewas_eins_flag = 1;
28
}
Im besten fall schläft die CPU die meiste Zeit energiesparent vor sich 
hin.
Und selbst wenn irgend eine ander Event die "main" quasi mal weckt ohne 
das eine "tuewas" gesetzt ist, ist das auch Bainbruch weil nach eine 
paar wenigen Takten gleich wieder weiter geschlafen wird.

Janosch schrieb:
> wie z.b. der ADC muss nicht dauernd abgefragt werden, sondern
> befüllt selbständig Variabeln.

Das wäre mir neu Neu. Das ADC weis noch nichtmal was eine Variable ist, 
der kann keine C:-)
Was du wohl meinst ist das der ADC via DMA einen zuvor definierten 
Bereich im RAM füllen kann (da gibt es auch schönde Events dafür wie zu 
50%/75%/100% oder so gefüllt). Auf diesen Speicherbereich kannst du dann 
natürlich auch von deinem Programm aus zugreifen, du hast ja zuvor 
selbst festgelegt wo dieser liegt.

von (prx) A. K. (prx)


Lesenswert?

Janosch schrieb:
> Wäre soetwas möglich? Also z.b. eine Uhr oder eine Sensorauswertung
> komplett ohne Loop?

Ja, das ist nicht einmal exotisch. Die Loop gibts dann zwar immer noch, 
aber sie tut nichts als warten.

> Und falls ja, kann mir jemand erklären, was in der Zeit wo "nichts"
> gemacht wird mit dem CPU passiert? Steht er still? Braucht er gleich
> viel Energie wie wenn er im Loop läuft?

Die Loop besteht in diesem Fall aus einem Befehl in Schleife, der die 
Befehlsausführung bis zu einem Ereignis anhält, und den Prozessor ggf in 
einen Strom sparenden Modus versetzt. Im passenden Modus läuft DMA 
weiter und Interrupts wecken ihn auf.

: Bearbeitet durch User
von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?


von (prx) A. K. (prx)


Lesenswert?

Ein PC macht das übrigens ähnlich, wenngleich etwas weiter entwickelt 
hinsichtlich Strom sparen. Auch der hat solche eine wartende "Loop", die 
immer dann zum Zuge kommt, wenn er nichts zu tun hat, Die Idle-Task.

von Roland D. (roland_d829)


Lesenswert?

Janosch schrieb:
> Wäre soetwas möglich? Also z.b. eine Uhr oder eine Sensorauswertung
> komplett ohne Loop?

jupp und ist auch Gang und Gebe in der embedded Entwicklung.

> Und falls ja, kann mir jemand erklären, was in der Zeit wo "nichts"
> gemacht wird mit dem CPU passiert? Steht er still? Braucht er gleich
> viel Energie wie wenn er im Loop läuft?

grob gesagt gibt es 2 Möglichkeiten.
 - Endlosschleife (loop) dann verbraucht er eben das was er verbraucht
 - wait for interrupt (WFI) mode, da ist die CPU in einer Art Standby, 
schläft und wartet auf einen Interrupt, das spart natürlich Energie, 
mittlerweile gibt es mehrere standby Stufen, die CPU kann so zu sagen 
noch tiefer schlafen, das spart zwar noch mehr Energie aber um so tiefer 
der standby ist desto länger braucht die CPU um wieder auf zu wachen, 
daher hängt es vom Anwdnungsfall ab wie tief die CPU schlafen kann.
Weiterhin können die peripherals noch mehr, manche Busse können eine 
ganze Nachricht komplett empfangen, im RAM speichern (und das ganz ohne 
CPU) um dann erst die CPU zu wecken.

spannender Ansatz das ganze noch weiter zu treiben ist das Real Time For 
the Masses Framework (RTFM) (C++ implementierung 
https://github.com/korken89/crect, rust implementierung https://rtic.rs)
Dieses nutzt praktisch das Interrupt System (NVIC) des Microcontroller 
als einen, in hardware gegossenen, Betriebssytenm (RTOS) Kernel.

von dummschwaetzer (Gast)


Lesenswert?

In CUBE-MX für einen STM32F303:
startup_stm32f303xe.s
...
/* Call the application's entry point.*/
  bl  main

LoopForever:
    b LoopForever

der macht alo nach der main() den Loop

von Carl D. (jcw2)


Lesenswert?

Irgendwer schrieb:
> ...
> Bei ARM nehme ich als Funktionsrumpf gerne sowas (in Pseudocode)
1
main()
2
{
3
  Installiere_alles_moegliche();
4
5
  do
6
  {
7
   if (tuewas_eins_flag)
8
   {
9
     tuewas_eins();
10
     tuewas_eins_flag = 0;
11
   }
12
   if (tuewas_zwei_flag)
13
   {
14
     tuewas_zwei();
15
     tuewas_zwei_flag = 0;
16
   }
17
   __wfe (oder __wfi) 
18
   // Schlafen bis zum naechsten Event/interrupt
19
 }
20
 while (bis zum st. nimmerleis Tag);
21
22
}
23
24
irgend_ein_irq()
25
{
26
  // z.B. alle 100ms um eine Anzeige via main zu aktuallisieren
27
  tuewas_eins_flag = 1;
28
}
> ...

Es macht keine Sinn, ein von der HW gesetztes "Interruptflag" eine 
Interruptroutine aufrufen zu lassen, um darin ein Flag im RAM zu setzen, 
das dann in der "Main-Loop" abgefragt wird. Das geht "direkt" einfacher.

von Johannes S. (Gast)


Lesenswert?

Es gibt auch sowas wie RTOS für preemptive Multitasking oder EventQueues 
für kooperatives Multitasking.

von Maxim B. (max182)


Lesenswert?

Janosch schrieb:
> habe ich mich gefragt, ob es nun theoretisch möglich
> wäre, ein komplettes Programm ohne Loop und völlig ohne Zusammenhang zu
> erstellen.

Warum nicht?
while(0){}
und danach geht nichts mehr.

von Stefan F. (Gast)


Lesenswert?

Janosch schrieb:
> Wäre soetwas möglich?

Ja durchaus.

Aber das Programm hat dann auch nur wenig Kontrolle darüber, wann es 
durch andere Programmteile unterbrochen wird. Es ergeben sich komplexe 
Zusammenhänge, die man als Anfänger gerne unterschätzt. Erfahrene 
Programmierer meiden diese Methode.

> Und falls ja, kann mir jemand erklären, was in der Zeit wo "nichts"
> gemacht wird mit dem CPU passiert? Steht er still?

In der Regel besteht das Hauptprogramm dann aus einer leeren 
Endlosschleife. Um Strom zu sparen, kann man die CPU anhalten. Sie wacht 
dann bei einem Interrupt wieder auf. Trotzdem braucht man eine 
Hauptschleife.

von Maxim B. (max182)


Lesenswert?

Schreibfehler.
while(1){}
es wird nur gemacht, was davor steht. Danach nichts.

: Bearbeitet durch User
von Hermann K. (r2d2)


Lesenswert?

Maxim B. schrieb:
> Schreibfehler.
> while(1){}
> es wird nur gemacht, was davor steht. Danach nichts.

Achtung: Streng genommen muss das nicht den gewünschten Effekt haben. In 
C ist es erlaubt, aber in C++ ist es undefined behavoir und der Compiler 
darf alles damit machen, was er will. Also z.B. auch die Befehle vor der 
Schleife weglassen.

https://stackoverflow.com/questions/16436237/is-while1-undefined-behavior-in-c

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.