Ich habe bis jetzt nur mit AVR gearbeitet. Da ich für ein kommendes Projekt viel rechnen muss habe ich mir mal das Keil ARM Eval Kit runtergeladen. Dann habe ich einfach mal in das Blinky Beispiel folgende Berechnung eingefügt: Static float x = 3.14; X = sin(x); Im Keil Simulator benötigt der LPC im ARM Modus ca. 25.000 Zyklen und ca. 400µs für die Berechnung bei 60MHz Takt. Mein AVR mit 20 MHz Takt mit WINAVR benötigt für dieselbe Berechnung die gleiche Zeit. Ist das normal das der LPC (bzw. die Keil sinus lib) so langsam ist? Gruß Bernd
Ich weiß nicht was die Keil Lib da macht aber die sin() Funktion rechnet eigentlich mit doppelter Genauigkeit. Da hilft es auch nicht einen float zu übergeben. Das das 25000 Takte dauern soll überrascht mich aber schon etwas. Der avr-gcc verwendet bei Gleitkomma immer 'float'. Mit dem Codevision AVR dauert die Rechnung übrigens 130µs. Der rechnet wie der GCC mit 32bit. - Michael
Ich will es ja auch nicht glauben, dass das so lange dauert - ist aber so (auch wenn er mit double rechnet). Vielleicht kann ich ja cuh nicht die Keil IDE bedienen.
Ich habe das jetzt mal gemessen:
1 | volatile unsigned int value1, value3; |
2 | volatile float x = 3.14; |
3 | |
4 | //! test
|
5 | value1 = T0TC; |
6 | x = sin(x); |
7 | value3 = T0TC; |
8 | value3 -= value1; |
9 | rprintf("Ergebnis: %u\n", value3); |
10 | // /test
|
11 | |
12 | .lss: |
13 | //! test
|
14 | value1 = T0TC; |
15 | 598: e2865901 add r5, r6, #16384 ; 0x4000 |
16 | 59c: e5953008 ldr r3, [r5, #8] |
17 | 5a0: e59f60ec ldr r6, [pc, #236] ; 694 <.text+0x694> |
18 | 5a4: e5863000 str r3, [r6] |
19 | x = sin(x); |
20 | 5a8: e59f40e8 ldr r4, [pc, #232] ; 698 <.text+0x698> |
21 | 5ac: e5940000 ldr r0, [r4] |
22 | 5b0: eb000fff bl 45b4 <__aeabi_f2d> |
23 | 5b4: eb000748 bl 22dc <sin> |
24 | 5b8: eb0011aa bl 4c68 <__aeabi_d2f> |
25 | 5bc: e5840000 str r0, [r4] |
26 | value3 = T0TC; |
27 | 5c0: e5953008 ldr r3, [r5, #8] |
28 | 5c4: e59f10d0 ldr r1, [pc, #208] ; 69c <.text+0x69c> |
29 | 5c8: e5813000 str r3, [r1] |
30 | value3 -= value1; |
31 | 5cc: e5913000 ldr r3, [r1] |
32 | 5d0: e5962000 ldr r2, [r6] |
33 | 5d4: e0623003 rsb r3, r2, r3 |
34 | 5d8: e5813000 str r3, [r1] |
35 | rprintf("Ergebnis: %u\n", value3); |
36 | 5dc: e5911000 ldr r1, [r1] |
37 | 5e0: e59f00b8 ldr r0, [pc, #184] ; 6a0 <.text+0x6a0> |
38 | 5e4: eb000042 bl 6f4 <rprintf> |
39 | // /test
|
Der Timer0 zählt mit einer Auflösung von 1µs und die Ausgabe ist: "Ergebnis: 48" Gerechnet wird mit double. Das ganze läuft auf einem LPC2148 bei 60MHz. Compiler: arm-elf-gcc (GCC) 4.1.2 (WinARM 4/2007) - Michael
Hi, Danke für deine Mühe. Ich habe jetzt auch mal den Timer mitlaufen lassen - mit dem gleichen Ergebnis. Mit der Keil GNU IDE bekomme ich nach der sin Berechnung einen Timerwert von 459 = 459 µS. Also ca. den Faktor 10 langsamer als bei dir. Ich habe mal meinen Code mit Startup usw. beigefügt. Vielleicht kannst du ihn mal bei dir testen?
Für die Addition von zwei ints brauche ich 15 Takte - bei doubles schon 660 Takte. Muss ich vielleicht eine spezielle lib für floating point einbinden?
Seltsam. Ich prüfe noch mal meine Timer-Konfiguration. Der Teiler steht auf 60-1 aber vielleicht ist die PClk langsamer als 60MHz. Am besten lasse ich mal eine LED im Sekundentakt timergesteuert blinken. Mal sehe ob ich heute Abend dazu komme weiter zu forschen bzw. deinen Code laufen zu lassen. - Michael
Sorry, hat etwas gedauert. Ich habe mir mein Programm bzw. die Konfiguration nochmal angesehen und ich bin mir sicher das F_CLK = P_CLK = 60MHZ ist. Toggeln einer LED und rücksetzen von Timer0 wenn T0TC 1.000.000 erreicht hat führt zu einer Blinkfrequenz von 0,5Hz (1s an, 1s aus). Dein Testprogramm habe ich nicht laufen lassen aber die startup.s habe ich mir angesehen. Meiner Ansicht nach stimmt die PLL Initialisierung nicht.
1 | .equ PLLCFG_MSEL, (0x1F<<0) /* PLL Multiplier */ |
2 | .equ PLLCFG_PSEL, (0x03<<5) /* PLL Divider */ |
Das sind die Konstanten M und P. P steht hier auf 8, was völlig O.k ist aber M ist 32. Laut dem PLL-Tool von Philips entspricht das (theoretisch) einer F_CLK von 384MHz. Bei einem 12MHz Quarz müßte M=8 sein. Was passiert denn wenn du die MSEL Zeile wie folgt abänderst:
1 | .equ PLLCFG_MSEL, (0x04<<0) /* PLL Multiplier */ |
Vielleicht interessiert sich der Simulator aber auch gar nicht dafür (ich habe den nie benutzt). Wenn ich das richtig überblicke wird in der timer.c der Timer durch den Match-Interrupt alle 155µs zurückgesetzt und 'timeval' um eins hochgezählt. Zumindest dann wenn der Kern mit 60MHz getaktet wird. Die Peripherie läuft dann mit 30MHz. - Michael
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.