Hallo liebe Gemeinde!
Heute mal zurück zu den Wurzeln! Ich möchte Vektoren kopieren, wobei die
Dimension des Quellvektors größer ist, als die Dimension des
Zielvektors! Anders gesprochen: ich möchte aus einem Datenfeld mit x
Elementen nur die x-3 letzten Elemente in ein neues Datenfeld kopieren!
Bisher erledige ich das mit einer Schleife und inhärenter
Indexmanipulation!
Gibt es einen direkten Weg in C?
Danke für Eure Hilfe!
Nein, in C gibt es keinen anderen Weg.
Schreib doch eine Funktion, an der beide Vektoren übergeben werden. Dann
verschwinden zumindest die Schleifen aus dem Hauptprogramm.
ArduStemmi schrieb:> Gibt es einen direkten Weg in C?
Je nach processor gibt des den directen Weg des direct memory access -
DMA.
Schau mal in der Bibliotheksbeschreibung "deines" processors.
Eric B. schrieb:> Ich hätte da eher a[index_U][index_V] genommen, oder die Schleifen> andersrum genestet:
Ja.
Das ist eine quick & dirty Demo, um memcpy (gerne auch mehrdimensional)
darzustellen.
Die eigentliche (Haus)Aufgabe des TO bleibt dem eigenen Fleiß
überlassen;-)
Danke, ich habe jetzt das Datenblatt und die Beschreibung von memcpy.
Ich glaube Zweiteres wird die Lösung des Problems sein können. Daher
möchte ich noch einmal auf meine Frage kommen. Ich möchte aus einem
Datenfeld mit 3 x 10 Elementen ein Datenfeld "entnehmen" mit 3 x 7
Elementen. Wobei die jeweils letzten 7 zu verwenden sind. Kann da memcpy
helfen? Ich habe verstanden, memcopy kopiert Byte für Byte einen
Speicherbereich in einen anderen. Wobei anzugeben sind: StartAdresse des
Quellbereichs, STARTAdresse des Zielbereichs und die Menge der zu
kopierenden Daten.
In meinem Fall gibt es ja nicht einen, sondern im besten Fall drei
Speicherbereiche (Elemente 3 - 10, Elemente 13 bis 20 und Elemente 23 -
30). Demnach habe ich drei StartAdressen (3, 13, 20)!
Wenn ich dann also auch bloss eine For Schleife brauche, dann kann ich
es auch Elementweise kopieren und weiterhin Index-Zauberei betreiben.
(Aus Element(0,3) wird NeuElement(0,0) usw., usf.
Oder irre ich?
ArduStemmi schrieb:> In meinem Fall gibt es ja nicht einen, sondern im besten Fall drei> Speicherbereiche (Elemente 3 - 10, Elemente 13 bis 20 und Elemente 23 -> 30). Demnach habe ich drei StartAdressen (3, 13, 20)!
Wenn du das Array mit den Daten passend deklarierst, nämlich nicht als
[3][10], sondern als [10][3], sind die zu kopierenden Elemente mit den
Indizes [3..9][0..2] zusammenhängend, und ein einzelner memcpy-Aufruf
genügt.
Das ist eine gute Idee! Muss mal sehen, ob ich mein Datenmodell
umstricken kann. Die Daten sind zum Teil schon im EEPROM und müssten
auch dort umgestrickt werden.
Aber wie lautet den der memcpy Befehl, wenn ich ab dem 3. Element einer
Auflistung zugreifen will?
ArduStemmi schrieb:> Aber wie lautet den der memcpy Befehl, wenn ich ab dem 3. Element einer> Auflistung zugreifen will?
Du kannst als Startadresse jedes beliebige Element eines Arrays angeben.
Es muss also nicht das Element mit dem Index [0][0] sein, sondern es
könnte auch [0][2] sein. Oder [2][0]. Oder was immer Du haben willst.
ArduStemmi schrieb:> Aber wie lautet den der memcpy Befehl, wenn ich ab dem 3. Element einer> Auflistung zugreifen will?
Das 3. Element hat in C den Index 2. Um also die 8 Elemente mit den
Indizes 2 bis 9 zu kopieren, schreibst du:
1
memcpy(ziel,array+2,8*sizeofarray[0]);
Falls du kein Freund von Zeigerarithmetik bist, kannst du statt array+2
auch &array[2] schreiben, was exakt dasselbe ist.
Das funktioniert unabhängig vom Elementyp des Arrays. Egal, ob array so
1
chararray[10];
oder so
1
structmystructarray[10];
oder so
1
doublearray[10][3];
definiert ist, es werden immer die gewünschten Daten kopiert.
Ehrlich gesagt würde ich mir in so einem Fall eine eigene Kopierfunktion
schreiben (gerne auch in inline-assembler). Sind auch nur ein paar
Zeilen, man kann es den gegebenen Erfordernissen anpassen, man weiss
genau was wohin kopiert wird, und weniger performant als das
standard-memcpy wird's kaum werden.
Besucher schrieb:> Ehrlich gesagt würde ich mir in so einem Fall eine eigene Kopierfunktion> schreiben (gerne auch in inline-assembler). Sind auch nur ein paar> Zeilen, man kann es den gegebenen Erfordernissen anpassen, man weiss> genau was wohin kopiert wird, und weniger performant als das> standard-memcpy wird's kaum werden.
Das mag so sein, aber was an:
1
memcpy(ziel,array+2,8*sizeofarray[0]);
ist lang, entspricht nicht den Erfordernissen oder lässt offen, was
wohin kopiert wird?
Das Rad ist bisher durch keine seiner Neu-Erfindungungen wesentlich
runder geworden. :-)
ArduStemmi schrieb:> umstricken kann. Die Daten sind zum Teil schon im EEPROM und müssten> auch dort umgestrickt werden.>> Aber wie lautet den der memcpy Befehl..
Funktioniert memcpy() auch für EEPROM? Der hat doch seine eigenen
Zugriffsmechanismus:
"The access between the EEPROM and the CPU is described in the
following, specifying the EEPROM Address Registers, the EEPROM Data
Register, and the EEPROM Control Register" (Datenblatt S.19)
Wann nimmt man:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__eeprom.html
Noch ein Aspekt der Beachtung verdient: 16bit versus 8bit transfers.
Der µC kann beides. Falls der vector aus 8bit breiten elementen besteht,
könnte man das kopieren beschleunigenen wenn man die Kopierschleife mit
16 bit transfers betreibt. Dazu muss man das erste und letzte byte ggf.
extra behandeln da ggf. missaligned. Beherscht das memcpy()?
Besucher schrieb:> Ehrlich gesagt würde ich mir in so einem Fall eine eigene Kopierfunktion> schreiben (gerne auch in inline-assembler). Sind auch nur ein paar> Zeilen, man kann es den gegebenen Erfordernissen anpassen, man weiss> genau was wohin kopiert wird, und weniger performant als das> standard-memcpy wird's kaum werden.
Auf einem AVR, wo's im Prinzip nur einen Weg gibt, um einen
Speicherblock zu kopieren, mag das stimmen. Allgemeingültig ist die
Aussage aber nicht. In der Regel hat man keinerlei Vorteil davon, statt
memcpy() eine handgestrickte Schleife zu machen. Und in Assembler würde
ich das schon gar nicht machen, außer wenn es einen ganz konkreten Grund
gäbe, warum das Programm dadurch signifikant schneller würde (z.B. weil
man sehr große Datenblöcke kopieren muss und das verfügbare memcpy einen
ganz besonders effizienzen Weg nicht nutzt).
Fpga K. schrieb:> Noch ein Aspekt der Beachtung verdient: 16bit versus 8bit transfers.>> Der µC kann beides.
Wie das? Der RAM ist doch nur 8-bittig angebunden.
Fpga K. schrieb:> Funktioniert memcpy() auch für EEPROM?
Nein. Du hast es doch selber verlinkt. Wenn du Daten aus dem EEPROM ins
RAM kopieren willst, nimmst du eepropm_read_block() statt memcpy().
Rolf M. schrieb:> Fpga K. schrieb:>> Noch ein Aspekt der Beachtung verdient: 16bit versus 8bit transfers.>>>> Der µC kann beides.>> Wie das? Der RAM ist doch nur 8-bittig angebunden.
Hm, da hab ich MOVW und SPM fälschlicherweise mit dem SRAM in Verbindung
gebracht.
> Fpga K. schrieb:>> Funktioniert memcpy() auch für EEPROM?>> Nein. Du hast es doch selber verlinkt. Wenn du Daten aus dem EEPROM ins> RAM kopieren willst, nimmst du eepropm_read_block() statt memcpy().
Ja, dann nützt dem TO memcpy wenig weil er EEPROM-Daten kopieren will.