Vorweg: bitte nagelt mich nicht ans Kreuz, ich habe mit dem Programmieren bis lang noch nicht so viel Erfahrung gesammelt. Ich habe einen 3-phasigen PFC Gleichrichter und soll für diesen einen Regler programmieren. Das habe ich gemacht und das ganze funktioniert bis jetzt eigentlich recht gut. Das Problem dabei ist die in meinen Augen nicht schöne Umsetzung: meine CPU verbringt nämlich 3/4 der Zeit in einer Interrupt Routine und rechnet dabei mit vielen floats einige dq-Transformationen, Strom- und Spannungsregler und eine PLL (also unter anderem einige sin/cos, sqrt und pow()). Die Plattform ist ein Zynq SoC. Getriggert wird die ISR von meinem PWM Counter. Die Fragen die ich mir nun stelle: - Wie macht man sowas "richtig", also ohne 3/4 der Zeit in der ISR zu stecken? Das ganze funktioniert prinzipiell, allerdings habe ich das Gefühl, miserable Software mit gewaltigem Übermass an Rechenpower erschlagen zu haben. Ohne gross Erfahrung zu haben gehe ich doch davon aus, für eine "normale" PFC nicht einen ARM Cortex A9 so auszulasten. - Ganz allgemein (nicht nur auf diese Anwendung bezogen) würde mich interessieren, ob und falls ja wieviel Rechenleistung ich einsparen könnte, wenn ich fixed point Arithmetik anstatt Gleitkommazahlen verwende. Da ich sin/cos/sqrt Berechnungen verwendet gehe ich davon aus, dass das Einsparpotential an der Stelle gering ist (solange diese Operationen drin bleiben). Wie sieht das aber auf modernen CPUs allgemein aus, vor allem wenn ich (wie hier) sehr wenig Daten habe (alles passt in den Cache). Dauern Addieren/Multiplizieren/Dividieren auf modernen CPUs mit FPU länger oder gleich lang wie äquivalente Fixpunktoperationen?
Das ist schwer zu beantworten ohne weitere, detaillierte Angaben deinerseits. Wie oft wird die ISR aufgerufen und welche Schaltfrequenz verwendest du? Führst du Berechnungen durch, die man einmalig zuvor ausführen kann, und nur die Ergebnisse verwendet?
Die Interrupt-Frequenz (identisch mit der doppelten Schaltfrequenz) ist ca. 75 kHz. Dinge vorausberechnen kann ich nicht, ich habe nur in die ISR gesteckt was von den Messwerten abhängt.
Rechenleistungs-Verschwender schrieb: > Wie macht man sowas "richtig", also ohne 3/4 der Zeit in der ISR zu > stecken? Was stört dich daran? Je nach Anwendung kann es für so eine Applikation das performanteste sein. Ob der Code nun in der ISR läuft oder nicht, ändert ja nix daran, dass die CPU zu 3/4 ausgelastet ist. Und wenn du deterministisch genau zu jedem PWM/ADC-Zyklus den Regler rechnen musst, bietet es sich halt an, das direkt im entsprechenden Interrupt laufen zu lassen. Dass in der Hauptschleife dann nur noch untergeordneter Kram dran kommt, erklärt sich von selbst. Alles eine reine Architekturabwägung. Rechenleistungs-Verschwender schrieb: > Ohne gross Erfahrung zu haben gehe ich doch davon > aus, für eine "normale" PFC nicht einen ARM Cortex A9 so auszulasten. Ohne deine Schaltfrequenz und den Prozessor zu kennen: eher nein. Aber ein Cortex A9 ist auch nicht die Architektur der Wahl für sowas. Compileroptimierung eingeschaltet? Du kannst dir jedenfalls sicher sein, dass in wesentlich kleineren Prozessoren mit geeigneter Architektur und vernünftige Code (und das Problem liegt nicht in der ISR!) komplexe antriebstechnische Aufgaben wie Mehrachsantriebe realisiert werden. Selbst ohne Compileroptimierung. Rechenleistungs-Verschwender schrieb: > Strom- und Spannungsregler und eine PLL (also unter > anderem einige sin/cos, sqrt und pow()) Es gibt ziemlich schnelle Softwareimplementierungen für sowas, die, gegen die für einen A9 gelinkt wird, wird wohl eher nicht so darauf optimiert sein. Ein Beispiel wäre die C2800er-Reihe von TI (natürlich tendenziell Overkill für eine PFC, aber das ist ein A9 auch). Texas bietet sowohl schnelle Implementierungen in Software, als auch Prozessoren mit Hardwarebeschleunigung für sowas. Nebenbei ist pow() für quadrieren (je nach Compiler und Code) tendenziell langsamer als x * x. Rechenleistungs-Verschwender schrieb: > Ganz allgemein (nicht nur auf diese Anwendung bezogen) würde mich > interessieren, ob und falls ja wieviel Rechenleistung ich einsparen > könnte, wenn ich fixed point Arithmetik anstatt Gleitkommazahlen > verwende. Kommt, wer hätte das gedacht, auf den Prozessor an. Eher nicht viel. Wenn es keine wichtigen Gründe dafür gibt (bestehender Prozessor, der $wichtiges_feature) sonst nicht packt, oder auf biegen und brechen ein kleinerer Prozessor verwendet werden muss um im Einkauf ein paar Cent zu sparen: den Aufwand nicht wert. Rechenleistungs-Verschwender schrieb: > Wie sieht das aber auf modernen CPUs > allgemein aus, vor allem wenn ich (wie hier) sehr wenig Daten habe > (alles passt in den Cache). Für sowas nimmt man keine Applikationsprozessoren, dann stellt sich die Frage "Cache oder nicht" gar nicht erst. Rechenleistungs-Verschwender schrieb: > Dauern Addieren/Multiplizieren/Dividieren > auf modernen CPUs mit FPU länger oder gleich lang wie äquivalente > Fixpunktoperationen? Datenblatt lesen.
Rechenleistungs-Verschwender schrieb: > Die Interrupt-Frequenz (identisch mit der doppelten Schaltfrequenz) ist > ca. 75 kHz. Ein 2000er macht dir die Stromregelschleife im einstelligen µs-Bereich.
Vielleicht wäre ein uC der C2000 von TI etwas für dich, der speziell für 3phasen Systeme passende dq Transformationen anbietet sowie code-optimierte PI Regler. Gruß,
Auf keinen Fall nimmt man einen Application Prozessor. Cortex M4 oder Cortex M7 von beliebigem Hersteller reicht. Nicht TI, viel zu teuer. NXP oder STM. Maches kannst du in langsamere ISR auslagern. Statt PLL und Clark, Park Transformation kann man auch mit Spannungs-Feedforward zur Regelstrecken-Linearisierung arbeiten, das spart dann auch noch Zeit. pow() und den ganzen anderen Schmarrn brauchst du nicht. Für sin/cos nimmt man LUTs mit linearer interpolation. Falls du einen Cortex M7 aussuchst, kann der zwar Floating Point, aber Fixed Point reicht für alles, was du dir im Bereich PFC vorstellen kannst. Meist sind Fixed Point Befehle 1-2 Zyklen schneller als FP.
Rechenleistungs-Verschwender schrieb: > Ich habe einen 3-phasigen PFC Gleichrichter und soll für diesen einen > Regler programmieren. Das habe ich gemacht und das ganze funktioniert > bis jetzt eigentlich recht gut. Das Problem dabei ist die in meinen > Augen nicht schöne Umsetzung: meine CPU verbringt nämlich 3/4 der Zeit > in einer Interrupt Routine und rechnet dabei mit vielen floats einige > dq-Transformationen, Strom- und Spannungsregler und eine PLL (also unter > anderem einige sin/cos, sqrt und pow()). Naja, ich hab hier eine 2phasige PFC, die läuft auf einem 60 MHz PICCOLO von TI, da wird alles in Festkommaarithmetik in 32 Bit gerechnet. Das reicht locker. "Nebenbei" laufen auch noch drei andere PID-Regler im Interrupt @100kHz und erzeugen dadurch ca. 50% CPU-Grundlast. Aber selbst wenn es 75% wären, wäre das OK, wenn alle zeitkritischen Anforderungen erfüllt werden. Es gibt kein Geld zurück für ungenutzte CPU-Leistung. > Gefühl, miserable Software mit gewaltigem Übermass an Rechenpower > erschlagen zu haben. Damit liegst du voll im Trend! ;-) > Ohne gross Erfahrung zu haben gehe ich doch davon > aus, für eine "normale" PFC nicht einen ARM Cortex A9 so auszulasten. Nö. > verwende. Da ich sin/cos/sqrt Berechnungen verwendet gehe ich davon aus, Naja, wozu brauchst du die denn? Eine normale PFC braucht die nicht, außer vielleicht die Wurzel, die aber nur am Ende einer Periode. In meinem Projekt, das auf einem Eval-Kit von TI aufbaut, läuft neben der 100kHz ISR (in Assembler) noch eine 10kHz ISR in C. Dort wird der Überwachungskram berechnet, spricht, Effektivwerte für Strom und Spannung. Aber die werden nur einmal pro Periode berechnet, sonst läuft nur die Akkumulation von U, I bzw. I^2. > dass das Einsparpotential an der Stelle gering ist (solange diese > Operationen drin bleiben). Wie sieht das aber auf modernen CPUs > allgemein aus, vor allem wenn ich (wie hier) sehr wenig Daten habe > (alles passt in den Cache). Dauern Addieren/Multiplizieren/Dividieren > auf modernen CPUs mit FPU länger oder gleich lang wie äquivalente > Fixpunktoperationen? Vermutlich gleich lang bis kürzer, ist ja schließlich eine Hardware-FPU.
Falk B. schrieb: > Naja, wozu brauchst du die denn? Eine normale PFC braucht die nicht, Es geht hier nicht um normal oder nicht-normal, sondern um 1phasig oder 3phasig. Und da unterscheiden sich die beiden Lösungen nunmal gewaltig. Es ist allgemein bekannt, dass PI Regler nur bei DC eine Regelabweichung von 0 haben. Bei 50Hz AC kann ein PI Regler per Definition die Regelabweichung nicht eliminieren, sondern höchsten reduzieren. Das schöne an 3phasigen Systemen ist, dass man mittels Clark/Park Transformation ein 3phasiges AC System in ein einphasiges DC System überführen kann. Genau dieses Prinzip nutzt man, um das resultierende magnetische Feld in 3phasigen AC Maschinen zu beschreiben. Sobald man das 3phasige AC System ins 1phasige DC System transformiert hat, kann man dort die Regelung mittels gewöhnlicher PI Regler ausführen, und dann anschließend alles zurück ins 3phasige System transformiert. Natürlich geht es auch ohne Clark/Park, das machen aber nur Amateure und Bastler. Gruß,
asdfjklö schrieb: > Cortex M4 oder Cortex M7 von beliebigem Hersteller reicht. Nicht TI, > viel zu teuer. NXP oder STM. Als ob bei einem Einzelstück der Preis wichtig wäre.
Vielen Dank für die Antworten, ich habe einige interessante Inputs bekommen. Allem voran ist mir der Begriff "Applikationsprozessor" nicht wirklich geläufig und mir war auch nicht bewusst, so etwas vor mir zu haben. Google spuckt auch keine exakte Definition dazu aus sondern mehr eine Sammlung von verschiedenen Merkmalen die je nachdem vorhanden sein können oder nicht. Könnt ihr mir ein paar konkrete Anhaltspunkte dazu nennen? Verschwender schrieb: > Ohne deine Schaltfrequenz und den Prozessor zu kennen: eher nein. > Aber ein Cortex A9 ist auch nicht die Architektur der Wahl für sowas. > Compileroptimierung eingeschaltet? Compileroptimierung ist an und auf "-O3". Verschwender schrieb: > Nebenbei ist pow() für quadrieren (je nach Compiler und Code) > tendenziell langsamer als x * x. Das hätte ich eigentlich wissen können, hatte ich aber vergessen. Falk B. schrieb: > Damit liegst du voll im Trend! ;-) Genau das finde ich nicht unbedingt erstrebenswert ;) Ausserdem ist deine CPU offenbar mehr als 10 mal langsamer und erledigt mehr Jobs als mein Programm. Das schreit für mich nach grobem Unfug den ich fabriziert habe. Falk B. schrieb: > Vermutlich gleich lang bis kürzer, ist ja schließlich eine Hardware-FPU. Ich war mir nicht sicher ob die Hardware FPU so schnell ist, habe es aber vermutet. Solange als eine Hardware FPU vorhanden ist sollte es keinen Unterschied machen, ob ich float oder int einsetze.
Hilft sowas hier weiter? https://arm-software.github.io/CMSIS_5/DSP/html/group__groupController.html
Wenn notwendig & auch möglich, versuche Berechnungen durch Lookup-Tabellen zu ersetzen und v.a. Divisionen wegzubekommen (das frißt Rechenzeit). Speziell Deine winkelfunktionen lassen sich durch eine einzige sin-Tabelle, erweitert um 90° für den Cos, locker ersetzen.
Rechenleistungs-Verschwender schrieb: > Allem voran ist mir der Begriff "Applikationsprozessor" nicht > wirklich geläufig und mir war auch nicht bewusst, Ein "Application Processor" ist ein Prozessor, der für allgemeine Anwendungsausführung (im Zusammenspiel mit einem Betriebssystem) ausgelegt ist. Also mit MMU und Speicherschutz, Caches, höherem Stromverbrauch und dem ganzen Pipapo. Ein Gegenstück sind dann z.B. digitale Signalprozessoren (DSPs), wie die genannten C2000. Die haben solche Spielereien eher nicht, aber dafür garantierten Datendurchsatz, spezielle Hardware, spezielle Befehlssätze (z.B. Fixpoint-Arithmetik oder FFT-Bausteine) und sowas. Die sind in der Regel auch schneller in einer ISR. Hast du mal zum Vergleich getestet, wie viel Last eine leere 75 kHz-ISR auf deinem System verursacht? Vielleicht kann man da etwas optimieren.
Vorallendingen sind Applikationsprozessoren überhaupt nicht für derartige Interruptraten ausgelegt. Dies sind dafür gedacht das da ein Linux o.ä. drauf läuft. Da sprechen wir typischerweise von Taskwechseln mit 100Hz, also alle 10ms. Hochfrequente Interrupte sind tödlich für diese Cores. Der hat eine 8 stufige Pipeline die geleert und wieder gefüllt werde muss, wenn die FPU benutzt wird müssen deren Register auch mit gesichert werden und eine MMU ist da auch noch. Bis der überhaupt in der ersten Anwenderinstruktion der ISR angekommen ist, hat ein M4 schon die halbe ISR fertig gemacht: Die Interruptlatenz eines M4 beträgt 12 Takte bei Zero-Waitstate RAM, d.h. ein 100 Mhz Cortex-M4 braucht ca. 0.2µs bis er im Interrupt ist. Ein Cortex A9 braucht, wenn man eine normale Applikation in der Main-Loop hat, im Mittel ca 800 Takte bis er im Interrupt steht, d.h. selbst ein 1Ghz A9 braucht 7mal länger als der CM4 um überhaupt erstmal in der ISR anzukommen. Das hat hier jemand schön untersucht (Bare-Metal System): https://www.jblopen.com/improving-interrupt-latency-on-the-cortex-a9/ Warum wird überhaupt der A9 benutzt? Der Zynq hat doch ein FPGA.
Vielen Dank für die Antworten. Was ihr schreibt macht für mich Sinn, war mir aber nicht bewusst (zumindest nicht in dem Ausmass). Andreas M. schrieb: > Das hat hier jemand schön untersucht (Bare-Metal System): > > https://www.jblopen.com/improving-interrupt-latency-on-the-cortex-a9/ Das hat mich echt überrascht, ich hätte nicht ansatzweise erwartet, dass die CPU 800 Zyklen (oder bis zu 1780 im Worst Case in dem Beispiel) braucht bis sie in der ISR steht. Ich wusste, dass bei modernen CPUs die Ausführungszeit nicht genau im Voraus bestimmt werden kann (wegen Cache-Hit/Miss, Branch Prediction, und solchen Dingen). Dass die Unterschiede aber so gewaltig sind und vor allem so streuen hätte ich nicht erwartet. Das bringt mich auf den unguten Gedanken, dass ich bis jetzt auch einfach Glück gehabt haben könnte. Wenn ich das Programm erweitere könnte es in dem Fall passieren, dass die ISR in einem sehr ungünstigen Fall plötzlich doppelt so lange dauert und damit nicht mehr vor dem nächsten Trigger fertig wird. Bei einer PFC die am Netz hängt gefällt mir der Gedanke überhaupt nicht. Zum Glück habe ich einen Watchdog im Hintergrund laufen, der am Ende der ISR jedes Mal zurückgesetzt wird, das würde mir in dem Fall wohl den Arsch retten. Andreas M. schrieb: > Warum wird überhaupt der A9 benutzt? Der Zynq hat doch ein FPGA. Man könnte das alles ins FPGA packen, die Entwicklung der entsprechenden FPGA Cores hätte mich aber sehr viel mehr Zeit gekostet (bin leider auch nicht so fit in VHDL, hatte schon mit den entsprechenden Einheiten für PWM-Generierung usw. meine Mühe). Oder hättest du einen kleinen und schnellen Software auf dem FPGA implementiert und das Programm dann für diesen geschrieben? Benutzt habe ich den Zynq im wesentlichen deshalb, weil er gerade rumlag und ich nichts anderes zur Verfügung hatte. Offensichtlich nicht die beste Wahl, der Lerneffekt durch das Projekt war auf jeden Fall recht erheblich ;)
Rechenleistungs-Verschwender schrieb: > FPGA Cores hätte mich aber sehr viel mehr Zeit gekostet (bin leider auch > nicht so fit in VHDL, hatte schon mit den entsprechenden Einheiten für > PWM-Generierung usw. meine Mühe). Oder hättest du einen kleinen und > schnellen Software auf dem FPGA implementiert und das Programm dann für > diesen geschrieben? Naja für mich wäre VHDL auch komplett neu, aber alleine aus Interesse hätte ich die Zeit darein gesteckt, das Thema interessiert mich brennend, habe nur keinen Anwendungsfall. Ich kenne jetzt die Algorithmik die man für PFC braucht nicht, aber ich würde erwarten, dass Effektivste under vermutliche auch Einfachere wäre das ganze komplett im FPGA zu lösen ohne den Umweg über einen Softcore. Ich denk mal es ist ein statischer Regelalgorithmus ohne irgendwelche Verzweigungen, also immer der gleiche Ablauf. Den Softcore muss man ja auch erst verstehen.
Andreas M. schrieb: > Naja für mich wäre VHDL auch komplett neu, aber alleine > aus Interesse hätte ich die Zeit darein gesteckt, [...] Sagen wir's mal so... ich hab einen VHDL-Kurs belegt und hätte trotzdem unglaublich viel Zeit darin versenkt, eine zuverlässige Lösung zu bauen. Das kann man so machen, wenn man VHDL lernen will - wenn es darum geht, irgendwann eine Lösung zu haben (und diese auch zukünftig warten zu können, wenn man mal länger kein VHDL angefasst hat), ist eine Softwarelösung eher besser. Aus der Sicht hat der TO schonmal nicht falsch gehandelt. Andreas M. schrieb: > komplett im FPGA zu lösen ohne den Umweg über einen Softcore Das ist schon ohne Softcore gelöst. :-) Der Zynq ist ein "Dualcore-ARM mit FPGA drin". Wenn du da den ARM nicht nutzt, ist er trotzdem da. Ich bin mir nur gerade nicht sicher, ob man den FPGA auch komplett ohne ARM nutzen kann (in unserem Projekt wurde der FPGA vom ARM-Linux aus konfiguriert).
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.