Hallo, ich stehe gerade auf dem Schlauch und vielleicht kann mir ja jemand helfen. Ich habe ein LPC Xpresso Board mit LPC1347 und versuche die Arbeitsgeschwindigkeit nachzuvollziehen. Dafür habe ich die Beispielfirmware "periph_systick" genommen in der ich zu Beginn des Programms eine Endlosschleife eingefügt habe. Jeder Schleifendurchlauf erzeugt einen Pintoggle. int main(void) { /* Generic Initialization */ SystemCoreClockUpdate(); Board_Init(); while(1){ Board_LED_Toggle(0); } } void Board_LED_Toggle(uint8_t LEDNumber) { Board_LED_Set(LEDNumber, !Board_LED_Test(LEDNumber)); } void Board_LED_Set(uint8_t LEDNumber, bool On) { if (LEDNumber == 0) { Chip_GPIO_WritePortBit(LPC_GPIO_PORT, 0, 7, On); } } So weit so gut, die LED leuchtet. Die Frequenz an der LED habe ich gemessen und stelle überrascht fest, dass ich auf maximal 400kHz komme, obwohl die CPU nach meinem Verständnis mit 72MHz taktet. Es kann doch nicht sein, dass eine einfache While Schleife mit einem Toggle beinahe 100 CPU Takte verschlingt? Oder irre ich mich in der Annahme, dass die CPU mit 72MHz läuft? Wird die Prozessorgeschwindigkeit im Debug Modus heruntergesetzt? Oder macht mir die Definition der GPIO Ports ein Strich durch die Rechnung? Wo stelle ich die maximale Frequenz der GPIO Ports beim LPCXpresso ein? Ich habe eine Funktion gefunden, die den GPIO Block aber nur initialisiert, jedoch nicht die Frequenz einstellt. void Chip_GPIO_Init(LPC_GPIO_T *pGPIO) { Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO); } Ist da sonst noch irgendwo eine Einstellung?
Schau Dir mal das Disassembly z.B. im Debugger an. Da wird ein Function call inklusive Rücksprung drin sein. Vielleicht hilft schon der Optimizer etwas. Wenn Du schnellen Code haben willst, must Du schon die GPIO Register direkt beschreiben - oder einen Timer als PWM benutzen.
So wie die Fragestellung aussieht würde ich auch nicht davon ausgehen, dass der Fragesteller weiß mit welcher Frenquenz die CPU läuft. Und die Dokumentation zum LPC1347 hat er sich sicher auch nicht durchgelesen und versucht etwas zu verstehen. Nur mal schnell Rumstochern und dann das Forum arbeiten zu lassen finde ich etwas mutig...
@temp So wie die Antwortstellung aussieht, ist diese aber auch nicht besonders zielführend. Kluge Sprüche klopfen kann ich auch. Abgesehen mal davon, habe ich niemanden gebeten meinen Code zu verbessern. Mich interessiert nur die Ursache der Diskreptanz zwischen meinen Erwartungen und den Messwerten. Eigentlich dachte ich, dass ein Forum dafür da ist und nicht damit sich einige namenlose "Schlauköpfe" profilieren. Schäm dich. Aus dem Manual ist mir durchaus bekannt, dass die Werte in den Registern SYSPLLCTRL und SYSAHBCLKDIV für die Takterzeugung relevant sind. Die Clock selection war meines Erachtens auch korrekt. Seltsamerweise haben meine Veränderungen an MSEL und PSEL nicht zu erwarteten Ergebnissen geführt, obwohl der Debugger die entsprechenden Zeilen anstandslos abgearbeitet hat. Erst als ich das Projekt neu angelegt habe, konnte ich mit dem main clock spielen. Entscheidend bei der Fehlersuche war das Herausführen vom main clock an CLKOUT. @Jim Ich nehme an, dass die Codeausführung tatsächlich recht langsam ist und nun kein Weg an Disassembler und Taktezählen vorbei führt. Danke für die Tipps, ich werde die beherzigen.
Ich kann das auf meinem LPC1347 Board nachvollziehen. Der Takt wird schon richtig über die PLL auf 72 MHz gestellt. Nur im Code sind ja mehrere Unterprogrammaufrufe und da hängt es sehr an der Optimierung des Compilers. Wenn ich für die chip und board lib Optimization -o3 und -lto einschalte, für das Projekt auch -o3 dann komme ich auf 1,12 MHz. -lto darf beim Hauptprojekt nicht eingeschaltet sein, dann werden die lib Aufrufe wegoptimiert und der Pin toggelt nicht mehr.
Alexander schrieb: > So wie die Antwortstellung aussieht, ist diese aber auch nicht besonders > zielführend. Kluge Sprüche klopfen kann ich auch. Abgesehen mal davon, > habe ich niemanden gebeten meinen Code zu verbessern. Och, weder ich noch andere haben versucht deinen Code zu verbessern. Ausserdem ist das auch nicht deiner, wie du selbt geschrieben hast. Mal abgesehen von den 10 Zeilen. Alexander schrieb: > Mich interessiert > nur die Ursache der Diskreptanz zwischen meinen Erwartungen und den > Messwerten. Sorry, wie kannst du überhaupt von was Erwartungen haben was du nicht verstehst? Oder hast du die Lib die du verwendest analysiert und verstanden. Wenn ja, würden sich die Fragen erübrigen. Den Hinweis die GPIO Register sebst zu beschreiben hast du ja schon erhalten. Deine Eierei an den Optimierungen ist doch nur ein Nebenkriegsschauplatz. Gerade wenn es auf Highspeed bei GPIOs ankommt, ist jeder Aufruf einer Funktion aus einer Lib großer Mist. Für das Toggeln des Bits 7 im Port 0 reicht bei deinem uC folgende Zeile:
1 | while (1) |
2 | LPC_GPIO->NOT[0]=(1<<7); |
3 | |
4 | was als Assembler ergibt: |
5 | |
6 | 4A01 ldr r2, =0x50002300 |
7 | 2380 movs r3, #0x80 |
8 | 6013 str r3, [r2] |
9 | E7FD b 0x00000290 |
Dazu muss man aber das Usermanual gelesen haben. Und wenn man das hat, kommt man nicht auf die Idee schnelles GPIO-Handling mit Bibliotheksfunktionen zu machen. http://www.nxp.com/documents/user_manual/UM10524.pdf
Johannes S. schrieb: > -lto > darf beim Hauptprojekt nicht eingeschaltet sein, dann werden die lib > Aufrufe wegoptimiert und der Pin toggelt nicht mehr. Oder Dein Oszi ist zu langsam - oder der Pin selber, bei 72 MHz sieht man das eventuell nicht mal mehr im Oszi.
Jim M. schrieb: > Oder Dein Oszi ist zu langsam - oder der Pin selber, bei 72 MHz sieht > man das eventuell nicht mal mehr im Oszi. Nö, mit der Schleife ohne calls wie von temp beschrieben
1 | while (1) |
2 | LPC_GPIO_PORT->NOT[0]=(1<<7); |
tickert es für mein Oszi sicht- und messbar mit ziemlich genau 12 MHz. Das es mit den C-calls langsamer läuft ist klar und würde mich auch nicht stören, ich lasse selten LED per Software mit 800 kHz blinken. Und das die Linker Optimierung nicht immer funktioniert habe ich schon öfter gehabt, vor allem auch bei Code mit Debug Infos. Nachtrag: und auch meine mbed Variante mit bösem C++ läuft mir mit 2,2 MHz schnell genug:
1 | #include "mbed.h" |
2 | |
3 | int main() |
4 | {
|
5 | DigitalOut testPin(P0_7); |
6 | |
7 | while(1) { |
8 | testPin = !testPin; |
9 | }
|
10 | }
|
@temp Bittogle war nicht das Ziel, sondern nur ein Mittel zum Zweck. Ich bezweifle nicht deine Fachkompetenz, womöglich programmierst du auch die USB Schnittstelle selbst. An deiner arroganten Art solltest du jedoch nicht weniger arbeiten, als ich an meinen Mikrocontrollerunkenntnissen. An der Optimierung herumzueiern habe ich gar nicht vor, ich denke da hast du unbewusst auf einen Beitrag von Johannes reagiert. Deine kurze und knappe Antwort hätte es von vornherein auf den Punkt bringen können: "Der Code ist einfach schlecht und wenn man Wert auf die Performance legt, sollte man nicht auf Standardbibliotheken setzen, sondern alles selbst programmieren. GPIO Takt ist bei LPC1347 gleich dem main clock in Verbindung mit dem System Clock Divider. Main Clock lasst sich wiederum an CLKOUT Pin herausführen und einfach nachmessen. Nachzulesen auf Seite 12ff UM10524." Ich danke allen für die Hilfe. Auch dir temp, obwohl mir deine Art zu antworten nicht besonders schmeckt. Das Problem hat sich für mich erledigt.
auf so Provokationen solltest du hier gar nicht eingehen, Programmiersprachen, OS, 8 oder 32 Bit µC und noch einiges sind Religionen hier und die Diskussionen versauen dann nur die Threads. Und gerade die selbstgekrönten Assemblergötter lauern nur auf solche Themen. Ich habe das jedendsfalls so verstanden das es nur ein Test war und dann die Enttäuschung das da soviel Overhead reinkommt. Aber so ein Beispiel taugt mMn nicht zur Beurteilung der Leistung, ein paar Takte mehr oder weniger liefern sofort grob unterschiedliche Frequenzen. Interessanter an dem LPC1347 ist die gute Peripherie wie die vielen 32 Bit Timer und USB incl. Ansteuerung dazu im ROM.
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.