Forum: Mikrocontroller und Digitale Elektronik STM32: CPU-Last errechnen


von Jan (Gast)


Lesenswert?

Hallo Community

Mein Programm besteht aus einem Teil der immer läuft (Interrupt für ADC 
usw.) und einem Teil der asynchron zum Programm läuft.
Nun wollte ich eine Art Task Manager für den µC zu machen, der mir 
anzeigt wieviel Prozent der Rechenkapazität ausgelastet sind. Dazu habe 
ich folgenden Code gebaut.
1
void Performance_Check()
2
{
3
performance.counter++;
4
if(performance.ind >= 20)
5
    {
6
    if (performance.counter < performance.counter_low)
7
        performance.counter_low = performance.counter;
8
    if (performance.counter > performance.counter_high)
9
      performance.counter_high = performance.counter;
10
    performance.ind=0;
11
    performance.counter_low = 65500;
12
    }
13
}
14
15
// In der Ausgaberoutine dann 
16
performance.percentage = 100-((performance.counter_low*100)/performance.counter_high);

Zur Erklärung performance_check wird in der main while schleife gepollt. 
performance.ind wird in einer Timer Interrupt Routine erhöht.
Funktioniert schonmal ganz gut.
Ist es sinnvoll das so zu machen?
Die Division frisst Rechenzeit. Wie kann ich hier besser arbeiten?
Wie erfasse ich auch noch die "ständigen Lasten" des Systems.

mfg Jan

von (prx) A. K. (prx)


Lesenswert?

Soll die Auslastung einmalig in der Entwicklung oder dauerhaft im 
Betrieb gemessen werden?

Entwicklung: Während des Ablaufs der Interrupt-Handler und im aktiven 
Code einen Pin setzen, ausserhalb davon löschen. R/C-Glied dran und 
Spannung messen, bei Zeigerinstrument gehts auch ohne R/C.

von Jan (Gast)


Lesenswert?

Es soll im laufenden Betrieb gemessen werden.

von holger (Gast)


Lesenswert?

>Entwicklung: Während des Ablaufs der Interrupt-Handler und im aktiven
>Code einen Pin setzen, ausserhalb davon löschen. R/C-Glied dran und
>Spannung messen, bei Zeigerinstrument gehts auch ohne R/C.

>Es soll im laufenden Betrieb gemessen werden.

Spannung am RC Glied mit ADC messen;)

von Jan (Gast)


Lesenswert?

Na das muss sich doch auch in Software realisieren lassen.

von holger (Gast)


Lesenswert?

>Na das muss sich doch auch in Software realisieren lassen.

Nimm einen Timer und sieh nach wie oft performance.counter
pro Sekunde oder Millisekunde so raufgezählt werden konnte.

von STM-noob (Gast)


Lesenswert?

Warum ueberschreibst du eigentlich dein low nach deiner If sofort wieder 
mit einem festen Wert ohne den alten je ausgewertet zu haben?

von Jan (Gast)


Lesenswert?

@ Holger

holger schrieb:
>>Na das muss sich doch auch in Software realisieren lassen.
>
> Nimm einen Timer und sieh nach wie oft performance.counter
> pro Sekunde oder Millisekunde so raufgezählt werden konnte.

Na genau so mache ich es doch. Es geht mir darum, ob ich die Division im 
Bereich der Berechnung der prozentualen Last etwas intelligenter lösen 
kann.
Division kostet Rechenpower^^. Oder ob es im allgemeinen noch andere 
(bessere?) Möglichkeiten gibt es zu realisieren.

STM-noob schrieb:
> Warum ueberschreibst du eigentlich dein low nach deiner If sofort wieder
> mit einem festen Wert ohne den alten je ausgewertet zu haben?

Oh da habe ich ne Zeite beim Copy Paste nicht erwischt
Wird natürlich voher ausgewertet.

mfg Jan

von (prx) A. K. (prx)


Lesenswert?

Jan schrieb:

> Die Division frisst Rechenzeit.

Na und?

> Wie erfasse ich auch noch die "ständigen Lasten" des Systems.

Du wirst bei diesem Ansatz nicht drum herum kommen, das System 
beispielsweise beim Start zu kalibirieren. Indem diese ständigen Lasten, 
wie etwa häufige Interrupts und irgendwelcher anderer Mainloop-Code 
anfangs erst einmal inaktiv sind, um das maximale Zähltempo zu 
ermitteln.

Wenn der erwähnte Timer ausreichend langsam interrupted um nicht selbst 
zu sehr das Ergebnis zu verfälschen, dann kannst du nach einigen Ticks 
davon andere Mainloop-Aktivitäten per Flag und andere Interrupt-Handler 
per Interrupt-Enable-Bits verzögert einschalten.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Jan schrieb:
> (Interrupt für ADC
> usw.)

Du bist dir bewusst, das du den ADC auch ohne jede CPU Belastung laufen 
lassen kannst? Das würde die Prozentzahl wieder etwas drücken.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jan schrieb:
> Nun wollte ich eine Art Task Manager für den µC zu machen, der mir
> anzeigt wieviel Prozent der Rechenkapazität ausgelastet sind.
Der Ansatz ist m.E. falsch. Denn die Rechenkapazität ist nie 
ausgelastet: warte einfach eine Sekunde, dann hast du wieder 
Rechenkapazität frei...

Interessant ist doch eher:
wie schnell kann dein System auf externe Ereignisse reagieren? Wie 
schnell kann also ein Taster oder Schalter abgefragt und darauf reagiert 
werden? Interessant ist also die Zykluszeit der Hauptschleife.
Und so wird das bei SPSen auch definiert: wie lange dauert 1 Durchlauf 
im Schnitt und wie lange dauert der im schlimmsten Fall? Denn es bringt 
dir nichts, wenn dein System im Schnitt 50 mal durch die Hauptschleife 
kommt, aber zwischendurch immer 1 Zyklus kommt, der 900ms braucht...

von (prx) A. K. (prx)


Lesenswert?

In Multitasking-Systemen ist die Anzahl gleichzeitig lauffähiger Tasks 
ein weit besserer Lastindikator als die prozentuale Auslastung.

von Christian G. (christian_g83)


Lesenswert?

Jan schrieb:

> Wie erfasse ich auch noch die "ständigen Lasten" des Systems.

Zunächst einmal muss Du definieren, was Du unter "Auslastung" des 
Prozessors verstehst. Der macht nämlich ständig irgend etwas. Von 
einigen Etwassen möchte man, dass sie zur Auslastung beitragen, von 
anderen möchte man das nicht (Stichwort: Idle-Task).

Um dann auf den Wert der Auslastung zu kommen, wird man die zeitlichen 
Anteile der jeweiligen Etwasse über einen bestimmten Zeitraum mitteln 
müssen. Eine punktförmige Messung ist bei einem Einkern-Prozessor nicht 
möglich, da ja tatsächlich immer nur ein Task wirklich ausgeführt wird.

Man misst also die Zeit, die der Prozessor sich innerhalb des Codes 
befindet, der zur Auslastung beitragen soll, und dividiert diese durch 
die insgesamt verstrichene Zeit.

"Zeit" ist hierbei als abstrakter Begriff zu verstehen. Das können 
Zeitscheiben, Interrupts oder sonst etwas Brauchbares sein. Oder eben 
Sekunden.

Christian

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Hi,

zu deinem Ausgangspost:

Schreibe einen einfachen Scheduler, der aus einem FuncPointerArray 
besteht. Da trägst du alle deine Funktionen ein, die nacheinander 
aufgerufen werden sollen.

Der Scheduler tut dies nun, und startet vor jedem Aufruf einen Timer, 
und beendet ihn beim Return. Der wird dann ausgelesen und abgespeichert.

Das funktioniert auch, wenn du in deiner Fkt. ein vorzeitiges Return 
aufgrund eines Ereignisses machst.

---
Noch besser:
Du schnappst dir ein RTOS, was auf einem CM3 durchaus Sinn macht, und 
nutzt dessen statistische Daten.


VG,
/th.

von STM-noob (Gast)


Lesenswert?

Um noch mal bloede zu quatschen: Ich gucke momentan nur nach der Anzahl 
der Durchlaufe zwischen zwei festgelegten Ereignissen 
(Timer-CC-Interrupt, den ich sowieso benoetige). Anhand der 
Zaehlerstaende sehe ich dann ob ich noch genug Zeit habe oder obs 
kritisch wird. Ist also eigentlich das selbe wie in deinem Fall. Wie 
schon jemand schrieb brauchst du ja nur den Worst Case in einem 
Bestimmten Bereich, es sei denn du willst das loggen.

An sonsten schwirrt mir gerade nur etwas im Kopf herrum von 
Bitinvertierung und dann mit der maximalen Anzahl der moeglichen 
Durchlaufe vergleichen. Aber ich denke nicht dass man die Division 
besser gestalten kann als ohnehin schon dein Compiler fuer dich macht.

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.