Hallo,
weiß jemand von euch wie man in Atmel Studio 7 festlegen kann, wie lange
(Zeit oder Cycles) ein Codeblock dauern soll, so dass der Compiler die
fehlende Zeit mit NOPs auffüllt?
Viele Grüße
blaudimau!
blaudimau schrieb:> weiß jemand von euch wie man in Atmel Studio 7 festlegen kann, wie lange> (Zeit oder Cycles) ein Codeblock dauern soll, so dass der Compiler die> fehlende Zeit mit NOPs auffüllt?
Ich wüsste nicht, dass irgendein Compiler dies könnte oder tun würde.
Man kann es so lösen:
- Zu Beginn des Codeblocks einen Timer starten
- Am Ende des Codeblocks den Timer pollen, bis Sollwert erreicht
Es geht leider genau darum nach Möglichkeit keine Timer zu verschwenden
:/
Wenn das kein Compiler kann, dann wohl saurer Apfel und Laufzeit messen
und NOPs manuell einfügen...
Falls niemand sonst eine Idee hat ;)
blaudimau schrieb:> Es geht leider genau darum nach Möglichkeit keine Timer zu verschwenden> :/> Wenn das kein Compiler kann, dann wohl saurer Apfel und Laufzeit messen> und NOPs manuell einfügen...> Falls niemand sonst eine Idee hat ;)
Und eine Schleife bauen, in welcher sich ein NOP befindet? Die
benötigten Schleifendurchläufe vorher ausrechnen...
Abgesehen davon, was heißt "Timer verschwenden"? Meist hat man doch
sowieso einen Timer laufen. Der kann das nebenher mit machen. Er muß
doch nicht nur eine Aufgabe bekommen bzw. man muß nicht für jede Aufgabe
einen separaten Timer nutzen.
blaudimau schrieb:> Es geht leider genau darum nach Möglichkeit keine Timer zu verschwenden> :/> Wenn das kein Compiler kann, dann wohl saurer Apfel und Laufzeit messen> und NOPs manuell einfügen...> Falls niemand sonst eine Idee hat ;)
Wenn eh ein Timer läuft, kannst du dir ja den Wert errechnen und dann
warten bis der Timer den Wert erreicht hat.
blaudimau schrieb:> C++ Codeblock soll eine bestimmte Zeit brauchen
Gegenfrage: Warum sollte man das wollen? Bzw. welches Problem willst Du
eigentlich lösen?
Und was ist wenn der Prozessor bei jedem Durchlauf unterschiedlich lange
braucht aufgrund vom Zustand der Pipeline, Cache, Bus-Auslastung usw.?
Dann funktioniert Takte zählen und NOP's einfügen nicht...
Mark B. schrieb:> Gegenfrage: Warum sollte man das wollen? Bzw. welches Problem willst Du> eigentlich lösen?
Es geht um eine Bibliothek die Pakete über eine Busleitung verschick.
Die Bibliothek soll demnach so wenig Hardware Ressourcen "verschwenden"
wie möglich, damit die für das Drumherum noch zur Verfügung stehen.
Da das Senden und Empfangen über einen Interrupt läuft, macht es bei den
kurzen Zeiten keinen Sinn, den Interrupt wieder zu verlassen (4 Cycles
hin, 4 wieder zurück...), deshalb ist auch ein Timer relativ nutzlos,
weil der max. 5 Cycles zählt bevor er wieder auslösen muss.
Programmierer schrieb:> Und was ist wenn der Prozessor bei jedem Durchlauf unterschiedlich lange> braucht
Mir wäre nicht bekannt, dass ein 8-Bit AVR im Hintergrund andere Sachen
treibt, die sich außerhalb von dem Bewegen, was in der Instruction Set
Summary aufgelistet ist. Wenn doch lass ich mich natürlich gerne eines
besseren belehren ;)
blaudimau schrieb:> Mir wäre nicht bekannt, dass ein 8-Bit AVR im Hintergrund andere Sachen> treibt, die sich außerhalb von dem Bewegen, was in der Instruction Set> Summary aufgelistet ist.
Wer redet hier von 8-Bit-AVR? Das Atmel Studio kann ja auch Cortex-M...
blaudimau schrieb:
1)
> Die Bibliothek soll demnach so wenig Hardware Ressourcen "verschwenden"> wie möglich, damit die für das Drumherum noch zur Verfügung stehen.
2)
> Da das Senden und Empfangen über einen Interrupt läuft, macht es bei den> kurzen Zeiten keinen Sinn, den Interrupt wieder zu verlassen (4 Cycles> hin, 4 wieder zurück...), deshalb ist auch ein Timer relativ nutzlos,> weil der max. 5 Cycles zählt bevor er wieder auslösen muss.
Vllt. jetzt zu kurz gedacht, aber wenn dein Programm die ganze Zeit
Pakete verschickt/empfängt 2), dann klingt für mich das so, als ob es
kein 1) geben kann, weil der µC nur mit Pakete bearbeiten zu 100%
ausgelastet ist.
Vllt. passt auch etwas am Design nicht. Zu viele zu kleine Pakete => der
µC hängt ständig in den beiden Interrups ... (nur als Gedanke ...)
blaudimau schrieb:> Es geht leider genau darum nach Möglichkeit keine Timer zu verschwenden> :/> Wenn das kein Compiler kann, dann wohl saurer Apfel und Laufzeit messen> und NOPs manuell einfügen...> Falls niemand sonst eine Idee hat ;)
NOP würde ich möglichst vermeiden. Damit verschwendest Du Rechenzeit.
Natürlich gibt es auch Fälle, wo sowas Sinn macht bzw. man es so machen
muss oder einfach nur der Einfachheit macht.
Programmierst Du eigentlich deine AVRs mit C++ oder geht es eigentlich
um ARMs???
Ja ich programmiere AVRs mit C++. Und ja ich rede von einem 8-Bit AVR.
Es geht mir nur darum wie ich es hinbekomme, dass ein Codeblock eine
bestimmte Zeit dauert. Lösungen mit Timern, etc. helfen mir dabei leider
nicht.
Die verschwendete Rechenzeit ist kein Problem.
Ich denke dann werde ich die NOPs nach Bedarf setzen.
Vielen Dank, euch allen ;)
Wenn Du schon C++ nimmst kannst Du das auch passend kapseln und erben.
Oder besser schau Dir mal Semaphoren an und wie man die implementiert.
NOPS sind immer der schlechteste Weg, was machste wenn der AVR
höher/niedriger getaktet wird ?
Timer sind wie schon erwähnt immer bei µC das passende, wo liegt das
Problem in der ISR eine weitere Variable mitzuzählen ?
Außer bei Super-simplen Funktionen ist Dein Vorhaben zum Scheitern
verurteilt.
Der Grund hierfür ist der, dass oberhalb des Super-simpel-Levels die
Laufzeit einer Funktion nicht vorhersehbar ist.
Spätestens bei der dritten Verzweigung (in "c" ein Einfaches if) gibt
eine kaum zu beherrschende Anzahl an verschiedenen möglichen
"Laufzeiten".
Natürlich kann ein an den Worst-Case angepasster Timer hier helfen. Dann
aber beißt sich die berühmt berüchtigte Katze in den eigenen Schwanz.
blaudimau schrieb:> Mir wäre nicht bekannt, dass ein 8-Bit AVR im Hintergrund andere Sachen> treibt, die sich außerhalb von dem Bewegen, was in der Instruction Set> Summary aufgelistet ist. Wenn doch lass ich mich natürlich gerne eines> besseren belehren ;)
Auch der hat Branch-Befehle, mit denen zur Laufzeit zwischen völlig
unterschiedlichen Codepfaden umgeschaltet werden kann.
Die verbrauchte Zeit auszählen und dann von Hand die entsprechende
Anzahl NOPs setzen ist Murks. Wenn du mal eine andere Compiler-Version
oder andere Compiler-Einstellungen nutzt, passt das nicht mehr.
blaudimau schrieb:> Es geht mir nur darum wie ich es hinbekomme, dass ein Codeblock eine> bestimmte Zeit dauert.
Warum kannst Du die delay.h nicht einsetzen?
Delays sind natürlich immer nur Minimalzeiten.
Sie verlängern sich um den anderen Code und um ausgeführte
Interrupthandler.
Wenn Du allerdings konstante Laufzeiten unabhängig von Verzweigungen
oder Variablen meinst, das geht nur mit Timern:
- starte Timer
- enable Timerinterrupt
- mache was
- sleep
Oder in Assembler, aber Sisyphos möchte dann nicht mit Dir tauschen.