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?
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
Pin frei? High setzen während der uC arbeitet, low bei sleep/idle. Oszi dran, oder RC und Spannung messen.
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
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?
Wenn du ein (Echtzeit-)Betriebsystem verwendest ist die Auslastung die Zeit wo nicht der Idle-Prozess läuft.
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
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
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.
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.
Brummbär schrieb: > (wobei letzteres auch eine sinnlose nop-Schleife > sein kann) ... oder einfach Schlafen.
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.
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
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.
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!
Tools wie Segger SystemView können dir anzeigen, wie viel Zeit du in welcher Funktion verbrauchst.
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.
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.