* the program opens a file with f_write/f_lseek. The startsector
* and the link-table are stored in kksectors/kkcltbl
* if there is only one fragment, data can be written in this file with
* cmd25 - write multiblock - beginning from the startsector.
*
* the spi-cmd25-sequence is
* 0xfc-512xdata-crc-crc-response
* crc and response are only dummies, therefore can be written
* a stream of 516data with dma from buffer. Cause of 0xfc-token,
* there is one byte difference between input and output
* __SECTION(data,RAM1) uint8_t buffer[25600];
*uint8_t *buf_cam0 =buffer+1;
*uint8_t *buf_cam1 =buffer+1+12800;
* Data can be written in buffer1, while dma is writing from buffer2
*
*With DMA speed goes up from 0,45MB/s to 1,2MB/s
*
*next step would be to to change code for fragmented data/cltbl[4]!=0
Falk Brunner schrieb:> Unheimlich nützlich für andere Leute
pardon, Ausgangscode ist der von Elm Chan, verwendet wird ein LPC1768
Der code stellt dar, wie man den sd-Schreibzyclus auf nur eine 516-byte
Datenfolge für die DMA vereinfachen kann. Wer sich mit DMA beschäftigt
hat, kann das leicht für andere mcus umsetzen.
Vor einer ernsthafen Verwendung muss ich leider abraten, denn
"abfr_busy()" blockiert den DMA Interrupt, je nach Karte für mehr als
100 ms.
Außerdem gibt es keine erkennbare Behandlung der übrig bleibenden Daten
im RX-FiFo des SSP, was nachfolgende Kommunikation beeinträchtingen
kann.
Multiple Block Write scheint in der Tat bei vielen SD Karten schneller
zu sein als single Write.
DMA halte ich aber in diesem Fall für überflüssig. Man erhält eine
praktisch idenische Geschwindigkeit durch das Ausnutzen des FIFO im SSP
(8 Einträge á 16 Bit) bei weniger aufwändigem Code.
Jim Meba schrieb:> "abfr_busy()" blockiert den DMA Interrupt, je nach Karte für mehr als> 100 ms
Märchen. Bei meiner 8GB-Karte jedenfalls nicht. Ich habe natürlich
überlegt, was ich mit der Readyabfrage mache - eigene DMA oder eigene
Timerroutine. Das Debugging hat aber gezeigt, dass hier kaum ein
Eintritt in die Schleife stattfindet. Das zeigt auch die erzielte
Datenrate. Mit DMA hat sich diese gegenüber Multiple Block Write mehr
als verdoppelt. Nach meiner Einschätzung lassen sich durch den Ersatz
von abfr_busy keine nennenswerten weiteren Geschwindigkeitszuwächse
erzielen. Deine Aussage gilt vielleicht für ältere Karten, nich jedoch
für moderne 8GB-Karten. Anderes sollte man sich aber heute nicht mehr
antun.
Jim Meba schrieb:> Außerdem gibt es keine erkennbare Behandlung der übrig bleibenden Daten> im RX-FiFo des SSP, was nachfolgende Kommunikation beeinträchtingen> kann.
Ein Problem, das mich wirklich fast zur Verzweifelung gebracht hat. Im
Ausgangscode von Elm Chan wird in der Sequenz
>token-512databyte-crc-crc-response
jeweils der rxfifo geleert und response ausgewertet. Verzichtet man auf
diese Auswertung, braucht man den rxfifo nicht leeren, so dass ein
einheitlicher 516Byte-Schreibvorgang entsteht.
Das Problem ensteht aber nach Beendigung der DMA, weil dann wieder mit
elm-chan code die response ausgewertet wird. der rxfifo muss nach der
DMA also geleert werden. Gelöst wird dieses Problem durch den Aufruf
von
1
voidDMA0_from_buffer_to_SSP0_end(void){
2
DMA_STATUS=2;
3
abfr_busy();
4
DMA3_transfer_from_SSP0_to_buffer(32);
5
}
Hier wird der rxfifo und wohl auch ein DMA-fifo geleert, so dass
anschließend ohne Konflikte mit elm chan weitergearbeitet werden kann.
Warum es hier 32 bytes sein müssen, kann ich dir nicht sagen, 8bytes
reichen jedenfalls nicht.
Jim Meba schrieb:> DMA halte ich aber in diesem Fall für überflüssig. Man erhält eine> praktisch idenische Geschwindigkeit durch das Ausnutzen des FIFO im SSP> (8 Einträge á 16 Bit) bei weniger aufwändigem Code.
Das habe ich mit der Funktion cmd25_spi_write() ausprobiert und mit DMA
verglichen. DMA läuft mehr als doppelt so schnell. Weiterer Vorteil, DMA
läuft -bis auf das vernachlässigbare abfr_busy- komplett im Hintergrund
ab. Man muss also nur für Zugriffe auf die Karte auf das Ende der DMA
warten und kann ansonsten die mcu andere Programmteile bearbeiten
lassen.
Grundschüler schrieb:> Deine Aussage gilt vielleicht für ältere Karten, nich jedoch> für moderne 8GB-Karten. Anderes sollte man sich aber heute nicht mehr> antun.
Ich hab hier eine alte ;) 64GB SD, die hat diese Delays auch drin.
Das ist in den Spec's auch so beschrieben und als normal anzusehen.
Du musst natürlich größe Datenmengen kontinuierlich aufzeichnen, dann
merkst Du, das (abhängig vom Kartentyp) aller sounsoviel Blocke kleinere
und größere Delays drin sind.
Ich empfehle Kapitel 4.6.2.2 der "SD Specification Part 1" Version 4.10
Detlef Kunz schrieb:> aller sounsoviel Blocke kleinere> und größere Delays
Mag sein. Es bleibt aber die Frage, ob es sich lohnt wegen delays, die
jedenfalls nicht in jeder Schreibsequenz auftreten, eine Routine zu
programmieren die bei jeder Schreibsequenz aufgerufen werden muss und
die allein durch diesen Aufruf eine eigene Verzögerung des
Schreibvorgangs mit sich bringt.
Ich meine nein. Meine Datenrate liegt bei 1,2MB/sec bei 600k Daten. Der
Ersatz von abfr_busy könnte bestenfalls bewirken, dass 8/516 des
Schreibvorgangs ebenfalls in den Hintergrund ausgelagert werden.
Schneller wird der Schreibvorgang dadurch nicht. Der programmtechnisch
erforderliche Aufwand für den Ersatz von abfr_busy lohnt sich nicht.
@Jim Meba (turboj)
>Vor einer ernsthafen Verwendung muss ich leider abraten, denn>"abfr_busy()" blockiert den DMA Interrupt, je nach Karte für mehr als>100 ms.
Es ist, wie der Name des Posters schon sagt, ein Gefrickel vor dem
Herrn.
Beitrag "sd-Karte Elm Chan DMA"
Der OP will keine solide Lösung (die deutlichen Aufwand bedeutet), weil
er meint, das einfach mal so machen zu können.
Beitrag "Re: sd-Karte Elm Chan DMA"
Falk Brunner schrieb:> Der OP will keine solide Lösung (die deutlichen Aufwand bedeutet), weil> er meint, das einfach mal so machen zu können.
das klingt ein bischen nach nicht-sein-kann-weil-nicht-sein-darf.
Meine DMA ist getestet und läuft stabil. DMA muss eine einfache Lösung
sein, weil es bei DMA darum geht, große Datenmengen in einem festen
Schema zu verarbeiten. Der Entwicklungsweg ging hier von anfangs
kompliziert bis zum Schluss recht einfach. Gefrickel ist das
zugegebenermaßen bei der Abfrage der Linktabel und des Anfangssektors -
kein schöner Programmstil, der trotzdem funktioniert. Der DMA-Teil ist
kein Gefrickel. Er funktioniert wie er soll. Kleinigkeiten kann man
sicher noch verbessern, aber eine grundsätzlich bessere Lösung die auch
nur annähernd vergleichbare Datenraten stabil schafft, gibt es offenbar
nicht.
>einfach mal so machen zu können
ist wochenlange Arbeit und viele dummen Fragen ans Forum mit Antworten,
die nur teilweise weitergeholfen haben. Ohne die Häme mancher Antworten
hätte ich mir die Arbeit aber auch nicht gemacht.