mikrocontroller.net

Forum: Compiler & IDEs Externes Ram: printf() - Problem


Autor: Andreas Paulin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habe ein externes SRAM an ATMEGA angebunden.
60kb zur Verfügung.

ExRam nur als Heap, daher erst in main() die Freischaltung:
// mit Waitstates:
MCUCR |= (1<<SRE)|(1<<SRW10);    
XMCRA |= (1<<SRW11);        // the number of wait-states
XMCRB |= (1<<XMBK);     

Nur: Die Testroutine, die ich dafür geschrieben habe zeigt ein 
merkwürdiges Verhalten.
Der Test läuft so:
- Ein Pointer 'pExRam' wird mit '__malloc_heap_start' (1100h) 
initialisiert
- Dann bis '__malloc_heap_end' (FFFFh)hochgezählt.
- Jede Speicherzelle '*pExRam' wird einmal mit 55h und mit AAh 
beschrieben, gelesen und gecheckt.

Damit der Test nicht bereits verwendete Zellen des Heap korrumpiert, 
wird
- zuerst der Wert gesichert
- dann getestet
- dann der ursprüngliche Wert zurückgeschrieben

Der Test läuft einwandfrei von 1100h bis FFFFh.

Seltsamerweise verschluckt sich der ATMEGA128 an printf()-Aufrufen 
innerhalb der Testschleife, wenn der Format/Ausgabestring
"etwas länger" wird. Siehe Codeauszug...
Heißt dann: Kiste steht, nichts geht mehr, bestenfalls Neustart..
Aber: 'printf()' wird immer erst aufgerufen, NACHDEM die Speicherzelle 
gecheckt UND der ursprüngliche Inhalt wieder restauriert wurde....

????
Codeauszug anbei.

Der RAMcheck läuft auch ohne printf(), aber trotzdem: Hat jemand einen 
Tip für mich, wo der Hund begraben liegen könnte?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Womit hast du denn stdout angelegt?  (fdevopen, fdev_setup, FDEV_SETUP)

Autor: Andreas Paulin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs mit dem Macro angelegt:
#ifndef STDIO_DEFINED  
  #define STDIO_DEFINED
  static FILE uart0_stream = FDEV_SETUP_STREAM(uart0_putchar, uart0_getchar, _FDEV_SETUP_RW);
  static FILE uart1_stream = FDEV_SETUP_STREAM(uart1_putchar, uart1_getchar, _FDEV_SETUP_RW);
#endif  
if (UartNum==0)
  {
  stdout = &uart0_stream;
............

Meines Wissens wird da nichtmal malloc() verwendet.
Und selbst WENN printf() auf das ExRam zugreift: Der Speicherzellentest 
AN SICH ist sehr kurz, außerhalb jedes printf-Aufrufes und transparent, 
also zerstört nicht den Zelleninhalt:
ucTemp1=*pExRam;
*pExRam=0x55;
ucTemp2=*pExRam;    // Inhalt zurücklesen
*pExRam=ucTemp1;    // alten Wert zurückschreiben

Hm.......

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Paulin wrote:

> Meines Wissens wird da nichtmal malloc() verwendet.

Ja, darauf wollte ich auch hinaus.

Nee, dann habe ich aus der Kalten keine Idee, was da schief gehen
könnte.  Hast du 'ne Chance, das mit einem JTAG ICE nachzuvollziehen?

Autor: Andreas Paulin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, ICE haben wir noch nicht.
Aber ist vielleicht mal ne gute Idee. Kost' 250 Steine, so'n Ding, und 
wenn ich überlege, wie oft ich schon tagelang wie Sherlock Holmes nach 
der Nadel im Heuhaufen gesucht habe.........

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Paulin wrote:
> Nein, ICE haben wir noch nicht.
> Aber ist vielleicht mal ne gute Idee. Kost' 250 Steine, so'n Ding, und
> wenn ich überlege, wie oft ich schon tagelang wie Sherlock Holmes nach
> der Nadel im Heuhaufen gesucht habe.........

Beim Elektronikladen (http://elmicro.com/de/avrjtag.html) gibt's so ein 
Ding (von Olimex) für EUR 45,70; ich bin damit super zufrieden.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, das Olimex-Teil ist halt ein Clone vom JTAG ICE mkI.  Damit kannst
du (mal aus Industriesicht) nur noch alten Schrott debuggen.

Interessanter dürften die Bündel aus JTAG ICE mkII + STK500 sein, die
es jetzt 'ne Zeit lang bei den Atmel-Distris gab (Spoerle zum Bleistift,
wohl auch Ineltek), die gab's zusammen für was um die 150 Fragezeichen.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ändere doch mal deinen Speichertest so:

Allokiere mit malloc den größtmöglichen Speicherblock, der Heap sollte 
davor zwar initialisiert sein, aber noch nicht benutzt.

Dann laß deinen Test über diesen Speicherblock laufen.

Dabei kannst der Heapverwaltung nicht ungewollt in die Quere kommen und 
die testet dir andereseits zumindest einen großen Teil des für die 
Heapverwaltung benötigten Speichers.

Autor: Andreas Paulin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das Problem gestern erstmal zurückgestellt, da der Ramcheck 
OHNE die printf-Statemenst einwandfrei durchlief. Prioritäten setzen!

Aaaaaaaaaaaaaaber:
Diese seltsamen Symptome hatte ich aber in ganz anderen Bereichen immer 
und immer wieder: Scheinbar irrelevante Codepartikelchen bringen die 
ganze Kiste zum Stehen
Hm.... Verdacht auf irgendwelche Speicherprobleme?
Schon.....
Habe dann meinen Widerwillen unterdrückt und mir mal das .MAP-File 
angesehen ächz WAS'n Gewurschtel. Ist ja echt ein Fall für'n Guru ;-)

Bin jetzt auch ein bischen Guru :) Das Ram war schlicht voll.
Die .data-Sektion reichte bis 0x00800dd0.
Ich hatte ein fettes, statisch deklariertes Array hatte ich vergessen, 
und die 4kB vom ATMEGA128 waren doch schon ziemlich voll......

Und ich denke, dass die langen printf-Strings über den Stack übergeben 
werden..? Und das war wahrscheinlich das Problem.

Habe das Array vorläufig mal rausgeschmissen, und plötzlich läuft alles 
schön rund :)
Memory checken!!

Hatte also nichts mit dem ext. SRAM zu tun, schien nur so........

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, die Mapfiles sind nur für Gurus, ich weiß gar nicht, warum die Leute
so auf diese Dinger stehen.  Eigentlich sind die nur nützlich für
jemanden, der am Linker oder den Linkerscripts arbeitet.

Das, was die meisten Leute als Map-Datei erwarten, ist beim GCC eher
die Symboltabelle.  Die bekommt man mittels avr-nm aus dem ELF-File
heraus.  Das WinAVR-Makefile müsste mittlerweile auch standardmäßig
eine Datei mit der Endung .sym damit anlegen.

Autor: Andreas Paulin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, herzlichen Dank für die Tips.
Habs jetzt hin- und herprobiert und es ist reproduzierbar einfach ein 
volles RAM.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.