Forum: Mikrocontroller und Digitale Elektronik Leisungsvergleich ARM AVR


von leluno (Gast)


Lesenswert?

Mein 16Mhz-Atmega1284 füllt einen 320x240 SPI-TFT (153600Bytes) mit 
186.000 Bytes/sec.

Mein 100Mhz-LPC1768 schafft das mit 480.000 Bytes/sec.

Die Verarbeitung des Datenstroms eines OV7670-Bildsensors kann der AVR 
mit 115.000Bytes/sec, der ARM mit nur 35.000 Bytes/sec.

Verwendet wird jeweils der gleiche code:
1
Timer=0;
2
if(!(vsync)){while(!(vsync));}
3
while(vsync);
4
/*
5
while(zl_row<20*teilbild){
6
while(!href);//Warten auf href_h
7
while(href);
8
zl_row++;
9
}*/
10
//start frame
11
zl_row=240;
12
while(zl_row){
13
while(!(href));//Warten auf href_h
14
while(href){
15
// +++ px ++++
16
  while(!(pclk));
17
    SSP0DR=Value_Datenbus;
18
//    S0SPDR=Value_Datenbus;
19
//    SPDR=PIN(Value_Datenbus);
20
//    buffer[zl_pix]=Value_Datenbus;
21
  while(pclk);
22
  zl_pix++;
23
}//zl_row
24
zl_row--;
25
}//end frame
26
zl_performance=Timer;


Wodurch kommt es zum Leistungsabfall beim ARM gegenüber dem AVR? Mit dem 
SSP scheint es nichts zu tun zu haben. Auch das Schreiben in einen 
buffer klappt nicht besser. Wird der code beim ARM anders compiliert?

von Uwe B. (derexponent)


Lesenswert?

deine Frage kann ich dir leider nicht beantworten

aber wenn du einen ARM F4 mit DCMI-Interface für die Camera benutzt,
sind 4,6 MByte/sec zu schaffen wenn er die Daten nur aufs Display
schaufeln muss
(nur als Info, wenn du was schnelleres brauchst)

Gruss Uwe

von Achim S. (Gast)


Lesenswert?

die Laufzeit dieses Codes ergibt sich doch größtenteils durch das Warten 
Flanken von pclk. Damit sollte die Laufzeit primär vom Timing deines 
Bildsensors bestimmt sein, nicht vom verwendeten µC (außer wenn er so 
langsam ist, dass er den Bildsensor nicht mehr richtig bedienen kann).

Wenn du einen Faktor 3 Unterschied in der Ausführungsgeschwindigkeit 
siehst: prüfe mal nach (Oszi), ob der Bildsensor jeweils gleich 
konfiguriert wurde und ob pclk jeweils die gleiche Frequenz hat. Wenn 
das nicht der Grund ist, würde ich als nächstes die Laufzeitmessung mit 
"Timer" überprüfen.

von Lothar (Gast)


Lesenswert?

leluno schrieb:
> Verwendet wird jeweils der gleiche code:

Soll das heissen der ARM muss mit char und short Variablen 
zurechtkommen? Der ARM kann nur 32-bit Speicherzugriff effektiv 
ausführen.

Ansonsten kommt es schon auf den Compiler an. Es wäre aber auch möglich 
die paar Zeilen in Assembler zu schreiben, um sicherzugehen.

von Tester (Gast)


Lesenswert?

leluno schrieb:
> Verwendet wird jeweils der gleiche code

Mmmmhhh, findet im Hintergrund nix statt? Wie wird der Timer gefüttert? 
Überläufe ausgeschlossen?

Dein Vergleich hinkt also gewaltig. Um es richtig zu bewerten und zu 
kommnetieren (falls einer Lust hat) musst du schon beide vollständigen 
Projekte einstellen.

Aber ungesehen stinkt der avr dabei voll ab. Der arm läuft mit höherem 
Takt und hat einen besseren Befehlssatz. Ist halt so.

von leluno (Gast)


Lesenswert?

Tester schrieb:
> Dein Vergleich hinkt also gewaltig.

Es ist jeweils identischer code. pclk wird jeweils so eingestellt, dass 
gerade noch alle 153.600/2 pixel dargestellt werden. Alle interrupts 
sind abgestellt und werden nur für die Timer-Messung angestellt. Im 
Hintergrund läuft nichts. Die Einstellung des Sensors ist - bis auf den 
prescaler - identisch.

Ich versuche jetzt noch, die pclk-Auswertung über interupt zu machen.

 >Der ARM kann nur 32-bit Speicherzugriff effektiv
Das werde ich noch versuchen umzustellen, dass 32bit-Variablen 
wesentlich schneller als 8bit-Variablen verarbeitet werden, glaube ich 
aber nicht.

von TriHexagon (Gast)


Lesenswert?

leluno schrieb:
>>Der ARM kann nur 32-bit Speicherzugriff effektiv
> Das werde ich noch versuchen umzustellen, dass 32bit-Variablen
> wesentlich schneller als 8bit-Variablen verarbeitet werden, glaube ich
> aber nicht.

Für solche Zwecke eignen sich besonders die int_fastx_t Typen.

von Dr. Sommer (Gast)


Lesenswert?

Lothar schrieb:
> leluno schrieb:
>> Verwendet wird jeweils der gleiche code:
>
> Soll das heissen der ARM muss mit char und short Variablen
> zurechtkommen? Der ARM kann nur 32-bit Speicherzugriff effektiv
> ausführen.
Falsch. Der LPC1768 ist ein Cortex-M3 und der kann Byte(=8Bit), Halfword 
(=16bit), Word (=32bit) Zugriffe gleich schnell (alles in 2 Takten) 
durchführen. Unaligned-Zugriffe (=Halfword-Zugriffe auf ungerade 
Adressen & Word-Zugriffe auf Adressen die keine Vielfachen von 4 sind) 
gehen ebenfalls, brauchen nur einen Takt mehr.

Man kann also auch auf dem Cortex-M problemlos "char" und "short" 
verwenden. Der Code ist unvollständig und nichtssagend, da ist was 
außendrum falsch konfiguriert.

Tester schrieb im Beitrag #3638686:
> Der ARM pustet 2 AVRs weg, keine Sorge. Hier wird ja nur ein Ausschnitt
> gezeigt. Wohl nicht ohne Absicht: Trollfutter.
Nicht nur 2. Die Rechen-Leistung ist um Größenordnungen höher, Latenzen 
der Instruktionen und Interrupts (für Echtzeit) geringer, der Code 
kleiner.

von Moby (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Die Rechen-Leistung ist um Größenordnungen höher, Latenzen
> der Instruktionen und Interrupts (für Echtzeit) geringer, der Code
> kleiner.

Wenn man's denn braucht + das Strombudget langt. Und auch nur die 
Leistung die nicht in ineffizientem Compiling versandet. Asm macht ja 
wenig Sinn bei den ARMs.

von Achim S. (Gast)


Lesenswert?

leluno schrieb:
> pclk wird jeweils so eingestellt, dass
> gerade noch alle 153.600/2 pixel dargestellt werden.

Damit auch ich es kapiere: Welche Frequenz hat pclk konkret beim 
Auslesen mit dem ATMega, welche Frequenz hat es beim Auslesen mit dem 
LPC? Nur nochmal zu Erinnerung: der Code wartet im wesentlichen immer 
nur auf pclk, die beiden µC warten nur unterschiedlich schnell.

leluno schrieb:
> Die Einstellung des Sensors ist - bis auf den
> prescaler - identisch.

Damit auch ich es kapiere: meinst du mit prescaler das, was im 
Datenblatt des Sensors als Pclk-Divider bezeichnet wird? Nach welchen 
Kriterien stellst du diesen Pclk-Divider ein? Hoffentlich nicht danach, 
dass über SPI die "richtigen" Daten empfangen werden, denn du prüfst 
nirgends, ob die SPI-Übertragung beendet ist. Wenn der ARM "zu schnell" 
läuft, machst du dir damit selbst die Daten kaputt.

von Dr. Sommer (Gast)


Lesenswert?

Moby schrieb:
> Dr. Sommer schrieb:
>> Die Rechen-Leistung ist um Größenordnungen höher, Latenzen
>> der Instruktionen und Interrupts (für Echtzeit) geringer, der Code
>> kleiner.
>
> Wenn man's denn braucht + das Strombudget langt.
Kannst dir ja anschauen, z.B. beim EFM32, sogar hier im Wiki:
"Max. Verbrauch im aktiven Modus bei 32MHz: 5mA
Verbrauch im Sleep Modus mit Funktionen wie Displayansteuerung oder 
Sensorüberwachung: 1-2µA (inkl. RTC, Brown Out, RAM aktiv)
Ruhestrom: 20nA"
Sollte für die meisten Strombudgets reichen. Und was heißt brauchen - 
warum den Extra-Komfort der Rechenleistung ablehnen?

> Und auch nur die
> Leistung die nicht in ineffizientem Compiling versandet. Asm macht ja
> wenig Sinn bei den ARMs.
Nur dass der ARMv7M viel besser für C(++) geeignet ist als AVR, und 
effizientes Kompilieren viel einfacher ist. GCC kann das zB schon 
ziemlich gut. Und wenn es tatsächlich nicht langt, warum soll ASM "wenig 
Sinn" machen?

Moby schrieb im Beitrag #3638737:
> Noch so ein schöner Satz für die Sammlung!
> Speed als Problemfall.
Wie bei der NASA, die alte 8086er sucht(e) weil ihre Programme nicht mit 
höherer Prozessorgeschwindigkeit klarkam... Das Problem liegt natürlich 
im Programm, nicht am Prozessor.

von Dr. Sommer (Gast)


Lesenswert?

Moby schrieb:
> Wenn man's denn braucht + das Strombudget langt.
PS: EFM32 braucht 150µA / MHz, ATmega88P (=stromsparversion) 300µA / 
MHz.
Tiefster Schlafmodus: EFM32 20nA, AVR 800nA.
Und aufgrund der höheren Effizienz des Cortex ist der EFM32 auch mit 
allen Operationen schneller fertig und kann schneller wieder schlafen 
gehen => Noch weniger Verbrauch.

von Moby (Gast)


Lesenswert?

Dr. Sommer schrieb:
> EFM32

Na ja schön. Ist/war? ausgerechnet der Spitzensparmeister bei den Arms.

von Lothar (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Falsch. Der LPC1768 ist ein Cortex-M3 und der kann Byte(=8Bit), Halfword
> (=16bit), Word (=32bit) Zugriffe gleich schnell (alles in 2 Takten)
> durchführen. Unaligned-Zugriffe (=Halfword-Zugriffe auf ungerade
> Adressen & Word-Zugriffe auf Adressen die keine Vielfachen von 4 sind)
> gehen ebenfalls, brauchen nur einen Takt mehr.

Was hat das damit zu tun? Bei einem char-Array braucht es dann auf dem 
LPC1768 für 4 byte mit char-Zugriff 2*1+(2+1)*3=11 Takte und ein 
long-Zugriff darauf braucht 2 Takte. Ist doch offensichtlich was 
schneller ist. Dazu kommt noch dass im hier nicht gezeigten AVR-Code 
vermutlich ALU-Instruktionen auf bytes drin sind, die beim ARM zusammen 
auf 4 bytes erfolgen können. Somit könnte der AVR-Code bei 
entsprechender Optimierung auf dem ARM um ein vielfaches schneller 
laufen.

von Dr. Sommer (Gast)


Lesenswert?

Moby schrieb:
> Na ja schön. Ist/war? ausgerechnet der Spitzensparmeister bei den Arms.
Den man sinnvollerweise nimmt wenns um Stromspar geht?! Und 
freundlicherweise hab ich ihn mit dem Stromspar-AVR verglichen.

von Lothar (Gast)


Lesenswert?

Moby schrieb im Beitrag #3638677:
> Ein AVR ist für viele Fälle eben die bessere Lösung.

Ein moderner 8051 wie der FT51 ist immer um ein vielfaches schneller als 
jeder veraltete AVR :-)

von Dr. Sommer (Gast)


Lesenswert?

Lothar schrieb:
> Dr. Sommer schrieb:
>> Falsch. Der LPC1768 ist ein Cortex-M3 und der kann Byte(=8Bit), Halfword
>> (=16bit), Word (=32bit) Zugriffe gleich schnell (alles in 2 Takten)
>> durchführen. Unaligned-Zugriffe (=Halfword-Zugriffe auf ungerade
>> Adressen & Word-Zugriffe auf Adressen die keine Vielfachen von 4 sind)
>> gehen ebenfalls, brauchen nur einen Takt mehr.
>
> Was hat das damit zu tun? Bei einem char-Array braucht es dann auf dem
> LPC1768 für 4 byte mit char-Zugriff 2*1+(2+1)*3=11 Takte und ein
> long-Zugriff darauf braucht 2 Takte.
Ich dachte es geht um einzelne Byte-Zugriffe. Aber auch die sind am ARM 
nicht langsamer als am AVR (also nicht ineffektiv) , nur der ARM kann 
zusätzlich (half-)word Zugriffe noch schneller...
> schneller ist. Dazu kommt noch dass im hier nicht gezeigten AVR-Code
> vermutlich ALU-Instruktionen auf bytes drin sind, die beim ARM zusammen
> auf 4 bytes erfolgen können. Somit könnte der AVR-Code bei
> entsprechender Optimierung auf dem ARM um ein vielfaches schneller
> laufen.
Ja. Aber der ARM ist definitiv nicht langsamer auf Bytes/Half-Words als 
ein AVR...

von Moby (Gast)


Lesenswert?

Lothar schrieb:
> ist immer um ein vielfaches schneller

Das ist aber auch in den meisten Bastler-Projekten zweitrangig.
Das Komplettpaket zählt. Robustheit. Ausgereiftheit. Erhältlichkeit. 
Preis. Vor allem aber: Einfache Anwendung.

Hab so einen Xmega128 in meiner Haussteuerung. Der hat sicher nicht 
wenig zu tun. Asm-optimiert zählt das Ding in seiner Haupschleife immer 
noch bis 60000H/Sek. Mein Gott, wohin bloß mit der Leistung? Ich krieg 
noch graue Haare. Da werd ich mir doch keine Gedanken über einen 
Plattformwechsel machen! Leistung ist doch sowieso völlig überbewertet. 
Oder man verbrät sie in eben Compilern und "schnellerem Warten" ;-)

von Hans-Georg L. (h-g-l)


Lesenswert?

Dr. Sommer schrieb:
> Moby schrieb im Beitrag #3638737:
>> Noch so ein schöner Satz für die Sammlung!
>> Speed als Problemfall.
> Wie bei der NASA, die alte 8086er sucht(e) weil ihre Programme nicht mit
> höherer Prozessorgeschwindigkeit klarkam... Das Problem liegt natürlich
> im Programm, nicht am Prozessor.

Die Nasa hat die Chips für ihre Space Shuttle Diagnosesysteme gesucht. 
Der 8086 sitzt in dem Teil, das den Raketenantrieb vor dem Start 
überprüft.  Hat überhaupt nix mit Geschwindigkeit zu tun, sondern lag 
einfach daran, das die 20 Mio. USD für eine Neuentwicklung nicht 
genehmigt wurden.

von TriHexagon (Gast)


Lesenswert?

Sag mal Moby willst du jetzt einen AVR vs. ARM Krieg auslösen? Wenn du 
dem TE nicht helfen kannst, dann halt dich am besten aus dem Thread 
raus.

von Marc P. (marcvonwindscooting)


Lesenswert?

Und nun? Bekommen wir den vollstaendigen Code zu sehen??

Schon die 2. Zeile sieht etwas ungelenk aus:
1
if(!(vsync)){while(!(vsync));}
kurz: if (A) while (A) ;
das ist: while (A) ;

Was soll das? Compiler-Optimierungs-Plausibilitaetscheck??
Wer das mach, der tut auch noch Schlimmeres...

von Detlef K. (adenin)


Lesenswert?

Ja Stelle finde ich witzig :D
Und die ist schlimmer als Du denkst.
1
Timer=0;                           //Timer rücksetzen
2
if(!(vsync)){while(!(vsync));}     //dann warten wir erst mal ganz entspannt auf den Bildsync
3
while(vsync);

von Dr. Sommer (Gast)


Lesenswert?

Moby schrieb:
> Hab so einen Xmega128 in meiner Haussteuerung.
Ist ja schön. Das hat aber nichts mit der Diskussion zu tun und ARM ist 
immer noch leistungsfähiger.

Hans-Georg Lehnard schrieb:
> Hat überhaupt nix mit Geschwindigkeit zu tun, sondern lag
> einfach daran, das die 20 Mio. USD für eine Neuentwicklung nicht
> genehmigt wurden.
Warum hätte man denn eine Neuentwicklung gebraucht wenn man stattdessen 
286er oder was andres neueres (verfügbares) verwendet hätte?

von leluno (Gast)


Angehängte Dateien:

Lesenswert?

>if(!(vsync)){while(!(vsync));}
stimmt, wird geändert,

Lothar schrieb:
> für 4 byte mit char-Zugriff 2*1+(2+1)*3=11 Takte und ein
> long-Zugriff darauf braucht 2 Takte.

vom OV kommt nur ein 8bit-Signal, daher stellt sich die Frage der 
Übertragung  von 32 bit nicht.

Achim S. schrieb:
> Nach welchen
> Kriterien stellst du diesen Pclk-Divider ein?

Der OV bekommt ein CLKOUT-Signal, beim AVR 16Mhz, beim ARM 12Mhz. Den 
Prescaler habe ich solange verändert, bis der OV so langsam war, dass 
der Zeitraum 1Takt-PCLK ausreichend war, um die Spi-Datenübertragung 
abzuschließen: Beim AVR Prescaler 12=> 1,3Mhz - beim ARM Prescaler 32= 
0,375Mhz. Wenn ich den Prescaler weiter verringere, werden nicht mehr 
alle Pixel übertragen, weil die Zeit für den Datentransfer nicht mehr 
ausreicht.

Die Abfrage Übertragungsende habe ich weggelassen, da es den Code 
verkürzt und  da die Bedingung "ausreichend" Zeit für Spi ohnehin 
eingehalten werden muss. Der Prozessor kann an dieser Stelle im Code 
ohnehin nicht warten, da er sonst den nächsten Pixel-Takt verpasst.

von Detlef K. (adenin)


Lesenswert?

Was soll ich dazu sagen?
Das ist wie, wenn Opa Kause (60 Jahre unfallfrei) Sonntags im Porsche 
auf der Autobahn fährt.
So ein Porsche ist nun mal nicht so schnell wie ein Trabi. ;)

von Achim S. (Gast)


Lesenswert?

Detlef Kunz schrieb:
> Was soll ich dazu sagen?
> Das ist wie, wenn Opa Kause (60 Jahre unfallfrei) Sonntags im Porsche
> auf der Autobahn fährt.
> So ein Porsche ist nun mal nicht so schnell wie ein Trabi. ;)

Danke für die Beschreibung: so schön hätte ich es nicht auf den Punkt 
bringen können....

von Lothar (Gast)


Lesenswert?

Mal abgesehen von der PCLK :-)

leluno schrieb:
> vom OV kommt nur ein 8bit-Signal, daher stellt sich die Frage der
> Übertragung  von 32 bit nicht.

Das heisst ja nicht dass man nicht die 8-bit puffern kann und wenn 
32-bit voll sind das zusammen abholt (spart 3 loops). DMA gäbe es dann 
notfalls auch noch.

von Manni (Gast)


Lesenswert?

> Falsch. Der LPC1768 ist ein Cortex-M3 und der kann Byte(=8Bit), Halfword
> (=16bit), Word (=32bit) Zugriffe gleich schnell (alles in 2 Takten)
> durchführen. Unaligned-Zugriffe (=Halfword-Zugriffe auf ungerade
> Adressen & Word-Zugriffe auf Adressen die keine Vielfachen von 4 sind)
> gehen ebenfalls, brauchen nur einen Takt mehr.

Das mag sein, aber bedenke, dass bei arithmetischen Operationen 
eventuelle Überläufe berücksichtigt werden müssen. Der ARM rechnet 
prinzipiell mit 32 Bit. Um die Bits los zu werden, die durch eventuelle 
Überläufe auf 1 gesetzt wurden, erzeugt z.B. der IAR Compiler bei 8-Bit 
Variablen massenhaft Shifts um 24 Bit nach links, gefolgt von Shifts um 
24 Bit nach rechts. Daher ist es beim ARM oft besser, auch für z.B. 
Schleifenzähler, bei denen 8 Bit reichen würden, gleich ein uint32_t zu 
verwenden.

von leluno (Gast)


Lesenswert?

Lothar schrieb:
> 8-bit puffern

Ich habe das doch probiert. Es macht keinen Unterschied, ob ich die 8bit 
erst in einen Buffer oder sofort in das SSP0DR-Register schreibe. Bei 
SSP0 ist DMA eingestellt, dürfte die CPU daher nicht belasten.

Auch für DMA brauche ich ausreichend Rechenzeit, um zumindest den 
Software-Single-Request aufzurufen. Diese Rechenzeit steht bislang nicht 
zur Verfügung.

von Achim S. (Gast)


Lesenswert?

ich sehe es dem Code auf die Schnelle nicht an: kannst du uns noch 
verraten, mit welchem Takt der SPI-Bus auf den beiden µC läuft?

Am liebsten sind mir bei solchen Angaben immer Werte, die man mal mit 
dem Oszi nachgemessen hat (damit man nicht irgendeine Prescaler- oder 
eine PLL-Einstellung übersieht, die sich auf den SPI-Takt auswirkt).

von leluno (Gast)


Lesenswert?

SSP0 läuft mit 25Mhz:
1
void lcd_ssp_init(void){
2
//0.15 0.17 0.18 ssp0/F x10
3
  pinSEL(0,16,0);
4
  pinDIRout(0,16);
5
  pinSET(0,16);
6
#if 1 //ssp0
7
  init_ssp0_1();
8
  ssp0_set_speed(2);
9
  //DMA:
10
  SSP0DMACR = 3;//176x
11
  LPC_SC->PCONP |= (1<<29);//Enable clock to DMA controller
12
#else....
13
void init_ssp0_1(void){
14
pinSEL(0, 15, 2);    // Attach SCK0 to I/O pad
15
pinSEL(0, 17, 2);    // Attach MISO0 to I/O pad
16
pinSEL(0, 18, 2);    // Attach MOSI0 to I/O pad
17
SSP0CR0 |= (DSS<<0);//8bits
18
SSP0CR0 |= (FRF<<4);//frame
19
SSP0CR0 |= (1<<CPOL);
20
SSP0CR0 |= (1<<CPHA);
21
SSP0CR1 = 0b0010;     // SOD = 0, MS = 0, SSEnable = 1, LBM = 0
22
SSP0CPSR = (PCLK_SSP / SCLK_SLOW) & ~1;//slow
23
SSP0CPSR = 250;
24
//SSP0CR0 = 0x0007;      /* Set mode: SPI mode 0, 8-bit */
25
//SSP0CR1 = 0x2;        /* Enable SSP with Master */
26
}
27
...
28
void ssp0_set_speed(char divider){// fast 2...254 slow
29
SSP0CPSR = divider;
30
}


Der SPI-AVR mit halbem Prozessortakt...
Beides ist in Ordnung, denn der Bildaufbau - ohne OV - ist ja o.k.


... Eine Idee habe ich noch. Am Pin 0.12 sitzt ein Taster. Der hat einen 
10k-Pullup. Möglicherweise verkürzt der die nutzbare Zeitspanne???

von Detlef K. (adenin)


Lesenswert?

:D
1
SSP0CPSR = (PCLK_SSP / SCLK_SLOW) & ~1;  //mach dies
2
SSP0CPSR = 250;                          //nein, doch lieber das

: Bearbeitet durch User
von leluno (Gast)


Lesenswert?

Der Pullup wars nicht. Ich habe CLKOUT mit dem CPU-Takt verbunden. Der 
Bildaufbau ist nun deutlich schneller als beim AVR. Mit dem ARM ist also 
alles in Ordnung. Was nicht funktioniert, ist die Änderung beim 
Prescaler. Vermutlich ein Problem beim SCCB-Bus. Für heute reichts. 
Vielen Dank für die Hilfe.

von leluno (Gast)


Lesenswert?

Um den Leistungsvergleich abzuschließen, die Datenübertragung beim ARM 
läuft jetzt mit 12/7=1,7 Mhz im Vergleich zu 1,3Mhz beim AVR.

So gewaltig ist der Unterschied also gar nicht.

von Detlef K. (adenin)


Lesenswert?

leluno schrieb:
> Um den Leistungsvergleich abzuschließen, die Datenübertragung beim
> ARM
> läuft jetzt mit 12/7=1,7 Mhz im Vergleich zu 1,3Mhz beim AVR.
>
> So gewaltig ist der Unterschied also gar nicht.

Ich sag ja auch immer: Glaub keinem Vergleich, den Du nich selbst 
getürkt hast.
Also wo liegt hier wohl der die Irreführung? :)
Ich erinnere mal an Opa Krause. ;)

Und wenn die Art, wie die Messung gestartet wird, nicht geändert wurde, 
dann geht das bildlich gesprochen so:

Opa Kause will wissen wie lange er für den Weg von einer Ampel zur 
nächsten braucht.
Das macht er so:
Er fährt zur ersten Ampel, und startet dort schon mal die Stoppuhr.
Es ist gerade GRÜN, aber er will ja mit der ROT/GRÜN-Flanke losfahren, 
damit das ganze schön syncron ist.
Also wartet er bis ROT ist und färt los, sobald wieder GRÜN wird.
Dann Stoppt er die Zeit an der nächsten Ampel.
Sein Kumpel Willi mit seinem Trabi macht das gleiche. Allerdings kamm er 
erst in allerletzter Sekunde vor dem Start an der Ampel an (mann muss ja 
mal aufs klo).
Beide kommen genau zur selben Zeit an der nächsten Ampel an. Und doch 
hat Willi laut Messung eindeutig weniger Zeit gebraucht, ist also 
folgerichtig schneller. Also ist der Porsche doch nicht so schnell.

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

Detlef Kunz schrieb:
> Beide kommen genau zur selben Zeit an der nächsten Ampel an. Und doch
> hat Willi laut Messung eindeutig weniger Zeit gebraucht, ist also
> folgerichtig schneller. Also ist der Porsche doch nicht so schnell.
Hihi, das find ich gut :)

von leluno (Gast)


Lesenswert?

Detlef Kunz schrieb:
> und wenn die Art, wie die Messung gestartet wird, nicht geändert wurde,
> dann geht das bildlich gesprochen so:

Du hast einen Fehler bei der Rücksetzung des Timers aufgezeigt. Das hab 
sogar ich verstanden und geändert. Die Frequenz von 1,7 Mhz wurde durch 
Veränderung des Prescalers ermittelt. Bei Prescaler 6 werden nicht mehr 
alle Pixel erfasst. Prescaler 7 ist ok. Daraus folgt 1,7Mhz.

Was erwartest du bei einer mit 25 Mhz betriebenen ARM-Peripherie im 
Vergleich zu einem mit 16 Mhz betriebenen AVR-System?

Dein Ton ist uenerträglich oberlehrerhaft.

von Tester (Gast)


Lesenswert?

> Dein Ton ist uenerträglich oberlehrerhaft.

Aber vollkommen berechtigt. Deine Vorstellung entspricht dem eines 
Schuljungen.

von Detlef K. (adenin)


Lesenswert?

leluno schrieb:
> Was erwartest du bei einer mit 25 Mhz betriebenen ARM-Peripherie im
> Vergleich zu einem mit 16 Mhz betriebenen AVR-System?

Ich bin von dem Erkenntnisgewinn beeindruckt.

leluno schrieb:
> Dein Ton ist uenerträglich oberlehrerhaft.

Nunja, ein Exchef meinte, ich wär überheblich.

von Dirk K. (dekoepi)


Lesenswert?

Was bei mir zwischendurch nicht gepasst hatte, waren 
Compiler-Optimierungen (-O2). Für das Projekt eingestellt, aber 
irgendwie hatte sich main.c ein -O0 eingefangen und lief damit 
schnarchlangsam - sowohl auf AVR als auch auf ARM. Der Unterschied 
nicht-optimiert zu optimiert war eine fast verdoppelte Transferleistung 
via SPI.

von leluno (Gast)


Lesenswert?

Dirk K. schrieb:
> Optimierungen (-O2)
Wie sieht dein Px-Auswerte-code denn inzwischen aus? Du hattest  auch 
if-while-Verschachtelungen...

von Dirk K. (dekoepi)


Lesenswert?

Die hatte ich drin, weil ich alles mögliche ausprobiert habe, um das 
Dingen ordentlich ans Rennen zu bekommen.

Inzwischen sieht die Schleife so aus - immer noch Polling, da ich mit 
DMA nicht zu Rande komme. DMA SPI->Rx läuft, Tx nicht. Habe mich da von 
deiner Schleife mal inspirieren lassen. Ist aber nicht unbedingt 
schneller.
1
  while (!(VSYNC)); // wait for next frame
2
  while (VSYNC); // wait for frame start
3
4
  int rows=480;
5
  int border = ram_size;
6
  while (rows) {
7
      while(!(HREF)) ;  // wait for row
8
      while (HREF) {
9
        while(!(PCLK)) ;  // wait for pixel valid
10
        spi1_tx((GPIOB->IDR)>>8);
11
//        pixelcount++;
12
        border--;
13
        if (border) {
14
          while(PCLK) ;  // wait for pixel to end
15
        } else {
16
             border = ram_size;
17
             bank++;
18
             chip_select(bank);
19
20
             // Send WRITE command to chip
21
             spi1_tx(WRITE);
22
23
             // as default sequential mode, thus address has to be sent only at start
24
             address = 0;
25
             spi1_tx((address>>16));   //send even MoreMSByte address first
26
             spi1_tx((address>>8));   //send MSByte address first
27
             spi1_tx((address));      //send LSByte address
28
        }
29
      }  // of href
30
      if (linecount == 0) linecount = (ram_size-border) / 2;
31
      rows --;
32
   }  // of rows / image transfer done!
33
34
  pixelcount=(bank*ram_size)+(ram_size-border);
35
  sprintf(text, "Writing image succeeded! Wrote %u bytes, used %i RAM chips.\n", pixelcount, bank+1);
36
  uart_tx(text);
37
  sprintf(text, "Image dimension: %i x %i pixel. 10 bytes captured:\n", linecount, ((pixelcount/linecount)/2));
38
  uart_tx(text);
39
40
  chip_deselect();

: Bearbeitet durch User
von leluno (Gast)


Lesenswert?

Dirk K. schrieb:
> // as default sequential mode, thus address has to be sent
> only at start
>              address = 0;
>              spi1_tx((address>>16));   //send even MoreMSByte address
>              spi1_tx((address>>8));   //send MSByte address first
>              spi1_tx((address));      //send LSByte address

du hast sehr viel code in der Px-Schleife. Normalerweise muss man 
Speicherchips nur einmal adressieren und kann dann die bytes 
nacheinander schreiben. das Hochzählen der Adressen geht automatisch. 
Dadurch kannst du die Geschwindigkeit erhöhen. Je weniger Befehle in der 
px-Schleife, um so besser...

Die Darstellung auf dem TFT ist bei mir mit 1,7Mhz pclk durchaus 
akzeptabel. Ich bastel jetzt an der sd-Speicherkarte. Die 9er Version 
von Chan funktioniert. Bei der 10er bin ich gescheitert. Wenn das 
klappen sollte, könnte ich komplette Bilder auf die sd-Karte schreiben.

von leluno (Gast)


Lesenswert?

leluno schrieb:
> sequential mode, steht ja in deinem Kommentar!

von Kaj (Gast)


Lesenswert?

leluno schrieb:
> die Datenübertragung beim ARM
> läuft jetzt mit 12/7=1,7 Mhz im Vergleich zu 1,3Mhz beim AVR

leluno schrieb:
> Was erwartest du bei einer mit 25 Mhz betriebenen ARM-Peripherie im
> Vergleich zu einem mit 16 Mhz betriebenen AVR-System?

Wie wäre es wenn du beide systeme mit der gleichen takt frequenz 
betreibst? dann wäre der vergleich meiner meinung nach viel sauberer. 
Eine höhere Taktfrequen bedeutet ja zwangsläufig, das ein höherer 
datendurchsatzt erreicht werden kann (unabhängig davon, wie viel höher 
der Durchsatzt dann wirklich ist). Wenn du es aber mal mit der gleichen 
Taktfrequenz testets, und der ARM dann langsamer ist, ist das ergebnis 
wirklich ernüchternd.
So wie es jetzt ist sage ich: Der ARM ist bei der Datenübertragung 
400kHz schneller. Und 400kHz sind nunmal 400kHz.

von Dirk K. (dekoepi)


Lesenswert?

Bei 640x480x2Byte (etwa 610 kByte) muss ich die Speicherchips von 
128kByte halt nach 128kByte umschalten ;) Den meisten Code überspringe 
ich ja und das klappt ohne Umschalten auch sehr gut und fix.

Ich verliere 8 Byte, offenbar ist das Umschalten der Speicherchips 2 
PCLK zu langsam. Auslagern kann ich das nicht, und SPI-RAM funktioniert 
nun mal so, dass ich den Befehl WRITE, die Adresse und dann die Daten 
sende - also anstatt 1 Byte sequentiell über die Leitung zu schicken, 
laufen da 5. Nehme ich da irgendwo CS weg, ist der Befehl zu Ende und 
der Chip wartet auf einen neuen Befehl.
In einer vorher laufenden Schleife kann ich immerhin schon mal auf 
Sequential Mode umstellen und kann mich auf umschalten + Daten senden 
beschränken.

Mit DMA und Puffer dürfte sich da was machen lassen. Aber der DMA zickt 
natürlich auch. Wäre ja zu einfach, würde eine Peripherie mal 
funktionieren wie beschrieben. ;) So lernt man jedes Protokoll, jeden 
Baustein wirklich gut kennen. Wenn man dann nicht irgendwo stecken 
bleibt, macht das sogar Spaß :)

von leluno (Gast)


Lesenswert?

Ich kann beim AVR mit einer Pixel-Clock-Frequenz von 1,7Mhz nichts 
anfangen, weil er die einkommenden Daten nicht mehr verarbeiten kann. 
Ohne Frage ist der ARM auch beim Spi-Transfer wesentlich schneller. Der 
Vorteil erhöht sich noch wenn die CPU-Rechenleistung von 100Mhz zum 
Tragen kommt. Trotzdem ist auch der AVR - insbesondere der M1284 - nicht 
schlecht.

von leluno (Gast)


Lesenswert?

Dirk K. schrieb:
> Ich verliere 8 Byte, offenbar ist das Umschalten der Speicherchips 2
> PCLK zu langsam. Auslagern kann ich das nicht,

Wenn du zeilenweise ansteuerst, müsste das gehen, weil bei !href ja eine 
Schreibpause eintritt.
1
zl_href = 124;
2
while(href)
3
{...
4
zl_href--;
5
}
6
7
cs_chip1_h,cs_chip2_l, write_cmd, zl_href = 124
8
9
zl_href = 124;
10
while(href)
11
{...
12
zl_href--;
13
}
14
...

die Dauer der Befelsfolge beim Umschalten bestimmt dann die 
Schreibgeschwindigkeit. Wenn du den chip nicht adressierst, müsste er 
bei 0 anfangen.

von Dirk K. (dekoepi)


Lesenswert?

Danke für den Vorschlag, da hätte ich vielleicht auch drauf kommen 
können, mich auf 102 Zeilen pro Modul zu beschränken - das hilft gegen 
die verlorenen Pixel :)
1
Reading COM11 again from OV7670: [143] -> Prescaler 16, frequency 500 kHz.
2
Select first RAM chip.
3
Writing image succeeded! Wrote 614400 bytes, used 5 RAM chips.
4
Image dimension: 640 x 480 pixel. 10 bytes captured:
5
[101]: 153   [102]: 187   [103]: 186   [104]: 202   [105]: 95   [106]: 223   [107]: 137   [108]: 220   [109]: 88   [110]: 222

Die Schleife sieht jetzt auch besser aus, weniger krampfhafte 
Stützkonstrukte (border ...).
1
  int rows=480;
2
  while (rows) {
3
      while(!(HREF)) ;  // wait for row
4
      while (HREF) {
5
        while(!(PCLK)) ;  // wait for pixel valid
6
        spi1_tx((GPIOB->IDR)>>8);
7
        pixelcount++;
8
        while(PCLK) ;  // wait for pixel to end
9
      }  // of href
10
      if (linecount == 0) linecount = pixelcount / 2;
11
      if ((rows % 101)==0) {
12
           bank++;
13
           chip_select(bank);
14
15
           // Send WRITE command to chip
16
           spi1_tx(WRITE);
17
18
           // as default sequential mode, thus address has to be sent only at start
19
           address = 0;
20
           spi1_tx((address>>16));   //send even MoreMSByte address first
21
           spi1_tx((address>>8));   //send MSByte address first
22
           spi1_tx((address));      //send LSByte address
23
      }
24
      rows --;
25
   }  // of rows / image transfer done!

War irgendwie der Idee aufgesessen, die Speicherchips randvoll zu 
schreiben - ist ja aber Quatsch. :)

Ohne Adressierung geht es nicht. Der Chip erwartet: <cmd> - <address> - 
<data>: http://ww1.microchip.com/downloads/en/DeviceDoc/25142A.pdf

: Bearbeitet durch User
von leluno (Gast)


Lesenswert?

Dirk K. schrieb:
> pixelcount++;
>         while(PCLK) ;  // wait for pixel to end
besser:
while(PCLK) ;  // wait for pixel to end
pixelcount++;

> spi1_tx((address>>16));   //send even MoreMSByte address
>            spi1_tx((address>>8));   //send MSByte address first
>                  //send LSByte address

besser:
spi1_tx(0);
spi1_tx(0);
spi1_tx(0);

von leluno (Gast)


Lesenswert?

Dirk K. schrieb:
> if ((rows % 101)==0) {

falls die Umschaltung der banks zeitkritisch ist, kannst du diese 
Abfrage auch einsparen, indem du den code 5mal wiederholst.

von Dirk K. (dekoepi)


Lesenswert?

An der Stelle ist das alles nicht mehr zeitkritisch - habe da ja locker 
8 oder mehr PCLK "blank pause", da kann der STM32F103 so richtig 
rumrechnen ;) Dass da drei Mal 0 als Adresse übertragen wird, ist schon 
klar - das macht den Kohl da aber nicht fett, da die Shifts in einem 
Takt laufen und die serielle Übertragung per SPI die eigentliche Bremse 
ist.

von MCUA (Gast)


Lesenswert?

>Was erwartest du bei einer mit 25 Mhz betriebenen ARM-Peripherie im
>Vergleich zu einem mit 16 Mhz betriebenen AVR-System?
Die Peripherie hat ja prinz. nichts mit dem Kern zu tun (wobei die SPI.. 
vom AVR aber extrem schlecht ist).
Aber m.E. liegt ganz oben schon ein Fehler vor, denn mit SPI ein 
Grafik-Display anzusteuern, ist einfach grässlich.

von leluno (Gast)


Lesenswert?

MCUA schrieb:
> mit SPI ein Grafik-Display anzusteuern, ist einfach grässlich

???????
Einfach anzuschließen, billig, vollwertiger Ersatz für Text-Lcd, super 
geeignet für die Darstellung von Funktionen und Graphen, Anzeige von 
Fotos mit noch akzeptabeler Geschwidigkeit. Bei genügend Speicher für 
die Zeichen-lib - ab Atmega32 - immer  zu empfehlen.

Beim aktuellen Projekt ersetzt das Lcd lediglich einen 
153.600-Byte-Speicher, der die praktische Eigenschaft hat, den 
Speicherinhalt optisch anzuzeigen. Es geht nur um einen Zwischenschritt, 
da die Bilder (mindestens 4x 153.600 Bytes) letztlich auf eine sd-card 
müssen.

von ReinerG (Gast)


Lesenswert?

Dirk K. schrieb:

> Ohne Adressierung geht es nicht. Der Chip erwartet: <cmd> - <address> -
> <data>: http://ww1.microchip.com/downloads/en/DeviceDoc/25142A.pdf

"If operating in Sequential mode, after the initial data
byte is shifted in, additional bytes can be clocked into
the device. The internal Address Pointer is automatically
incremented."

Seite 5, Kapitel 2.4 Write Sequence

Alles andere wäre sehr ungewöhnlich.

von Dirk K. (dekoepi)


Lesenswert?

Rainer, wo ist der Widerspruch?!

Sofern du CS wieder wegnimmst, ist der aktuelle Befehl beendet. Du 
startest wieder mit Befehl, wenn du den Chip anwählst.

Und der verlangt eine Adresse.

Die Adresse wird nur einmal gesetzt beim Adressieren des Chips. Steht 
alles doch da. Nach der Initialisierung schubse ich rein die Daten rüber 
und verlasse mich auf Autoinkrement.

: Bearbeitet durch User
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.