Forum: Mikrocontroller und Digitale Elektronik µC eines Datenloggers hängt sich nach unbestimmter Zeit auf !


von Gast (Gast)


Lesenswert?

Hallo ihr Experten!

mir macht zur Zeit mein µC meines Datenloggers ein wenig 
Schwierigkeiten!
Verwendet wird ein AT90CAN128. Peripherie ist eine RTC und ein 
SD-Card-Slot.

Der Datenlogger loggt Daten mit und schreibt diese alle 960 ms auf eine 
SD / MMC - Karte. Der verwendete Bus ist der SPI-Bus. Dieser wird zuerst 
mit ca. 125 kHz initialisiert, also eig. so wie das OK sein sollte ( 
<400 kHz ). Nach einer kurzen Delay-Time und dem Senden von mind. 74 
Clocks und den entsprechenden Commands an die Karte ist diese 
initialisiert.

Nun wird der SPI Bus auf 2 MHz eingestellt, da die verwendeten 
Pegelwandler nicht mit Frequenzen >3 MHz arbeiten können. Zusätzlich 
wird ein FAT16 Dateisystem initialisiert.

Komisch ist nun, dass sich nach unbestimmter Zeit, z.B. mal nach 2 1/2 
Stunden, 4 Stunden, 6 3/4 Stunden das Programm bzw. die Software einfach 
aufhängt und nicht mehr weiterarbeitet! Im Debugmodus konnte 
herausgefunden werden, dass wohl der Schreibzyklus für ein Byte 
(sd_write_byte()-Funktion) zu lange dauert. Aber warum geht das die 
ersten 2-3, manchmal auch 5-6 Stunden gut? Ich meine, so werden 
Langzeitmessungen eig. unmöglich!!

Hat jemand ne Idee, an was dies legen könnte? Pegelwandler (MAX3371) 
vllt. ?!

Viele Grüße
S.

von Benedikt K. (benedikt)


Lesenswert?

Vermutlich wird das Wearleveling der SD Karte aktiv. Einige SD Karten 
benötigten beim Schreiben ab und zu mal etliche 100ms bis >500ms für 
einen Sektor.
Du musst halt einen ausreichend großen Puffer im RAM vorsehen, in den 
alle Daten passen die in dieser Zeit ankommen.

von pfft. (Gast)


Lesenswert?

Das Problem waere eher etwas fuer die Kategorie : Wie debuge ich ein 
Programm. Das beinhaltet Software und Hardware, die sich etwas anders 
verhaelt als urspruenglich angenommen.

von pfft. (Gast)


Lesenswert?

Wenn man natuerlich nach jedem sektor, um den das file laenger wird das 
Direktory updatet, so hat man verloren. Ich wueerd mal ein file der 
maximalen leange allozieren, und nachher nur noch auf die betroffenen 
Sektoren zugreifen. Und nur ganze sektoren neu schreiben, keine 
teilweisen sektoren.

von Gast (Gast)


Lesenswert?

Hallo.

Erstmal vielen Dank für eure Antworten!

@ Benedikt:
Ist es möglich, dieses Wearleveling der SD-Karte irgendwie zu umgehen 
(z.B. durch schnelleren Clock ?!) bzw. auszuschalten (womöglich durch 
ein Command?!) ? Würde dann aber die Karte nicht einfach die Daten 
verwerfen und neu starten ? Oder hängt sie sich komplett auf ?
Ansonsten ist das mit dem Puffer eine gute Idee.

@pfft.:
Was meinst du mit "Wie debugge ich ein Programm" ? Das Programm lief 
über eine JTAG-Schnittstelle online mit. Als der Fehler auftrat wurde 
PAUSE geklickt und der gelbe Pointer des AVR-Studios stand bei oben 
genannter Funktion (sd_write_byte())! Ich habe vorher bereits vermutet, 
dass es an einer der Schreibfunktionen liegen muss bzw. an irgendeiner 
Funktion, welche irgendwann den SPI-Bus zu lange belegt. Da klingt doch 
das von Benedikt genannte Wearleveling ganz plausibel.

Habt ihr sonst noch irgendwelche Ideen?
Bin über jede Antwort dankbar!

Viele Grüße
S.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Im Debugmodus konnte herausgefunden werden, dass wohl der
> Schreibzyklus für ein Byte (sd_write_byte()-Funktion) zu lange dauert.
Zu lang für was? Wo steht denn, wie lange der Zyklus dauern darf?
Du kannst niemals davon ausgehen, dass eine C-Funktion in der Zeit 
lim->0 abgearbeitet wird.

Ich habe an etliche Hersteller von Compactflashs mal die Frage gestellt, 
wie lange die Versorgungsspannung nach dem letzten Schreibbefehl (und 
abschliessendem fclose() ) noch stabil anliegen muß, dass die Daten 
sicher auf dem CF gespeichert werden. Eigentlich eine einfache Frage, 
aber die Antworten reichen von "keine Reaktion", über "typisch 300ms" 
bis "in der Regel maximal 600ms".
Im Endeffekt habe ich dann den Dosenöffner genommen und automatisiert 
über jeweils eine Woche direkt an den Steuerleitungen des Flashspeichers 
im CF gemessen. Heraus kam, dass die von den Herstellern vorher 
abgelieferten Zahlenwerte eigentlich nur irgendwelche Hausnummern 
waren...  :-o

von holger (Gast)


Lesenswert?

>Als der Fehler auftrat wurde
>PAUSE geklickt und der gelbe Pointer des AVR-Studios stand bei oben
>genannter Funktion (sd_write_byte())! Ich habe vorher bereits vermutet,
>dass es an einer der Schreibfunktionen liegen muss bzw. an irgendeiner
>Funktion, welche irgendwann den SPI-Bus zu lange belegt. Da klingt doch
>das von Benedikt genannte Wearleveling ganz plausibel.

Nicht unbedingt. Wenn der SS Pin nicht als Ausgang
definiert ist, oder als Eingang mit Pullup, kann es zu
solchen SPI Hängern kommen. Grund dafür ist das schon
ein kurzes Low auf SS reicht um den Master in den
Slave Modus zu schalten. Wenn der SS Pin floatet
reicht es schon mit der Hand in die Nähe der Schaltung
zu kommen.

von pfft. (Gast)


Lesenswert?

Ist eine EEPROM Write funktion blockierend ? Wozu waer das denn gut ? 
Das waer aber ganz schlecht. In die Tonne mit dem Dreck.

von Benedikt K. (benedikt)


Lesenswert?

Gast schrieb:
> Ist es möglich, dieses Wearleveling der SD-Karte irgendwie zu umgehen
> (z.B. durch schnelleren Clock ?!) bzw. auszuschalten (womöglich durch
> ein Command?!) ?

Nein.

> Würde dann aber die Karte nicht einfach die Daten
> verwerfen und neu starten ? Oder hängt sie sich komplett auf ?

Fragst du ab ob die Karte bereit ist, oder sendest du einfach drauf los?
Wenn das ganze für immer an der Stelle hängen bleibt, dann ist das nicht 
das Wear Leveling, sondern sonst ein Problem in der Software oder der 
Hardware.

von pfft. (Gast)


Lesenswert?

Datentragerzugriffsprozeduren duerfen natuerlich nicht blockierend sein. 
Sie muessen einen Schreib/Lesefehler abfangen koennen, und neu 
aufsetzten. Falls eine Operation nach Reties nicht funktioniert, so muss 
das Programm weiter laufen koennen.

von Gast (Gast)


Lesenswert?

Hallo,

nochmal vielen Dank für die Antworten. Hab mir jetzt mal die SW nochmals 
durchgeschaut und versuche euch mal das Problem bzw. die SW etwas 
genauer zu erläutern.

Die Daten werden alle in einer Textdatei (*.txt) formatiert gespeichert. 
Es wird die Uhrzeit (empfangen über TWI-Schnittstelle) geschrieben und 
dann die relevanten Werte zu diesem Zeitpunkt (je 67 Stück). Und das, 
wie erwähnt, alle 960ms. Soweit so gut.

In der main()-Funktion wird zuerst abgefragt ob die *.txt - Datei 
vorhanden ist. Wenn nicht, wird sie angelegt. Auch noch simpel.
Danach wird eine Funktion gerufen, welche vom CAN-Bus die Daten 
empfängt. Dabei wird zuerst die Uhrzeit (vom TWI empfangen und) 
geschrieben und dann die vom CAN-Bus empfangenen Daten. Dabei wird 
geprüft, ob im aktuellen Sektor noch Platz ist, wenn nicht, wird der 
nächste geladen. Gleichermaßen wird mit dem Cluster verfahren. Wenn 
alles OK ist, dann wird das Byte auf die Karte geschrieben.
Zuvor wird natürlich ein Sektor an die Karte geschrieben, in welchen 
dann die Daten geschrieben werden. Dabei wird CMD24 gesendet, der Befehl 
zum Senden von 512 Bytes bzw. 1 Sektor. Danach wird ein Clock gesendet 
und das StartByte bzw. das sog. Datatoken (0xFE). Danach wird der Sektor 
bzw. die 512 Bytes geschrieben und das / die CRC-Byte/s, welche aber im 
SPI-Mode ja sowieso ignoriert werden. Es wird nun gewartet, bis die 
Karte wieder bereit ist und der SPI wird wieder disabled.
Erst dann werden die eigentlichen Daten geschrieben. Im Prinzip wurde 
sich größtenteils an die Sourcecodes von U.Radig und R.Riegel 
orientiert. Also dürfte das eigentlich soweit passen!

Ich frag mich langsam echt, was da los ist?!

Mit freundlichen Grüßen

S.

von Benedikt K. (benedikt)


Lesenswert?

Und wo bleibt die Software jetzt genau hängen? Beim Warten auf die SD 
Karte oder sonstwo?

von Gast (Gast)


Lesenswert?

Sie bleibt in der Funktion sd_write_byte() hängen. Und zwar an folgender 
Stelle:

while(!(SPSR & (1<<SPIF))); // Wartet bis Byte gesendet wurde

MfG

von holger (Gast)


Lesenswert?

>Sie bleibt in der Funktion sd_write_byte() hängen. Und zwar an folgender
>Stelle:
>
>while(!(SPSR & (1<<SPIF))); // Wartet bis Byte gesendet wurde


Das kann nur das hier sein:

Beitrag "Re: µC eines Datenloggers hängt sich nach unbestimmter Zeit auf !"

von Gast (Gast)


Lesenswert?

Du meinst also, dass ein PullUp-Widerstand auf der SS Leitung fehlt ? Da 
muss ich mich nachher mal erkundigen, bin aber grade in ein anderes 
Projekt vertieft. Sobald's was Neues gibt, meld' ich mich.

Trotzdem schon mal vielen Dank für eure Tipps!

Was könnte man, vorausgesetzt der PullUp wäre dran, noch dagegen machen 
?

MfG

von holger (Gast)


Lesenswert?

>Was könnte man, vorausgesetzt der PullUp wäre dran, noch dagegen machen
>?

Den Pin auf Ausgang schalten und Pullup weglassen.

von Gast (Gast)


Lesenswert?

Hallo,

nun ja, es werden vier bidirektionale Pegelwandler (MAX3371) verwendet, 
welche alle einen internen PullUp enthalten. Diese hängen je an SS, 
MISO, MOSI und SCK (Clock) der SPI. Beim Senden eines Commands an die 
Karte wird zuerst über SS disabled, dann werden mittels 
sd_write_byte(0xFF) 8 Clock Impulse (0xFF) gesendet wobei anschließend 
die Karte wieder über SS enabled wird. Ist diese Zeit bzw. sind die 
Clocks vielleicht zu kurz ? Danach wird das Command gesendet und auf 
eine Antwort der Karte gewartet mittels:

// Wartet auf eine gültige Antwort von der MMC/SD-Karte
while (tmp == 0xff)
{
  tmp = sd_read_byte();      // sd_read_byte() gibt nach Erfolg 0
  if (Timeout++ > 300) break;       zurück
}

  sd_write_byte(0xFF);           // Sendet 8 Clock Impulse
  return(tmp)

Wären unidireketionale Pegelwandler vielleicht besser?

MfG
S.

von Benedikt K. (benedikt)


Lesenswert?

Ist SS bei dir ein Ausgang, oder Eingang?
Wenn SS an CS der SD Karte geht, dann müsste dies doch eigentlich ein 
Ausgang sein. Von daher dürfte es eigentlich keine Probleme geben. Prüf 
das mal.

von Gast (Gast)


Lesenswert?

Der Port wurde als Ausgang definiert:

DDRB |= (1<<SPI_MOSI) ... Es wird auch nicht mehr umgestellt.

Das dürfte eigentlich keine Probleme machen!?

MfG

S.

von Gast (Gast)


Lesenswert?

Uups, das war wohl der falsche. Korrektur:

DDRB |= (1<<SPI_SS)

MfG

von holger (Gast)


Lesenswert?

>Der Port wurde als Ausgang definiert:
>
>DDRB |= (1<<SPI_MOSI) ... Es wird auch nicht mehr umgestellt.

Da sehe ich nur MOSI.
Entweder irgendeine Ausgabe auf DDRB schaltet den Pin
auf Eingang, oder SPCR wird von irgendwas so zermatscht
daß das SPI Modul deaktiviert wird.

von Benedikt K. (benedikt)


Lesenswert?

Lass das ganze mal laufen und schau mit dem Debugger nach ob SS wirklich 
auf Ausgang ist, wenn das ganze sich aufhängt.
Ansonsten bleibt der µC natürlich auch hängen wenn kein Wert gesendet 
wurde, und trotzdem gewartet wird, bis die Übertragung fertig ist. Dazu 
müsstest du deine Software man genau anschauen ob das sein kann.

von Gast (Gast)


Lesenswert?

Komplett ist die Init wie folgt:

DDRB &=~(1<<SPI_MISO);   //Setzt den Pin MMC_DI als Eingang
DDRB |= (1<<SPI_Clock);  //Setzt den Pin MMC_Clock als Ausgang
DDRB |= (1<<SPI_MOSI);   //Setzt den Pin MMC_DO als Ausgang
DDRB |= (1<<SPI_SS);     //Setzt den Pin SPI_SS als Ausgang
DDRB |= (1<<SD_VCC);     //Setzt den PIN SD_VCC als Ausgang

MISO,usw. als defines der Portnummern. Also nix weltbewegendes!
werd morgen das mal ausprobiern. danke

gruß

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.