Millis versus Centis auf der AVR-Plattform

Ich baue ein Gerät auf der AVR-Plattform. Das Gerät benötigt einige Timing-Informationen, daher dachte ich daran, die Arduino- millisähnliche Funktionalität neu zu implementieren (wenn auch nicht genau so ). Nachdem ich jedoch einige Hüllkurvenberechnungen durchgeführt hatte (teilweise basierend auf diesem Beitrag ), schien es mir, dass millismindestens 5% der CPU-Zeit auf einem 20-MHz-Prozessor und proportional mehr als auf einem 16-MHz-Prozessor verbraucht werden:

  • Jede Millisekunde, die der Timer (timer0) überläuft, löst einen Interrupt aus, der inkrementiertmillis
  • Eine ISR sollte 26 Takte für die Prä-/Post-ISR-Routine benötigen (5 PUSH+ POPplus CLR, IN, undRETI
  • Die ISR selbst sollte ungefähr 21 Takte dauern (32-Bit-Wert laden, inkrementieren und wieder im SRAM speichern).
  • Dies ergibt fast 50 Takte oder 50 Mikrosekunden pro Millisekunde.
  • Tatsächlich ist die Arduino ISR-Funktion langsamer (wie in diesem Beitrag gezeigt ), weil sie wirklich darauf achtet, Millis so genau wie möglich zu halten, was immer noch mehr CPU-Zyklen dauert

Ich brauche keine millisPräzision, also denke ich darüber nach, Prozessorzyklen für andere Dinge zu implementieren centisoder sogar zu sparen. decisIst das unvernünftig? Sind meine Berechnungen falsch? Es scheint eine seltsame Designwahl zu sein, oder übersehe ich etwas?

Wenn Sie es nicht für die Endbenutzerprogrammierung erstellen, verzichten Sie auf irgendeine Funktion dafür und nehmen Sie das Timing einfach auf die altmodische Weise vor.
Hast du nicht 20MHz? Dann sind 50 Taktzyklen ungefähr 3 us und nicht 50. Haben Sie auch den generierten Maschinencode überprüft, um festzustellen, ob Ihre Zahlen korrekt sind - sie scheinen mir etwas hoch zu sein
@TomL. Ja, Sie haben Recht, die 20 vorne vergessen, ich habe die CPU-Geschwindigkeit als 1 MHz behandelt. Ich habe den Arduino-Code nicht dekompiliert. Was erscheint hoch?
@IgnacioVazquez-Abrams Was ist "Timing auf die altmodische Art"?
Finden Sie heraus, wie viel Zeit Sie brauchen, stellen Sie den Timer ein und lassen Sie ihn los.
Nun, ich muss mehrere Ereignisse zeitlich festlegen, die unterschiedliche Zeitüberschreitungsintervalle haben, daher Millis oder Äquivalent.
Zu Ihren Berechnungen: Sind Sie auf einem 8-Bit- oder 32-Bit-Gerät? Außerdem macht der Optimierer einige Operationen sehr effizient (vielleicht können einige Lade-/Speicheroperationen in einem einzigen Zyklus durchgeführt werden). Es hängt sehr stark von Ihrer Plattform ab, daher sollten Sie den Code, der generiert wird, um diese Schätzungen vorzunehmen, wirklich überprüfen
Ich finde die „millis“-Funktion eine ganz nette Idee für einen einfachen Planer, wenn man mehrere Aufgaben zur Hand hat; Ich habe in den letzten 10 Jahren eine nahezu identische Implementierung verwendet.

Antworten (1)

50 Takte sind bei 16 MHz nicht 50 us, sondern etwa 3 us. Also 0,3 % Overhead, nicht 5 %. Sie können das sicherlich tun, aber ich hatte noch nie Probleme damit, einen kleinen ISR bei 1 kHz so zu betreiben. Es könnte eine gute Idee sein, es neu zu implementieren, nur damit Sie mehr Dinge hinzufügen können, die bei jedem Timer-Tick ausgeführt werden, oder Dinge planen können, die bei zukünftigen Ticks ausgeführt werden. Eine Methode, die ich ziemlich oft verwende, ist, etwas so zu planen, dass es z. Wenn ein Tick übersprungen wird, wird der aktuelle Anruf nur um einen Tick verzögert. Es wäre sehr einfach, diese Methode zu verwenden, um Dinge in 10-ms- oder 100-ms-Intervallen auszuführen.