Forum: Mikrocontroller und Digitale Elektronik Wie Auslatung von uC messen?


von martin (Gast)


Lesenswert?

Wie kann ich in der Praxis die Auslastung eines Mikrocontrollers messen?
Ich habe über Keil einen Stm32F1 programmiert. Dieser steuert nur ein 
Display und sollte deshalb überdimensioniert sein.
Doch wie kann ich jetzt die aktuelle Auslastung in Prozent ermitteln und 
genaue Werte zu erhalten?

von Purzel H. (hacky)


Lesenswert?

Ich nehme an, du hast deine Applikation nichtblockerend als 
Zustandsmaschine geschrieben, wo genau an einem Ort im Main die Zeit 
verbraten wird. Dann mach dort ein Bit-Toggle hin und miss dessen 
Aktivitaet mit einem Oszilloskop.

: Bearbeitet durch User
von Tastenklopper (Gast)


Lesenswert?

Pin frei? High setzen während der uC arbeitet, low bei sleep/idle.

Oszi dran, oder RC und Spannung messen.

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


Lesenswert?

martin schrieb:
> Doch wie kann ich jetzt die aktuelle Auslastung in Prozent ermitteln und
> genaue Werte zu erhalten?
Ich messe die Zykluszeit der Haupschleife. Und wenn dieser Zyklus länger 
wird als 5..10ms, dann sehe ich nach, wo denn da Zeit verplempert wird.

> Doch wie kann ich jetzt die aktuelle Auslastung in Prozent ermitteln und
> genaue Werte zu erhalten?
Definiere "Auslastung". Ein µC ist eigentlich immer zu 100% ausgelastet, 
weil er ja nie "wartet", sondern auch in einer Warteschleife wild vor 
sich hinrechnet.

Oder andersrum: dein µC ist dann zu 100% asgelastet, wenn du nichts mehr 
"dazuprogrammieren" kannst, ohne dass irgendwas anderes nicht mehr 
funktioniert. Ein µC, der also nur jede Minute die Temperatur abliefern 
muss, hat zwar eigentlich fast nichts zu tun, kann aber schon 
"überlastet" sein, wenn er diese Temperatur auf 5µs genau abliefern 
muss...

Tastenklopper schrieb:
> Pin frei? High setzen während der uC arbeitet, low bei sleep/idle.
Das ist die einfachste Form, die aber nur funktioniert, wenn man den 
Sleepmode tatsächlich ausgiebig nutzt.

: Bearbeitet durch Moderator
von Joachim B. (jar)


Lesenswert?

martin schrieb:
> Stm32F1 programmiert. Dieser steuert nur ein
> Display und sollte deshalb überdimensioniert sein.
> Doch wie kann ich jetzt die aktuelle Auslastung in Prozent ermitteln und
> genaue Werte zu erhalten?

Ich aktualisiere ein Display nur 4x pro Sekunde, mehr lann ich eh nicht 
lesen.

Messwerte ermitteln, Display schreiben, je einen Port am Anfang setzen 
und am Ende löschen, das kann ich mit dem Oszi prüfen oder einen 
Hardware Timer und ausgeben wie lange was dauert, ist genug Luft 
vorhanden oder stoßen die beiden zusammen?

von user (Gast)


Lesenswert?

Wenn du ein (Echtzeit-)Betriebsystem verwendest ist die Auslastung die 
Zeit wo nicht der Idle-Prozess läuft.

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


Lesenswert?

Joachim B. schrieb:
> Ich aktualisiere ein Display nur 4x pro Sekunde, mehr lann ich eh nicht
> lesen.
Ich aktualisiere in einem üblichen Text-Display zyklisch von links oben 
nach rechts unten pro ms (im Timertic) ein Zeichen. Das hat sich als am 
einfachsten und deterministischsten herausgestellt.

: Bearbeitet durch Moderator
von Joachim B. (jar)


Lesenswert?

Lothar M. schrieb:
> Ich aktualisiere in einem üblichen Text-Display zyklisch von links oben
> nach rechts unten pro ms (im Timertic) ein Zeichen. Das hat sich als am
> einfachsten und deterministischsten herausgestellt.

das mag sein kostet aber mehr Zeit,

warum soll ich alle ms was machen?
kommt halt auf die Anbindung des Displays an, SPI sind oft schneller als 
I2C

Ich bin ja nicht der Profiprogrammierer also schreibe ich nicht zu oft, 
zumal ich nicht immer weiss welche Bytes da übertragen werden müssen mit 
Init, Zeilen Spalten ansprechen Command/Data Wechsel usw.

: Bearbeitet durch User
von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich verwende in meinen Programmen kein OS/RTOS.
Im Main-Loop zähle ich eine INT Variable hoch. Jede Sekunde, im Sekunden 
Timer kopiere ich die in eine zweite Variable und nulle den Zähler.
Diese Zahl zeige ich im Display an und zeigt somit die Main Durchläufe.

Um so größer diese ist um so weniger "Arbeit" steht gerade an.
Wenn ich eine Änderung mache und diese Zahl reduziert sich deutlich, 
dann habe ich entweder extrem schlecht was geändert (viel Warten im 
Code) oder die Berechnung zieht tatsächlich das System herunter, wo man 
dann wiederum überlegen sollte diese in mehr Teilaufgaben zu zerlegen 
oder doch besser anders rechnet.

Dieser Indikator hat schon einige Male mir geholfen und ist sehr einfach 
zu programmieren. Der Systic-Counter ist bei ohnehin immer aktiv.

von Brummbär (Gast)


Lesenswert?

martin schrieb:
> Doch wie kann ich jetzt die aktuelle Auslastung in Prozent ermitteln und
> genaue Werte zu erhalten?

Auslastung bedeutet doch nichts anders als das Verhältnis zwischen 
Arbeiten und nichts tun (wobei letzteres auch eine sinnlose nop-Schleife 
sein kann).

Hast Du zeitkritische Dinge zu erledigen, so ist die Auslastung bei 
100%, wenn diese nicht mehr zeitgerecht ausgeführt werden können.

Hast Du einen Maximalverbauch einzuhalten, so ist die Auslastung bei 
100%, sobald dieser überschritten wurde. Du kannst also den Prozessor 
nicht mehr entsprechend lange schlafen lassen, da er "zu viel" zu tun 
hat.

von Brummbär (Gast)


Lesenswert?

Brummbär schrieb:
> (wobei letzteres auch eine sinnlose nop-Schleife
> sein kann)

... oder einfach Schlafen.

von Jacko (Gast)


Lesenswert?

Lothar M. schrieb:

> Ich aktualisiere in einem üblichen Text-Display zyklisch von links
> oben nach rechts unten pro ms (im Timertic) ein Zeichen. Das hat
> sich als am einfachsten und deterministischsten herausgestellt.

Bei einem 2 x 16 Display sind das 32 ms Updaterate.
OK, fast (!) schnell genug für's Auge.

Aber wozu?

Gibt man alles in einem Schwupp raus, spart man sich die Cursor-
Positionierung und ist in wenigen ms fertig - wobei wichtige
Ereignisse zwischendrin immer mit Interrupt erfasst werden
können.

Wenn es zeitlich eng wird, verschwendet man damit unnötig
µC-Zeit.

von Alex G. (dragongamer)


Lesenswert?

Brummbär schrieb:
> Hast Du zeitkritische Dinge zu erledigen, so ist die Auslastung bei
> 100%, wenn diese nicht mehr zeitgerecht ausgeführt werden können.
Das in ähnlicher Form wurd ein diesem Thread schon um die 5 mal erwähnt.
Denke aber der TE will nicht wissen ob bei Programm X die Auslastung bei 
100% liegt oder nicht (also ne binäre Antwort), sondern eine konkrete 
Prozentangabe damit er weiss wieviel Spielraum er noch hat.
Davon ist z.B. abhängig was für algorithmen man für ein konkretes 
Problem wählt oder auch ob er noch bestimmte optionale Features (die 
einige Arbeitsstunden brauchen bis zum ersten Test) überhaupt noch 
realisierbar sind, oder nicht (weil das sonst verschwendete Arbeitszeit 
wäre).
Also das klingt jedenfalls nützlich.

Eine smarte Lösung die mir einfallen würde, welche es nicht erfordert 
dass man an vielen Stellen im Code was ändert, wäre einsetzbar wenn man 
ein Echtzeit Betriebssystem verwendet. Bei fast allen gibt es die 
Möglichkeit den Threads eine Priorität zu geben.
Dann braucht man einen Thread mit einer Priorität neidriger als alle 
nützlichen Programmthreads und darin werden dann die Zyklen gezählt, 
denn der Scheduler wird immer dann in diesen Thread springen wenn sonst 
nichts anderes etwas zutun hat.

EDIT: Wenn Stromsparmaßnahmen aktiv sind, muss man das natürlich 
berücksichtigen wobei man diesen Auslastungswert ja eher nur während der 
Entwicklung bzw. zu Debugzwecken braucht. Dann kann man die 
Stromsparmaßnahmen abschalten und den Thread mit einer Endlosschleife 
laufen lassen.

: Bearbeitet durch User
von Purzel H. (hacky)


Lesenswert?

An den Unglaeubigen, der ein display auf's Mal beschreiben will ...
Schon mal das Datenblatt angeschaut wie lange du nach einem Zeichen 
schreiben warten musst ? Of ist das in den Mikrosekunden, nicht in den 
Nanosekunden.
Du kannst natuerlich auch das Ready auswerten. Und waehrend ready nicht 
da ist nichts machen, Zeit verbloeden, was man eben genau nicht machen 
sollte.

Die einfachere und effizientere Loesung wie auf Ready warten ist eben 
der Timer. Damit kann man sich das Ready schenken, den Code dazu, wie 
auch den Anschluss.

von Falk B. (falk)


Lesenswert?

Jacko schrieb:
>> Ich aktualisiere in einem üblichen Text-Display zyklisch von links
>> oben nach rechts unten pro ms (im Timertic) ein Zeichen. Das hat
>> sich als am einfachsten und deterministischsten herausgestellt.
>
> Bei einem 2 x 16 Display sind das 32 ms Updaterate.
> OK, fast (!) schnell genug für's Auge.

Man kann ja auch in jedem 10. 1kHz Interrupt ein Zeichen schreiben, dann 
sind es immer noch 3 Hz Wiederholfrequenz.

>
> Aber wozu?

Der Witz an der Sache ist der, daß diese LCDs langsam ohne Ende sind. 
Das eigentliche Schreiben eines Zeichens dauert ca. 1us (Puls an Signal 
E), dann muss man ca. 40us warten, sprich, die CPU ist blockiert. Das 
Ganze dann 4x20=80 mal. Effektive CPU-Nutzung nicht mal 5%. Im Interrupt 
spart man sich das Warten. Außerdem geht das Scheiben in den Puffer im 
SRAM des Mikrocontrollers um Größenordnungen schneller als eine direkte 
Ausgabe auf das LCD.

Trotzdem sind beide Varianten praktikabel!

von Dr. Sommer (Gast)


Lesenswert?

Tools wie Segger SystemView können dir anzeigen, wie viel Zeit du in 
welcher Funktion verbrauchst.

von Timer (Gast)


Lesenswert?

Ich verwende bei PIC24 und PIC32 einen kleinen "Trick", der auch bei 
STM32 klappen könte.

Es setzt voraus, dass man den Idle-Modus benutzt. Aber das will man 
sowieso.

Ich setze zwei Timer auf, einer zählt im Idle weiter, der zweite nicht 
(die Timer der PIC32 kann man so konfigurieren). Einen Timer kann man 
sparen, solange man eine akurrate Vergleichsbasis hat (z.B. einen 
RTCC-Interrupt oder dergleichen).

Den Timer, der nicht im Idle-Modus zählt, liest man nach einer 
definierten Zeit aus und dividiert man durch den Zahlenwert, den er 
hätte, würde er die ganze Zeit zählen. Schon hat man die CPU-Auslastung. 
Inklusive der Zeit, die er in ISRs verbringt.

Man kann sich sogar ein Flag setzen, wenn sie einen Schwellwert 
erreicht, oder man kann sich den Maxwert anzeigen lassen. Was praktisch 
ist, wenn man feststellen möchte, wie knapp man dabei ist. Oder wenn man 
Stromsparen muss.

Man kann einen Timer auch benutzen, um Laufzeiten von bestimmten 
Programmteilen zu messen - beim Eintritt in eine Programmteil starten, 
danach anhalten.
Die gemessenen Zeiten kann man sich bequem in ein Array oder eine 
Struktur speichern. Ich nutze das zur Optimierung. Meistens komme ich da 
mit der Taktfrequenz ziemlich weit hinunter, und es sind oft 
Kleinigkeiten die ziemlich bremsen.

Möglicherweise könnte sich der Core-Timer eignen, falls ein ARM sowas 
hat. Ich habe keine Ahnung, ob ein ARM sowas hat, und ob der im idle 
weiterzählt. Anschauen kann aber lohnen.

von Joerg W. (joergwolfram)


Lesenswert?

> Ich aktualisiere in einem üblichen Text-Display zyklisch von links oben
> nach rechts unten pro ms (im Timertic) ein Zeichen. Das hat sich als am
> einfachsten und deterministischsten herausgestellt.

Das mache ich auch so. In meiner aktuellen Variante brauche ich sogar 4 
Ticks für ein Zeichen. Damit kann ich die Dauer des Taktsignals von der 
CPU-Frequenz entkoppeln und die Routine läuft vom 8MHz AVR bis zum 
120MHz SPC56xxx ohne Änderungen. Bei 1KHz Tick komme ich bei 2x16 auf 
ca. 8Hz Refresh-Rate, das reicht im Allgemeinen aus.

Um die Auslastung zu messen kann man das entweder über "Bitwackeln" oder 
auch über die Stromaufnahme (Shunt) machen, wenn man den Controller in 
den Pausen in den Sleep schickt. Ohne Oszi ist das halt leider nicht 
besonders genau.

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.