Forum: Compiler & IDEs Speicher ATMega128


von Christian Rattat (Gast)


Lesenswert?

Hallo,

ich kämpfe hier weiterhin mit einem Problem und hab keine Ahnung, wie
ich das lösen soll. Vielleicht kann von Euch jemand einen Tipp geben:

Ich hab ein Programm das auf dem ATMega128 läuft. Darin werden neben
dem Code ein paar Arrays verwendet. Der avr-gcc packt den code in das
.text segment und die arrays in das .bss segment. Das lässt sich soweit
gut nachvollziehen. Nun ist das .bss segment aber voll (32k). Sobald ich
ein byte mehr im array verwende, wird andere speicher im .bss Segment
überschrieben, was sich prima nachprüfen lässt.

Auf der anderen Seite gibt es aber im .text Segment noch reichlich
platz und des weitere ein .data segment, das leer ist (0byte).

Kann mir jemand sagen ob und wie ich die Arrays in das .data oder .text
segment bekomme, oder wie ich prinzipiel auf diese Segmente überhaupt
zugreife und wie die im Speicher des ATM128 aufgeteilt sind? Gibt es da
eine gute Doku zu?

Danke schonmal,
Christian

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die ,,Segmentgröße'', die du vermutest, ist nicht dein Problem; es
gibt eine solche nicht (nicht bei 32 K).  Das schrob ich dir doch
schonmal.  Hier das Stück aus dem Linkerscript (für avr5):

MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = 128K
  data   (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
}

Obiges "data" enthält dabei sowohl .data als auch .bss (womit schon
klar ist, dass es keinen Sinn hätte, zwischen beiden zu
,,verschieben'').  .text ist ROM, ich denke nicht, dass du Variablen
in den ROM legen willst. ;-) (Du kannst natürlich konstante Tabellen
in den ROM legen, aber da musst du den Zugriff anders formulieren.)

Ich stelle nicht in Abrede, dass du irgendwo in ein Problem rennst,
aber es ist müßig, wenn du trotz Hinweisen das Problem hartnäckig
weiter dort suchst, wo du es selbst vermutest.  Entweder musst du
deine Suche von 0 anfangen und alle deine bisherigen Vermutungen
erstmal in Frage stellen, oder aber du reduzierst das Problem auf die
Minimalvariante, mit der auch andere es reproduzieren können, und
postest es hier.

von Christian Rattat (Gast)


Lesenswert?

Ok, hier ein reduzierter Code, der den Fehler reproduziert. Kommentare
im Code:

> ein struct zum aufnehmen der Fontdaten für ein Zeichen
struct CharacterInfoStruct
{
  unsigned char width;
  unsigned char height;
  unsigned char data[font_max_byte];
};

> für alle ASCII Zeichen eine struct
struct CharacterInfoStruct font_data[256];


>... und hier der Test:

> Auswertung reuziert auf das Zeichen 'A'. Wegen fehlender
Textausgabe aufgrund des kaputten Fonts hab ich einfach Linien
gezeichnet, funktioniert aber auch

DrawLine(100,0,100,20); > eine linie zur kontrolle

w = GetCharFromFlash(p, i+3); > zeichen info auslesen
if (w != 0x0c) > prüfen, ob wert korrekt
{
  DrawLine(120,0,120,20);
}

h = GetCharFromFlash(p, i+4);
if (h != 0x14)
{
  DrawLine(130,0,130,20);
}

> die Prüfung oben ergibt in allen Fällen (mit oder ohne den Fehler)
eine korrekte Ausgabe der Linien (d.h. w hat den Wert 0x0c und h den
Wert 0x14, das habe ich verifiziert). Nun schreiben wir die beiden
Werte in den zugehörigen struct:

font_data[65].width = w;
font_data[65].height = h;

> in font_data sollten nun width und height 0x0c und 0x14 gesetzt sein.
Die Kontrollausgabe, die nun folgt, gibt aus, dass die Werte für width
und height nicht(!) korrekt sind. D.h. dass direkt nach dem Schreiben
in die Fontdaten die Werte schon nicht mehr stimmen, oder erst gar
nicht geschrieben wurden.

DrawLine(200,0,200,20);
if (font_data[65].width != 0x0c)
{
  DrawLine(210,0,210,20);
}
if (font_data[65].height != 0x14)
{
  DrawLine(220,0,220,20);
}

Das Ganze lässt sich nun (zurück zu meinem ursp. Problem) darauf
reduzieren, dass der Fehler nur auftritt, wenn das .bss Segment  32767
byte überschreitet. Es mag sein, dass das Segment größer sein kann,
nichts desto trotz steht es direkt damit in Verbindung. Ich will auch
nicht ausschliessen, das ich noch was falsch mache, wüsste aber nicht,
was das sein sollte.

Irgendeine Idee dazu?

von Christian Rattat (Gast)


Lesenswert?

p.s. noch eine Anmerkung: Für den Test habe ich alles mit -O0
kompiliert.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

Jörg meinte vermutlich irgendein Minimalbeispiel das man compilieren
kann. Also idealerweise eine problem.c die sämtlichen nötigen Code
enthält.


Matthias

von Christian Rattat (Gast)


Lesenswert?

Hi,

das Beispiel ist glaube ich auch ohne compiler einfach nachzuvolliehen.
Die Frage ist doch eigentlich, wie es grundsätzlich passieren kann, das
man in Speicher schreibt und in der Anweisung direkt danach der
Speicherinhalt nicht mehr stimmt. Das würde bedeuten, das entweder der
Speicherzugriff falsch codiert wird (Compilerfehler oder Linkerfehler)
oder die Anweisungen nach dem Setzen der Werte selbst den Code
modifizieren (also entweder das Drawline, was ich ausschliessen kann,
da ich auch das rausgenommen habe) oder aber ein anderer Code asynchron
(Interrupt) die Daten überschreibt, welchen ich aber gar nicht habe.

Ich werde trotzdem noch mal eine Demo kodieren und posten, wenn das
mehr helfen sollte.

Grüße,
Christian

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Daß das Beispiel nachzuvollziehen ist, bezweifelt ja gar keiner. Dein
Problem ist es damit aber noch lange nicht!
Um irgendwelche möglichen Compiler-/Linkerfehler nachvollziehen zu
können, braucht man eben ein Kompilierbares Minimalbeispiel. Mach Dich
aber schon mal darauf gefasst, daß der Fehler zu 99,9% ca. 50cm vor dem
Bildschirm entsteht ;-)

von Christian Rattat (Gast)


Angehängte Dateien:

Lesenswert?

Ok, hier ein sample, das den Bug reproduzierbar macht. In dem
ac_graphic.c passiert das ganze in InitializeGraphics(). Ihr müsst ggf.
zum Testen die Ausgabe auf etwas geeignetes bei Euch umsetzen. Ich habe
alle urspr. Kommentare entfernt und neue zur Beschreibung eingefügt.
Hoffe, das reicht so aus.

Es gibt dort einen dummy-buffer, der einfach nur Speicher im .bss
belegt. Setzt man den runter auf zB 1000 funktioniert alles. In dem
Zustand jetzt tritt der Fehler bei mir auf.

Programmieren tue ich das Gerät mit einer eigenen SW, die ich
allerdings nicht weitergeben kann, sollte aber auch mit jedem anderen
Programmer problemlos gehen.

Danke für die Unterstützung,

Christian

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

ac_main.c: In function `main':
ac_main.c:16: warning: implicit declaration of function
`InitializeGraphics'

[...]

ac_graphics.c: In function `InitializeGraphics':
ac_graphics.c:52: warning: unused variable `j'
ac_graphics.c: In function `DrawLine':
ac_graphics.c:133: warning: implicit declaration of function
`HWL_SetPixel'

Linking ac_main.elf
avr-gcc -O0 -mmcu=atmega128 -std=gnu89 -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wa,-adhlns=ac_main.o ac_main.o ac_hardware.o
ac_font.o ac_hitachi.o ac_graphics.o  --output ac_main.elf -L.
-L"C:\Programme\WinAVR\lib"
-Wl,-Tdata=0x801100,--defsym=__heap_end=0x8090ff  -lm -lgcc -lc
-litcl32 -litk32 -Wl,-Map=ac_main.map,--cref
c:\WinAVR\bin\..\lib\gcc\avr\3.4.3\..\..\..\..\avr\bin\ld.exe:
cannot find -litcl32
make: *** [ac_main.elf] Error 1

Sorry, lässt sich nicht kompilieren.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

ld: cannot find -litcl32

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Debugging symbols sind auch keine drin in dem, was du compiliert
geliefert hast, sonst könnte man damit ja wenigstens mal gucken.

von Christian Rattat (Gast)


Angehängte Dateien:

Lesenswert?

Hm, die tcl/tk lib sind der Standardinstallation vom avr-gcc enthalten
und auch in den mitgelieferten Makefiles drin. Ich verwende WinAVR
(3.4.3).

Hab die libs rausgeschmissen und nochmal ein Update angehängt, dass
diese nicht dazu linkt.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Ahja, ich hab mal die Pfade richtig gesetzt (Dein WinAVR ist nicht im
Standard-Pfad installiert!) und ein paar Prototypen bzw. includes
ergänzt, jetzt lässt es sich hier zumindest mal kompilieren (Dein
erstes .zip-File)...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hmm, was wolltest du eigentlich mit dem tcl/tk?  Da gibt's wohl
eine lib mit, aber doch keine für den AVR...

Anyway, ich denke, dein Problem liegt einfach mal hier:
1
void HWL_InitializeDisplay(void)
2
{
3
        LCDValue  = (uint8*)0x8002;
4
        LCDAddressLowByte  = (uint8*)0x8000;
5
        LCDAddressHighByte = (uint8*)0x8001;
6
        LCDRead   = (uint8*)0x8003;
7
        LCDStatus = (uint8*)0x8001;

Wenn du natürlich auf Adresse 0x800x memory-mapped IO machen
willst, solltest du wohl nicht versuchen, mehr als 32K -
(sizeof register area) an RAM zu benutzen...

von Christian Rattat (Gast)


Lesenswert?

Hm, da hast Du wohl recht! :-) Ich kann das leider so nicht verhindern,
da die Hardware fertig gebaut ist und ich auf das Zeugs keinen Einfluss
habe. Da muss ich mal mit den HW Entwicklern reden.

Kann ich vielleicht diesen Bereich irgendwie explizit sperren oder das
Problem sonst wie umgehen?

Danke für die Hilfe!

Grüße,
Christian

von Christian Rattat (Gast)


Lesenswert?

p.s. tcl/tk habe ich nicht mit eingebunden. Ich hab einfach das WinAVR
Template Makefile verwendet, da war das so drin.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

hat dein System überhaupt mehr als 32k RAM?

Matthias

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

>Ich hab einfach das WinAVR Template Makefile verwendet, da war das
>so drin.

Im Template findet mein emacs aber weder itcl noch itk...

von Christian Rattat (Gast)


Lesenswert?

@Patrick: Hast recht. Hab noch mal nachgesehen, die libs und sourcen
hatte ich aus dem Vorgängerprojekt der gleichen HW übernommen, da war
auch das tcl/tk her.

@Matthias: Ja, der hat 128KB. Die wurden bei der letzten Version auch
voll genutzt. Leider immer noch und wir warten schon seit längerem auf
den ATMega2560.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Zeig doch mal bitte Dein "Speicherlayout"...

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

der Mega128 hat 128kB Flash. Aber wieviel RAM hängt da dran? Der
Mega128 hat von sich aus nur 4kB RAM und kann maximal mit 64kB (ein
paar 100 Byte weniger) umgehen wenn der Compiler das komplett selber
verwalten soll. Alles was darüber hinausgeht mußt du selber verwalten.

Matthias

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Kann ich vielleicht diesen Bereich irgendwie explizit sperren oder
> das Problem sonst wie umgehen?

Nur semi-manuell.  Du könntest einen customized linker script zimmern
und für data nur den Bereich unterhalb 0x8000 zulassen.  Den Bereich
oberhalb 0x800f weist du dann einem separaten Segment zu, das du im
C-Programm explizit mittels __attribute__((section("xxxx"))) belegst.

von Christian Rattat (Gast)


Lesenswert?

Hi,

@Jörg: danke für die Infos. Liegen dann bei mir die 2ten 32KB ab
0x8000?

@Matthias, Patrick: Die Kiste hat 32KB internes und 32KB externes RAM
und 1MB externen Flash. Ich dachte, wir hätten auch bereits 128kb RAM.

Grüße,
Christian

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Liegen dann bei mir die 2ten 32KB ab
> 0x8000?

Genau genommen wohl ab 0x8010, nicht?

von Christian Rattat (Gast)


Lesenswert?

Wenn die überhaupt da liegen, das war mir halt nicht klar. :-)

Zu dem Linker-Script, das Du angesprochen hast: Geht es dort um die
EXTMEM Options? Und gibt es eine Doku oder einen Thread hier, wo ich
dazu mehr erfahren kann?

Grüße,
Christian

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Zu dem Linker-Script, das Du angesprochen hast: Geht es dort um die
> EXTMEM Options?

Nein, um den Linkerscript.  Der liegt im Verzeichnis
${prefix}/avr/lib/ldscripts und heißt standardmäßig (für deinen
ATmega128) avr5.x.  (Was genau ${prefix} bei dir ist, musst du selbst
rausfinden.)  Den kannst du dir als Template nehmen, um deinen eigenen
daraus zu zimmern.  Diesen wiederum übergibst du mit der Linkeroption
-T.  Wenn du selbige vom Compiler an den Linker weiterreichen willst,
geht das mit -Wl.  Nehmen wir also mal an, du hast einen Linkerscript
myproject.x erzeugt, dann wäre das

avr-gcc ... -Wl,-T,myproject.x ...

Zur Syntax möchte ich dich auf die info-Pages des Linkers verweisen.
Wenn du WinAVR benutzt, hast du meines Wissens mit tkinfo einen Reader
dafür installiert bekommen, für den's auch ein Icon auf dem Desktop
gibt.

von Christian Rattat (Gast)


Lesenswert?

Na, das ging aber flott. Danke mal wieder für die Info. (Ich werde
vielleicht irgendwann doch nochmal Profi :-))

Aber davon ab:

Schläfst Du auch irgendwann mal, oder machst sonst was außer
"nervige" Beiträge von unwissenden Leuten zu beantworten? :-)

Grüße,
Christian

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Schläfst Du auch irgendwann mal

Ja, aber nicht am Tag. :)

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.