Forum: Mikrocontroller und Digitale Elektronik LPC1347 GPIO taktet zu langsam


von Alexander (Gast)


Lesenswert?

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?

von Jim M. (turboj)


Lesenswert?

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.

von temp (Gast)


Lesenswert?

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...

von Alexander (Gast)


Lesenswert?

@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.

von Johannes S. (Gast)


Lesenswert?

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.

von temp (Gast)


Lesenswert?

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

von Jim M. (turboj)


Lesenswert?

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.

von Johannes S. (Gast)


Lesenswert?

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
}

von Alexander (Gast)


Lesenswert?

@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.

von Johannes S. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.