Hallo,
ich habe hier ein Problem mit einer Arrayübergabe an eine Funktion. Ich
habe im Hauptprogramm ein globales Array. Die Funktion soll via SPI aus
einem Flashspeicher byteweise Daten auslesen und in besagtem Array
ablegen.
Das (für mich) mysteriöse: Bis zu 20 Byte werden problemlos ausgelesen
und gespeichert. Ab 200 Byte stürzt der Controller ab :-) Er startet
dann einfach neu...
u8_Datablock++;// Zeiger auf nächstes Byte im Array
34
}
35
36
FM_SPI_CHIP_RELEASE();
37
38
return0;
39
}
40
41
42
// Hauptprogramm
43
intmain(void)
44
{
45
// Inits rausgekürzt...
46
47
while(1)
48
{
49
flashmem_read_block(0x000000,u8_TempData,256);
50
}
51
}
52
53
// C-Code ist für die Lesbarkeit gekürzt!
54
// Controler: AT90CAN128 @ 16 MHz
Der Flash-Speicher gibt mir als Antwort auf ein Dummy-Byte immer das
gelesene Datenbyte zurück und erhöht intern automatisch die Leseadresse
um 1 Byte. Die empfangenen Bytes möchte ich im übergebenen Array
speichern, um damit später im Hauptprogramm zu arbeiten.
Es gibt noch eine Funktion, die in den Speicher schreiben soll, die
eigentlich genau wie die die Lese-Funktion aufgebaut ist - nur dass sie
nichts ins Array schreibt. Diese macht überhaupt keine Probleme - egal
wieviele Byte sie verarbeiten soll...
Es würde mich sehr freuen, wenn Ihr mir erklären könnt, was hier
passiert.
Vielen Dank schonmal!
Gruß,
André
PS: Pointer sind nur solange schön, wie sie funktionieren... ;-)
Uwe S. schrieb:> Nur als Tipp, wo übergibst du einen Zeiger auf das Feld |u8_TempData| ?
u8_TempData ist doch ein Array. Lasse ich die Klammern weg, müsste es
doch automatisch als Zeiger auf das erste Byte verwendet werden.
Schreibe ich &u8_TempData[0] tritt das Problem genauso auf.
Thomas schrieb:> Einzige Vermutung: Ist Dein Data-Block im Linkerfile groß genug> definiert?
Hmm, gute Frage. Bin mir nicht sicher wo ich das bei AVR Studio 5
einstellen kann (war bisher noch nie notwendig). Nach dem
Compilieren/Linken bekomme ich die Meldung:
Das mit Übergeben des Zeigers auf Arry und einfach weglassen der Klammer
ist eigentlich korrekt macht aber ab und an Probleme...
Ich löse es so: &(arrary[0])
Dosmo schrieb:> Doofe Frage: Watchdog bedient?
Der Watchdog wird nicht verwendet und ist deaktiviert.
Ich vermute, dass die Funktion die ausgelesenen Daten irgendwo
speichert, wo sie nichts zu suchen haben und dadurch das Programm nach
(oder während) der Speicherung keine Befehle oder korrekte
Sprungadressen/Stackdaten mehr findet und ins Nirwana läuft. Dann wird
sie wahrscheinlich irgendwann beim Reset-Vektor ankommen und so das
Steuergerät "neu starten". Aber das ist mehr ins Blaue geraten :-(
Leider kann ich das Programm nicht zur Laufzeit debuggen...
C mässig ist an dem Codefetzen nichts auszusetzen.
Also musst du am drumherum suchen
* richtiger Prozessor eingestellt
* Hast du Dinge, die zur Laufzeit exzessiv Stack verbrauchen
(zb in main viele lokale Variablen)
so dass die 74% SRAM-Verbrauch signifikant zur Laufzeit
überschritten werden?
Karl Heinz Buchegger schrieb:> C mässig ist an dem Codefetzen nichts auszusetzen.>> Also musst du am drumherum suchen> * richtiger Prozessor eingestellt> * Hast du Dinge, die zur Laufzeit exzessiv Stack verbrauchen> (zb in main viele lokale Variablen)> so dass die 74% SRAM-Verbrauch signifikant zur Laufzeit> überschritten werden?
Der Prozessor ist im AVR Studio richtig eingestellt. An lokalen
Variablen habe ich nur ab und zu mal eine kleine Zählvariable in den
üblichen for-Schleifen. Aber selbst wenn die alle gleichzeitig genutzt
werden würden, käme ich da zusammen auf nicht mehr als 100 Byte (eher
wesentlich weniger)... Und die verbleibenden 26% sind gut 1000 Byte.
Ich habe eben etwas merkwürdiges festgestellt: Wenn ich das Arry nicht
global anlege, sondern lokal in der main (vor der while(1)-Schleife),
stürzt der Controller beim Ausführen der Funktion nicht ab. Es wird
immer seltsamer...
André Wippich schrieb:> Ich habe eben etwas merkwürdiges festgestellt: Wenn ich das Arry nicht> global anlege, sondern lokal in der main (vor der while(1)-Schleife),> stürzt der Controller beim Ausführen der Funktion nicht ab. Es wird> immer seltsamer...
Es liegt dann an einer anderen Stelle im Speicher und du überschreibst
halt irgendwas anderes im Speicher, was für das Programm nicht so vital
ist, wie die Rückkehradresse der Funktion nach main().
-> Variablen im Speicher rumschieben bringt nichts. Die Dinge sind dann
nur im Speicher anders angeordnet und unter Umständen verlagert sich
dadurch der Fehler nur an eine andere Stelle. Aber auch wenn man den
Fehler nicht mehr sieht, ist er immer noch vorhanden. Die Devise lautet:
Die Ursache bekämpfen, nicht die Symptome.
Hilft nichts: Ganzes Programm muss her.
Wenn du nett bist, speckst du das Programm ab, so dass alles was zur
Reproduzierbarkeit des Fehlers nicht notwendig ist rausfliegt,
überprüfst nochmal ob sich der Fehler auch wirklich noch zeigt und
postest das Minimalprogramm.
Karl Heinz Buchegger schrieb:> Hilft nichts: Ganzes Programm muss her.> Wenn du nett bist, speckst du das Programm ab, so dass alles was zur> Reproduzierbarkeit des Fehlers nicht notwendig ist rausfliegt,> überprüfst nochmal ob sich der Fehler auch wirklich noch zeigt und> postest das Minimalprogramm.
Das mache ich - schaffe es aber wahrscheinlich erst nächste Woche :-(
Dem Zeitdruck geschuldet habe ich das Programm jetzt so umgeschrieben,
dass die Funktion direkt auf ein globales Array zugreift und jeden
Pointer rausgeschmissen. So funktioniert es zumindest, auch wenn es
nicht so richtig elegant ist...
So oder so möchte ich aber rausfinden was im Originalprogramm vor sich
geht. Nächste Woche kann ich es vielleicht auch mal auf ein STK600
flashen und mittels JTAG debuggen.
Ich möchte Euch aber schon jetzt für die vielen Antworten und die
Hilfestellung danken!
Ein schönes WE wünsche ich!
Ich kann mit neuen Informationen aufwarten! Glücklicherweise konnte ich
mich doch schon jetzt dransetzen und den Code debuggen, da mein Kollege
einen Debugger in der Schublade hatte und sich die Zeit zum Testen ergab
:-)
Witzigerweise funktionierte das Programm beim Debuggen problemlos -
keinerlei Abstürze oder Fehlverhalten...
Ich habe dann folgendes probiert: AVR Studio 5 erzeugt ja verschiedene
HEX-Dateien je nach Anwendungsfall. Eine HEX im Debug Ordner und eine
HEX im Release Ordner, die jeweils mit einer eigenen Konfiguration
erzeugt werden. Als ich die Release-HEX nochmal draufgespielt habe hing
sich das Programm wie gewohnt auf. Mit dem Debug-HEX lief es problemlos.
So weit so gut :-)
Ich habe dann die Compilier und Linker Optionen im AVR Studio 5 für
beide Fälle angeschaut und tatsächlich gab es beim Linker eine
Abweichung.
Linker-Debug-Configuration:
Bei der Release-Config setzt AVR-Studio den Stack auf die Adresse
0x0400. Und ratet mal wo mein u8_TempData-Array laut Debugger im
Speicher liegt - im Adressbereich 0x0387 bis 0x048A. D.h. die Funktion
schreibt programmgemäß Daten ins Array, nur leider überschneidet sich
das ab der 121. Speicherstelle mit dem Stack. Dann ist es kein Wunder
wenn das Programm durchdreht.
Weiß jemand warum AVR Studio 5 diese Stack-Einstellung vornimmt und ob
sie notwendig ist? Ich habe sie definitv nicht dort eingetragen! Leider
kenne ich mich mit der Speicher-Konfiguration für den Linker nicht aus
und weiß nicht wie ich das Problem am Besten umgehen kann. Ich habe
einfach mal den "-Wl,--defsym=__stack=0x400" Teil gelöscht und schon
läuft das Programm mit der Release-Config (scheinbar) problemlos. Es
stürzt nicht mehr ab :-)
Ich befürchte nur, mir durch das Ändern der Stack-Geschichte andere
Fehler einzufangen. Wie gesagt: Ich weiß an der Stelle nicht so recht
was ich damit beim Linker anrichte...
Gruß,
André
Hmm, schade dass keiner mehr antwortet.
Ich habe leider nicht mal bei Google was zum AVR Studio 5 Linker bzw.
dessen Optionen finden können, um mir dessen Verhalten zu erklären.
Kennt evtl. jemand eine Website, die sich mit dem Thema beschäftigt?
Gruß,
André
> Bei der Release-Config setzt AVR-Studio den Stack auf die Adresse> 0x0400.
Und was geschieht, wenn Du genau die Stackdefinition dort weglässt, also
auf "--defsym=__stack=0x400" verzichtest?
Rufus Τ. Firefly schrieb:> Und was geschieht, wenn Du genau die Stackdefinition dort weglässt, also> auf "--defsym=__stack=0x400" verzichtest?
Dann funktioniert das Programm. Allerdings weiß ich nicht, ob ich mir
damit nicht einen Fehler an anderer Stelle einhandle, der dann
sporadisch auftreten könnte. Ich kenne mich mit den Optionen des Linkers
nicht aus und weiß daher nicht, ob er den Stack ohne die Definition
automatisch an einer "sicheren" Stelle anlegt.
Die Entwickler vom AVR Studio 5 werden sich doch was dabei gedacht haben
diese Stackdefinition extra einzutragen. Naja, vielleicht auch nicht...
:-)
Gruß,
André
Da im Debugfall diese Definition nicht angegeben wird, wird es wohl
einen (sinnvollen?) Defaultwert für den Stack geben. Das sollte irgendwo
dokumentiert sein.
André Wippich schrieb:> Die Entwickler vom AVR Studio 5 werden sich doch was dabei gedacht haben> diese Stackdefinition extra einzutragen.
Ich habe das noch nie in irgendeinem Studio5-Build-Output gesehen. Ich
bezweifle, dass das wirklich initial vom Studio5 stammt. Hast du das
Projekt vielleicht irgendwo her übernommen? Oder hast du vielleicht
irgendein anderes Projekt "recycelt"?
Stefan Ernst schrieb:> Ich habe das noch nie in irgendeinem Studio5-Build-Output gesehen. Ich> bezweifle, dass das wirklich initial vom Studio5 stammt. Hast du das> Projekt vielleicht irgendwo her übernommen? Oder hast du vielleicht> irgendein anderes Projekt "recycelt"?
Nein, habe kein altes Projekt recycelt. Und selbst wenn dem so wäre -
ich habe mit absoluter Sicherheit noch nie den Stack verschoben ;-)
Verrücktes AVR Studio...
Guten Morgen!
Ich habe eben mal ein neues AVR Studio 5 Projekt für den AT90CAN128
angelegt und tatsächlich ist dort diese "Stack ab 0x400"
Linker-Einstellung nicht eingetragen. Woher die dann in meinem Projekt
kommt ist ein Fall für die X Akten...
Also als Fazit können wir festhalten, dass die Stackadresse nicht
manuell eingetragen werden muss und der Linker anscheinend weiß was er
tut. Und man sollte auch die Linkereinstellungen nach Anlegen eines
Projektes prüfen.
Vielen Dank für eure Hilfe!
Gruß,
André