Guten Tag,
ich benutze in einem AVR Programm FatFS zusammen mit der FIFO
Bibliothek von Falk Brunner.
Die grundsätzliche Idee war:
Ein AD Wandler misst eine Spannung und im ADC Interrupt wird der Wert in
den Fifo geschrieben. Hat der Fifo einen gewissen "Füllstand" erreicht,
schreibe ich die Werte mit FatFS auf eine SD Karte, sofern das Schreiben
aktiviert ist.
Ist das Schreiben nicht mehr aktiviert, es befinden sich aber noch Daten
im Fifo, so sollen diese auch auf die SD Karte geschrieben werden.
Den Schreib- und Lesezugriff auf den Fifo habe ich aus der Beispieldatei
main_fifo.c übernommen.
Nachdem ich im normalen Betrieb Daten auf die Karte geschrieben und dann
den Schreibmodus deaktiviert habe, sollten eigentlich die im Fifo
verbliebenen Restdaten einmalig auf die SD Karte geschrieben werden.
Danach wird der Füllstand des Fifos aktualisiert und er sollte nach
meinem Verständnis leer sein.
Das Problem ist, dass der Füllstand des Fifos in meinem Programm laut
fifo_get_level() allerdings nie den Wert 0 erreicht. Der Programmteil,
der die Restdaten eigentlich nur einmalig abspeichern soll, wird
fortlaufend aufgerufen.
Nach meinem Verständnis sollte der Füllstand nach dem Schreiben mit
f_write und der Korrektur des Lesezeigers mit fifo_read_bursted
eigentlich den Wert 0 erreichen. Das tut er aber nicht.
Scheinbar übersehe ich irgendetwas oder benutze die Fifo Funktionen
falsch.
Wäre schön wenn jemand einen Blick auf den Code werfen könnte und mir
zeigt, was ich falsch mache.
Ich kann mir das Verhalten im Augenblick nicht so recht erklären.
In der fertigen Textdatei sieht das dann so aus: (steht alles
hintereinander, zur Verdeutlichung leicht gekürzt und formatiert)
Man sieht einen Zusammenhang zwischen den zunehmenden "x" und den
abnehmenden "NUL".
Aber woher zieht er die "NUL", die er auf die Karte schreibt und wieso
steigt die Anzahl der "x"?
Die UART Ausgaben im Code ergeben:
1
00507// Ausgabe des Fifo Füllstandes mittels "uart_uint(fifo_get_level(&fifo),5);"
2
00512
3
Schreibvorgang:00512
4
00005
5
00010
6
00015
7
00020
8
00025
9
00030
10
00035
11
00040
12
00045
13
00050
14
00055
15
00060
16
00065
17
00070
18
00075
19
00080
20
00085
21
00090
22
00095
23
00100
24
00105// Hier wird der Schreibvorgang manuell beendet, Schreiben der Reste soll beginnen
25
Restdatenspeichern:00105//fifo_get_level unmittelbar nach Eintritt, kurz danach wird das 'x' in den Fifo
26
blocksize00512// Wert von fifo_block_size
27
wrapsize00512// Wert von fifo_wrap_size
28
levelende00618// fifo_get_level nach der Korrektur des Lesezeigers durch fifo_read_bursted
29
Restdatenspeichern:00618// Funktion wird neu aufgerufen
30
blocksize00512
31
wrapsize01024
32
levelende00107
33
Restdatenspeichern:00107
34
blocksize00512
35
wrapsize00512
36
levelende00620
37
Restdatenspeichern:00620
38
blocksize00512
39
wrapsize01024
40
levelende00109
41
Restdatenspeichern:00109
42
blocksize00512
43
wrapsize00512
44
levelende00622
45
Restdatenspeichern:00622
46
blocksize00512
47
wrapsize01024
48
levelende00111
49
Restdatenspeichern:00111
50
blocksize00512
51
wrapsize00512
52
levelende00624
53
Restdatenspeichern:00624
54
blocksize00512
55
wrapsize01024
56
levelende00113
Der Code sieht in Auszügen so aus:
Main.h:
1
#define fifo_buffersize 1024
2
#define fifo_writesize 512
Main.c:
1
fifo_tfifo;
2
fifo_data_tfifo_bufferarray[fifo_buffersize];
3
4
5
ISR(ADC_vect){
6
if(SDcard_ready&&AnalogChannel.WriteEnable){
7
if(fifo_get_free_ISR(&fifo)){
8
if(fifo_write_code0&(1<<i)){
9
fifo_write_ISR(&fifo,'a');// bei Start des Schreivorgangs
@Michael N. (natulo)
>ich benutze in einem AVR Programm FatFS zusammen mit der FIFO>Bibliothek von Falk Brunner.
Schön. Aber ist der Betreff deines Beitrag nicht ein "wenig" lang? ;-)
>Die grundsätzliche Idee war:
Die Idee ist grundsätzlich richtig. Sie muss aber auch korrekt umgesetzt
werden.
Wie schnell arbeitet dein ADC (Abtastrate)?
>Ist das Schreiben nicht mehr aktiviert, es befinden sich aber noch Daten>im Fifo, so sollen diese auch auf die SD Karte geschrieben werden.
Hier wird es schwammig.
>Nachdem ich im normalen Betrieb Daten auf die Karte geschrieben und dann>den Schreibmodus deaktiviert habe, sollten eigentlich die im Fifo>verbliebenen Restdaten einmalig auf die SD Karte geschrieben werden.>Danach wird der Füllstand des Fifos aktualisiert und er sollte nach>meinem Verständnis leer sein.
Nö, denn parallel zum Schreiben auf SD-Karte kommen ja neue Daten vom
AD-Wandler.
>Das Problem ist, dass der Füllstand des Fifos in meinem Programm laut>fifo_get_level() allerdings nie den Wert 0 erreicht.
Logisch.
>Der Programmteil,>der die Restdaten eigentlich nur einmalig abspeichern soll, wird>fortlaufend aufgerufen.
Programmfehler.
>Nach meinem Verständnis sollte der Füllstand nach dem Schreiben mit>f_write und der Korrektur des Lesezeigers mit fifo_read_bursted>eigentlich den Wert 0 erreichen. Das tut er aber nicht.
Siehe oben.
Ich glaube der Fehler liegt in deinem 2. Abschnitt.
1
// Inhalt des Fifo auf Karte schreiben, wenn kein Kanal mehr loggt, aber noch Daten im Fifo liegen
Kleiner Tip. Die Sequenz mit den 2 Blöcken für den FIFO-Zugriff und
SD-zugriff packt man besser in eine Funktion. Denn sie wird 2 mal
verwendet und ist recht lang. Damit wird deine Hauptschleife kürzer und
übersichtlicher.
Hallo Falk, vielen Dank für die Antwort!
Falk B. schrieb:> @Michael N. (natulo)>> Schön. Aber ist der Betreff deines Beitrag nicht ein "wenig" lang? ;-)>
Ich wusste nicht wie ich das Problem auf den Punktbringen soll, daher
wollte ich möglichst viele Informationen in den Titel stopfen damit
direkt erkennt, worum es in dem Thema geht.
>>Die grundsätzliche Idee war:>> Die Idee ist grundsätzlich richtig. Sie muss aber auch korrekt umgesetzt> werden.>> Wie schnell arbeitet dein ADC (Abtastrate)?>
Über einen 1ms Interrupt mit 1/10/100/1000Hz jeweils als Einzelwandlung.
>>Ist das Schreiben nicht mehr aktiviert, es befinden sich aber noch Daten>>im Fifo, so sollen diese auch auf die SD Karte geschrieben werden.>> Hier wird es schwammig.>
Da SD Karten erst bei Vielfachen von 512 Byte richtig schnell schreiben,
war die Idee einen Fifo mit z.B. 2048 Byte Größe anzulegen, in den dann
die Wandlerwerte geschoben werden.
Wenn der Füllstand des Fifo dann z.B. 1024 Byte übersteigt, sollen diese
auf die SD Karte geschrieben werden. Das wäre der "normale"
Schreibvorgang.
Wenn ich den Schreibmodus beende, aber erst z.B. 240 Byte im Fifo sind,
sollen diese auf die SD Karte geschrieben werden, auch wenn noch nicht
die z.B. 1024 Byte voll sind. Daher das Schreiben der "Restdaten".
Zumindest ist das mein aktueller Ansatz.
>>Nachdem ich im normalen Betrieb Daten auf die Karte geschrieben und dann>>den Schreibmodus deaktiviert habe, sollten eigentlich die im Fifo>>verbliebenen Restdaten einmalig auf die SD Karte geschrieben werden.>>Danach wird der Füllstand des Fifos aktualisiert und er sollte nach>>meinem Verständnis leer sein.>> Nö, denn parallel zum Schreiben auf SD-Karte kommen ja neue Daten vom> AD-Wandler.>
Der AD-Wandler läuft zwar weiter, die Ergebnisse werden aber nur in den
Fifo geschrieben wenn die jeweilige "WriteEnable" Variable gesetzt ist.
(if-Abfrage im ADC Interrupt)
Beim Deaktivieren des Schreibmodus wird die Variable auf 0 gesetzt.
>>Der Programmteil,>>der die Restdaten eigentlich nur einmalig abspeichern soll, wird>>fortlaufend aufgerufen.>> Programmfehler.>
Korrekt.
>> Ich glaube der Fehler liegt in deinem 2. Abschnitt.>
Ebenfalls korrekt. Als ich deine Antwort gelesen habe, hat mich
sinnbildlich der Blitz getroffen.
Wenn man sich in Ruhe verdeutlicht was das Programm da macht, ist das
einer dieser "logisch, wieso habe ich das nicht gesehen?" Fehler.
Was ich gemacht habe:
Es sind z.B. 100 Byte an Restdaten im Fifo, schreibe fifo_block_size =
512 Byte aus dem Fifo auf die SD Karte und korrigiere den Lesezeiger um
512 Byte. Da braucht man sich dann auch nicht wundern, wieso das schief
geht.
Richtig und logisch ist natürlich deine Korrektur:
Guck wie viele Restdaten noch im Fifo sind, merk dir die Anzahl und
schreibe dann diese Anzahl an Bytes auf die SD Karte und korrigiere
entsprechend den Lesezeiger.
Mit dem korrigierten Code klappt es.
fifo_read_bursted(&fifo,fifo_block_size);// Anm.: hier dann natürlich ebenfalls rest_size
18
19
f_sync(&file1);
20
}
>> Kleiner Tip. Die Sequenz mit den 2 Blöcken für den FIFO-Zugriff und> SD-zugriff packt man besser in eine Funktion. Denn sie wird 2 mal> verwendet und ist recht lang. Damit wird deine Hauptschleife kürzer und> übersichtlicher.
Danke für den Tipp, werde ich machen!
@ Michael N. (natulo)
>> Schön. Aber ist der Betreff deines Beitrag nicht ein "wenig" lang? ;-)>Ich wusste nicht wie ich das Problem auf den Punktbringen soll, daher>wollte ich möglichst viele Informationen in den Titel stopfen damit>direkt erkennt, worum es in dem Thema geht.
Nicht sinnvoll, das gehört in den 1. Beitrag. Die Überschrift sollte
eher kurz und prägnant sein.
Problem mit FATfs + FIFO
>Da SD Karten erst bei Vielfachen von 512 Byte richtig schnell schreiben,>war die Idee einen Fifo mit z.B. 2048 Byte Größe anzulegen, in den dann>die Wandlerwerte geschoben werden.
Ja, aber das macht FATfs schon, das hat einen 512 Byte Sektorpuffer.
Beitrag "Re: Geschwindigkeitsfrage AVR auf SD">Wenn der Füllstand des Fifo dann z.B. 1024 Byte übersteigt, sollen diese>auf die SD Karte geschrieben werden. Das wäre der "normale">Schreibvorgang.
Ist OK.
>Wenn ich den Schreibmodus beende, aber erst z.B. 240 Byte im Fifo sind,>sollen diese auf die SD Karte geschrieben werden, auch wenn noch nicht>die z.B. 1024 Byte voll sind. Daher das Schreiben der "Restdaten".
Schon klar.
>Ebenfalls korrekt. Als ich deine Antwort gelesen habe, hat mich>sinnbildlich der Blitz getroffen.
;-)
>Wenn man sich in Ruhe verdeutlicht was das Programm da macht, ist das>einer dieser "logisch, wieso habe ich das nicht gesehen?" Fehler.
Das ist das "ich sehe den Wald vor lauter Bäumen nicht"-Problem.
>Mit dem korrigierten Code klappt es.
Heureka!