Hi, bin ziemlich neu in der Mikrocontrollerprogrammierung und kenne noch nicht die "Gemeinheiten" des atmega8 ;-) Ich versuche, Ulrich Radigs SD-Kartenlesecode (link s. u.) in meinem Projekt umzusetzen. http://www.ulrichradig.de/home/index.php/avr/mmc-sd Dazu habe ich alles bis auf die usart-Dateien eingebaut und die SD-Card natürlich auch physikalisch mit den SPI-Pins des atmega8 verbunden, so wie in der vereinfachten Schaltung angegeben: http://www.ulrichradig.de/site/atmel/avr_mmcsd/gfx/MMCSDSCH.JPG Es wird die Konfiguration für Hardware-SPI verwendet. Wenn ich das Programm mit der main.c so wie sie im Anhang ist in dem atmega ausführe, sehe ich auf dem Display: Hello! -> SUCHE SD-CARD -> SD GEFUNDEN -> Hello! -> ... wieder von vorne und immer so weiter. Ich nehme an, wegen irgend etwas stürzt der Controller ab und startet von vorn. Jetzt geht die Fehlersuche los. Wenn ich die Zeile fat_cluster_data_store(); auskommentiere, geht's weiter, nämlich bis er mit der Anzeige "HAUPTSCHLEIFE" aufhört. Soweit, so gut und nachvollziehbar, wenn man davon ausgeht, dass da irgendwo der Fehler ist. Was mich aber irritiert ist, dass er auch dann bis "HAUTPSCHLEIFE" kommt, wenn man fat_cluster_data_store(); drinn lässt, aber die beiden Zeilen mmc_read_csd (Buffer); und Clustervar = fat_read_dir_ent(0,a,&Size,&Dir_Attrib,Buffer); auskommentiert!!! Das bedeutet doch im Umkehrschluss, wenn man diese nicht auskommentiert, dann "weiß" der Microcontroller bereits bevor er bei der Ausgabe von "TEST" ist (denn da stürzt er ja dann schon ab), dass die beiden Funktionen mmc_read_csd und fat_read_dir_ent demnächst kommen werden und beschließt, lieber rechtzeitig abzustürzen?! Ich kann mir das leider nicht erklären, eigentlich stürzen Programme doch erst ab, wenn sie den Fehler erreicht haben?? Ich habe dann gedacht, vielleicht ist der Fehler in einem "parallelen" Programmteil und habe die sei(); auskommentiert, um die Interrupts zu deaktivieren, hat aber nichts gebracht. Nun denke ich, gibt es irgend eine Beschränkung derart, dass sich der Code zu weit verzweigen und verschachteln würde, wenn nicht ein oder zwei Funktionen auskommentiert sind? Dann könnte ich mir ja noch vorstellen, dass der atmega zu früh abstürzt... Oder ich steh' einfach auf'm Schlauch. Vielen dank, dartrax PS: Ach ja, einiges in meinem Code sieht bestimmt "schrecklich" aus, ich lerne noch ;-)
Schonmal darüber nachgedacht, dass der Speicher des Mega-8 zu klein ist... ? Welchen Controller hat denn Ulrich Radig verwendet - und warum?
Klar habe ich darüber nachgedacht, deshalb habe ich das ja im untersten Absatz wissen wollen, ob es da so eine Beschränkung gibt. Leider bist du mir die Antwort schuldig geblieben. Von der Größe her passt das Programm locker, mit dem FAT und SD-Code ist er von etwa 43% auf 74% angewachsen. Der MP3-Player hier in der ersten Version verwendet erfolgreich einen Atmega8L, ich hatte diesen Code für den SD-Zugriff zuvor ausprobiert und die Größe belief sich auf 99%. Deswegen glaube ich, dass es schon machbar sein sollte, aber lasse mich natürlich auch eines besseren belehren. http://members.liwest.at/dobretsb/stephan/schaltung.html dartrax
Hi Und wie sieht es mit dem RAM aus? Ich tippe eher auf Stackfehler. MfG Spess
Hallo! Danke für deine Antwort. Der Compiler zeigt an: Program: 6100 bytes (74.5% Full) (.text + .data + .bootloader) Data: 253 bytes (24.7% Full) (.data + .bss + .noinit) Was ist ein Stackfehler? Habe leider nur einen Suchbegriff gefunden. Wie finde ich das raus? dartrax
Der Blick auf statische Daten hilft nicht viel weiter, wenn das Programm den grössten Teil seiner Daten auf dem Stack anlegt. Das betrifft also alle Daten, die in einer Funktion definiert und nicht ausdrücklich als "static" markiert sind. Hier beispielsweise liegt Buffer[] mit 512 Bytes auf dem Stack und taucht daher in der Angabe des belegten RAMs nicht auf. Frisst aber bereits die Hälfte davon weg.
Hi Der Stack ist in Speicherbereich, der vom oberen Ramende nach unten 'wächst'. Bei Unterprogrogrammaufrufen werden z.B. die Rückkkehradressen abgelegt. Compiler benutzen den auch zur Veriablenübergabe. Wenn der Stack in den RAM-Bereich kommt, der auch von deinem Programm genutzt wird, werden essentielle Daten überschrieben und es kommt unweigerlich zum Absturz. MfG Spess
Genau darauf wollte ich hinaus. Ich habe bislang noch keinen Code für FAT gesehen, der in einen Mega-8 gepasst hat - meist ist ein Mega-16 Mindestanforderung. Und seltsame, nicht nachvollziehbare Abstürze riechen geradezu danach, dass es ein Stack-Problem ist. Ergo: Größeren Controller nehmen oder den Code so umschreiben, dass es passt. Auf die Angaben des Compilers kannst Du Dich überhaupt nicht verlassen, weil bei der Belegung des RAM nicht die dynamischen Komponenten (z.B. lokal definierte Variablen) berücksichtigt werden. Ich würde die erste Variante nehmen ;-)
Marvin M. wrote: > Ich habe bislang noch keinen Code für > FAT gesehen, der in einen Mega-8 gepasst hat Dann hast du aber bisher zu wenige gesehen. Ich kenne 3 Dateisystemroutinen, und alle 3 laufen auf einem mega8. - eines von mir - das tiny Filesystem von ELM Chan - das von Ulrich Radig Das von Chan sogar in Schreib/Lese Konfiguration.
Ich glaube, dass ihr Recht habt und es am geringen Speicher liegt. Wenn ich nämlich spaßeshalber den unsigned char Buffer[512]; auf [12] verringere, stürzt es nicht ab. Da ich den Buffer jedoch brauche, muss ich sehen, warum vor dieser Deklaration irgendwo innerhalb des fat_cluster_data_store()-Aufrufs nochmal so viel Speicher verbraucht und scheinbar nicht wieder freigegeben wird (???). Es wird bereits innerhalb von fat_cluster_data_store() ein Buffer deklariert: unsigned char Buffer[BlockSize]; (BlockSize ist 512) Dann folgt der Aufruf ... = fat_addr (Buffer); Diese Funktion enthält zwei Aufrufe von mmc_read_sector(...). Sobald ich beide auskommentiere, funktioniert's. Lasse ich sie drin und kommentiere den gesamten Inhalt der Funktion mmc_read_sector aus, funktioniert's nicht mehr! Der Unterschied liegt doch lediglich in einem weiteren Funktionsaufruf. Keine weiteren Variablendeklarationen, nichts. Heißt dass, dass hier der Rückkehradressen-Stack überläuft? Der RAM müsste zu diesem Zeitpunkt 86 bytes (Compilermeldung, ich habe andere Funktionen entfernt, die ich im Moment nicht brauche) + 512 Bytes (Deklaration des Buffers) + ein paar weitere Deklarationen betragen. Eigentlich sollte Platz sein...? dartrax
... dartrax ... wrote: > Da ich den Buffer jedoch brauche, Dann mach ihn mal global. Dann wird dieser Verbrauch schonmal beim compilieren mitgezählt. > Es wird bereits innerhalb von fat_cluster_data_store() ein Buffer > deklariert: > unsigned char Buffer[BlockSize]; (BlockSize ist 512) Könntest du die Datei mal hier reinstellen ?
Hi Mir wird immer klarer, warum ich in Assembler programmiere. Danke. MfG Spess
Gute Idee^^ Die fat und mmc-Dateien von Ulrich Radig sind in den Anhängen (der folgenden Posts). Ich habe "ertestet", dass der Buffer bis 480 bytes das Programm in Ruhe lässt, bei 481 wird's kritisch (gibt "HAEPTSCHLEIFE" statt "HAUPTSCHLEIFE" am Ende aus), ab 482 stürzt es in der Routine ab. Ich habe ihm eben mal ein "static" davor gesetzt, Compiler sagt jetzt: Data: 599 bytes (58.5% Full) @Spess53 Man gewöhnt sich an alles. Auch an deine Spitzbübigkeiten ;-) dartrax
fat.h - Sorry, hat nicht geklappt. Kommt weiter unten.
Da Cluster Data Store ja nur ganz am Anfang aufgerufen wird, kannst du eigentlich auch den globalen Buffer dafür verwenden. Entferne als die Zeile aus der Funktion, und mache Buffer[512] global. Dann sollte das ganze mit 512 + ein paar Bytes auskommen.
JUCHHEEEEYYY!!!!! Die SD hat gerade ihre Ordner- und Dateinamen im Root auf dem Display preisgegeben! Die Fehlerursache und dein Tipp, Benedikt, waren goldrichtig! DAANKEE!! dartrax
Hi ... dartrax ... könntest du mal deine Version der mmc.c und main.c posten? Ich habe nämlich das gleiche Problem mit der Allocation des Buffers auf einem ATmega88 VooChee
Hi! Ich hab dir den Code in den Anhang gepackt. Einige Funktionen, die ich inzwischen hinzugefügt hatte für andere Funktionen habe ich in deiner Kopie entfernt, aber ich kann's im Moment leider nicht testen, ob's noch funktioniert, da ich gerade "auf dem Sprung" bin. Wenn du Probleme hast, kann ich vorr. Dienstag/Mittwoch nochmal reinschauen. Die Deklaration des Buffers ist in fat.h, ich habe insgesamt aber nur wenige Zeilen ändern müssen. Im Anhang ist auch ein Screenshot, wie du die SD-Karte mit der Kommandozeile (XP) formatieren solltest, wobei du den Wert für a so anpassen musst (halbieren/verdoppeln), dass hinterher "16 Bits in jedem FAT-Datensatz" übrig bleiben. Die SD-Karte ist wie von Ulrich Radig vorgeschlagen angeschlossen: http://www.ulrichradig.de/site/atmel/avr_mmcsd/gfx/MMCSDSCH.JPG Verwendet werden die SPI-Pins des atmega8, das ist voraussetzung wenn man den Hardware-SPI (wie ich) verwenden will (was mir vorher nicht ganz klar war). Die Pinbelegung siehst du in mmc.h. Viel Erfolg! dartrax
Hi dartrax habe es mit deinem Codebeispiel nun auch auf einem ATmega88 zum laufen gebracht. Meine globale Buffer-Variable war irgendwie nicht so global wie deine :) Einige Probleme die ich hatte rührten daher, das ich den ISP noch draufstecken hatte, was sich scheinbar mit dem SPI nicht verträgt. THX VooChee
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.