www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik komisches verhalten AVR avr-gcc


Autor: gastgast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielleicht kann mir wer von euch helfen bzw. einen Tipp geben?

Ich hab hier ein größeres Projekt welches sehr stabil läuft (Feldtests 
schon mehere Wochen/Monate ohne Probleme). Letzte Woche hab ich dem Code 
noch etwas verpasst (ein paar Funktionen fürs Flash, Datenspeichern 
etc.)

Die Funktionen hab ich alle in einer rel. einfach gestrickten main - 
applikation getestet - funktioniert prima soweit getestet.

nun hab ich alles samt in des große projekt mit eingebaut und dort 
krachts nun ordentlich:
- hab komische sachen fest gestellt z.B.: (code dient nur zur erklärung)
void main(void)
{
 ...
 i = 2;
 func_A();
 i++;
 func_B();
 ...
 do{
   ...
   func_C();
   ...
}while(1);
}


void func_C(void)
{
 uint8 dummy;
 if(g_oTest)
{
 dummy = HEADER;
 func_save(dummy);
...
}
...
}

Nun wird nach func_A() nicht i++; ausgeführt sonderen dummy=HEADER -> 
man sieht im lss file das der code hier wirklich drin ist, die ganze 
func_C existiert aber an einem anderen Codebereich ...

Gut ich hab dann das ganze etwas umgekapselt in andere Funktionen und 
dann war das Problem beseitigt und wurde auf meine TODO liste geschoben.

- nun hab ich aber das Problem das sich meine Applikation immer an der 
selben stelle aufhängt bzw. in .init3 geht, zuerst dachte ich an 
watchdog oder stack pointer ... konnte ich schon aus"debuggen". schalte 
ich die optimierung von s auf 2 oder 1 herunter dann geht die 
applikation ein stück weiter ressetiert sich aber später dann doch...

ich versteh das ganze nicht, es sieht so aus als ob entweder eine 
pointer operation einen gewaltigen misst macht und mir alles zusammen 
haut -> da hab ich im code schon gesucht, oder ich etwas falsch mache 
mit der bedienung von avr-gcc -> meine vermutung wegen dem ersten 
komischen verhalten bzg. codeteil an falscher position eingefügt.

vielleicht kann mir wer eien tipp geben wo ich hier ansetzten kann, bin 
etwas ratlos, danke!

grüße

Autor: Albrecht H. (alieninside)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keine Ahnung, ..., selbstverständlich nicht, ich am allerwenigsten.

Du lieferst auch ein bisschen arg dürftige Informationen, 
zusammenfassend klingt das ungefähr so: "Ich hab in mein Programm (was 
das genau macht sag ich nicht), ein paar neue Funktionen eingebaut, 
(welche im Detail sag ich auch nicht), und seitdem funktioniert das 
Programm nicht mehr richtig!".

Controller? Takt? Versorgung? Aufbau/Schaltplan? Peripherie? 
Entwicklungsumgebung?

Ok, muss man ja vielleicht nicht gleich alles mitteilen. Ist nicht böse 
gemeint, ich kann schon verstehen, dass man von einem, möglicherweise 
kommerziellen, Projekt, nicht sofort alle Details posten möchte, aber je 
weniger Informationen du weitergeben willst, um so mehr musst du dein 
Problem auf nachvollziehbare, kleinere Einheiten herunterbrechen, also 
im besten Fall kompilierbaren Code anhängen in dem das Problem auch 
auftritt. Wobei du während du das machst, den Fehler wahrscheinlich 
sogar selbst finden würdest.

Ansonsten kann man halt auch nur mit Allgemeinplätzen antworten:

SRAM zu klein geworden?

EEPROM/FASH schreiben? Klingt immer verdächtig ...

Autor: gastgast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für den hinweis,
ich möchte das ganze vereinfacht darstellen deshalb das ganze sehr 
allgemein gehaltn, ich dachte vielleicht hat schon wer solch ein problem 
gehabt. HW etc. würde ich mal ausschließen, hat alles nicht mit dem 
einschieben von codeteilen zu tun welche erste in einer funktion 
ausgeführt werden -> optimierung des compilieres ist auszuschließen da 
die funktion erst aufgerufen wurde wenn per user (uart) ein befehl 
gekommen ist - befehl wird nicht gesendet (wurde auch schon in der 
empfangsroutine ein breakpoint gesetzt ) wird nie erreicht. letzendlich 
ist es einfach sehr komisch dass der gcc bzw. linker einfach codeteile 
wild hin und her schiebt und dadurch probleme auftreten können ...


danke

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nun wird nach func_A() nicht i++; ausgeführt sonderen dummy=HEADER ->
>man sieht im lss file das der code hier wirklich drin ist, die ganze
>func_C existiert aber an einem anderen Codebereich ...

Was meinst du mit "wirklich drin"?

Bei der Optimierungsstufe -Os zeigt der Debugger selten sinnvolle Dinge 
an, da geht dem die Zuordnung zwischen C- und Assemblercode verloren.

"Übliche" Gründe für solche Probleme sind neben üblichen 
Programmierfehlern ein überlaufender Stack.

Oliver

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man sieht in einem extrem verkürzten Quelltext nicht wie

z.B. i definiert ist. Und man sieht nicht was damit gemacht wird. 
Angenommen es ist nicht volatile und wird nach i++ nicht mehr 
verwendet... kann der Compiler das rausoptimieren. warum was rechnen, 
was nicht benötigt wird?

z.B. func_B() definiert ist. Wenn func_B() keine Seiteneffekte hat und 
der Rückgabewert zur Kompilierzeit bekannt ist, kann der Compiler den 
Funktionsaufruf komplett wegoptimieren. Der Compiler kann func_B() je 
nach eingestellter Optimierungsstrategie u.U. auch selbstständig 
inlinen, so dass es im Debugger so aussieht, als ob func_B() nicht 
aufgerufen wird.

Autor: gastgast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für die hinweise

nein der compilier optimiert nichts weg! er macht zu viel
i ist irrelevant weil so im code gar nicht drin (da werden andere 
globale variablen gesetzt) es geht einfach darum das codefragmente von 
func_c in der main auftauchen wo sie nicht hin gehören (ich bin ja nur 
drauf gegkommen - debugged ) weil genau diese fragemente in meinen 
externen spi flash schreiben und wenn dieses fragment ausgeführt wird 
ohne das ich es will ein müll im flash steht, daher hab ich debugged und 
bin auf das komische gestoßen ...


aber ich versteh natürlich wenn ich nicht den ganzen code posten will 
das hier die hilfe schwer ist, trotzdem danke!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht ist ein Rucksprungwert zerschossen.

Nach welcher Funktion X aus main() landest du denn irregulär in Code der 
void func_C(void)?

Wenn du das reproduzieren kannst, hast du zwei Optionen: Macht diese 
Funktion X aufgrund von Anweisungen Mist (Zeigeramok, Bufferoverflow, 
...) oder aufgrund von zu hohem Speicherbedarf.

Autor: gastgast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo nochmal,

also mein 2. problem hab ich gelöst, das war ein ganz böses problem 
welches sich erst jetzt durch das zusammen fügen von code teilen 
bemerkbar gemach hat (pointer und arrays sag ich nur ... )

das ist gelöst, gds.

das "komische" verhalten des compilers leider nicht, ich habs jetzt an 
einer anderen stelle und die ist relativ kompakt dazu der code(im 
entwickler/hackerstadium) der funktioniert:
uint32 backup_adr=0;
static uint32 rd_log(log_data_t *pa_oData, uint32 pa_nAdr, uint8 pa_nType)
{
  uint32 adr = pa_nAdr;

  uint8 header_min, header_max;
  if(pa_nType == 0x10) //Alarm
  {
    header_min = 0x10;
    header_max = 0x1F;
  }
  if(pa_nType == 0x20)
  {
    header_min = 0x20;
    header_max = 0x2F;
  }
  do{
    adr = sto_read(pa_oData, adr);
    if(adr)
    {
      backup_adr = adr;
    }
  }while((pa_oData->header != 0xFF) && !(pa_oData->header > header_min && pa_oData->header < header_max) && adr && pa_oData->header && pa_oData->length);
  return backup_adr;
}

der Code funktioniert nicht:
static uint32 rd_log(log_data_t *pa_oData, uint32 pa_nAdr, uint8 pa_nType)
{
  uint32 adr = pa_nAdr;
        uint32 backup_adr=0;

  uint8 header_min, header_max;
  if(pa_nType == 0x10) //Alarm
  {
    header_min = 0x10;
    header_max = 0x1F;
  }
  if(pa_nType == 0x20)
  {
    header_min = 0x20;
    header_max = 0x2F;
  }
  do{
    adr = sto_read(pa_oData, adr);
    if(adr)
    {
      backup_adr = adr;
    }
  }while((pa_oData->header != 0xFF) && !(pa_oData->header > header_min && pa_oData->header < header_max) && adr && pa_oData->header && pa_oData->length);
  return backup_adr;
}

sto_read ließt was vom speicher, gibt 0 zurück wenn ein fehler auftritt.

im ersten code erkenne ich den fehler, im zweiten code wird der fehler 
nicht erkannt weil der kompilier einfach backup_adr weg optimiert?

die frage ist was mache ich falsch? am compiler wirds glaub ich nicht 
liegen ... ;(

bin dankbar für jeden hinweis und tipp, und sorry das ich gestern keinen 
code posten wollte aber das wäre ziemlich wirr gewesen.
thx

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.