ungewollter Funktionsaufruf in ATMega64

Gast #3952578
Hallo zusammen.

Ich habe ein Problem mit einem ATMega64.
Der ATMega64 dient der Steuerung von
- Erzeugung von Audio Signalen
- Verstärken von empfangenen Audiosignalen
- Steuerung von AD Wandler zur Digitalisierung der verstärkten Signale
- Ausgabe der Ergebnisse über UART (nur auf Anforderung von außen)
Das ganze läuft mit 2 Batterien (AA je 1,5V). Daher ist ein Auto Power 
Off eingebaut wodurch Strom gespart werden soll, wenn länger nichts 
gemessen wurde.

Dazu verwende ich einen Bootloader, der es mir ermöglicht ein Firmware 
Update durchzuführen ohne eine der Standardprogrammierschnittstellen 
verwenden zu müssen. Somit kann ich den Flash schreiben und löschen, 
wann immer ich den Bootloader benutze will.
Der Bootloader kann nur durch eine bestimmte Reihenfolge an 
Funktionsaufrufen aktiviert werden.

Jetzt habe ich aber das Problem, dass es hin und wieder vorkommt, dass 
die Funtkion zum Löschen des Flashes auch ohne das Starten des 
Bootloaders ausgelöst wird.
Dies äußert sich so, dass das Programm nicht mehr funktioniert, keine 
Kommunikation möglich ist, und dass Auslesen bzw. Schreiben des Flashes 
nur noch über ISP möglich ist.

Beim Auslesen des Flashes und anschließendem Vergleich mit der Original 
Hexdatei hat sich gezeigt, dass in solch einem Fall immer genau eine 
Page (also 256 Bytes) gelöscht wurde. Natürlich läuft das Programm dann 
nicht mehr.

Neu flashen bringt den Controller auch wieder zum Laufen.

Ich kann diesen Fehler bisher auch nicht reproduzueren.
Ich habe mit der Spannungsversorgung einiges ausprobiert (leere 
Batterien simoliert), alles ohne Erfolg.

Hat jemand schon mal ein ähnliches Verhalten beobachten können?
Wie kann ich dem Problem Herr werden?
Könnt es hier ein Problem mit der Spannungsversorgung geben?

Was könnte noch die Ursache sein?
EMV vielleicht?

Ich danke Euch für jeden Tipp den Ihr mir geben könnt.
Gast
du denkst schon in die richtige richtung...
wenn exakt eine page (128 bzw. 256 bytes, je nach atmega typ) korrupt 
wird deutet das auf unbeabsichtigte ausführung der programmierroutine 
mit irgendwelchem grütz im ram-puffer aus dem programmiert werden soll 
hin.
reproduzieren ist schwierig, warum musst du mal selbst überlegen ;)

Was zu tun ist:

1. ab welcher spannung läuft dein verwendeter uC stabil ?
...externen spannungsmonitor/reset controller benutzen

...interne brown-out detection auf einen sinnvollen spannungspegel 
einstellen und aktivieren (per fuses)

... die ausführung der programmierroutinen von einem kontrollierten 
programmfluss abhängig machen. z.B. eine globale variable als erstes 
statement in der main() auf einen definierten wert setzen, variable beim 
UART-Empfang auf den nächsten wert setzen, wenn der ganze block 
empfangen wurde auf einen nächsten wert setzen und so weiter. so kannst 
du sicher stellen das dein programm nicht irgendwo angesprungen wurde 
und wenigstens die main() einmalig von beginn an ausgeführt wurde. im 
programmfluss solltest du natürlich auf den gültigen eingangswert testen 
und wenn da was anderes drinsteht einen SW-Reset ausführen.
Wenn Du ALLE globalen und static variablen in deinem programm per code 
vorinitialisierst anstelle dich auf das automatische 0 setzen des 
c-startup codes zu verlassen sowie die HW-reset default werte der 
uC-register, sollte das klappen.

viel erfolg.
Man sollte natuerlich die Flags, die bestimmen, ob eine Page geloescht 
resp geschrieben werden soll, nach Verlassen des Bootloader loeschen, 
resp, sie so bemessen, dass sie default off sind. Ich denke hier an die 
Zustandsmaschine im Bootloader. Dass ein zufaelliger Sprung in den Code 
nicht anrichten kann.

Ja. und Debuggen ist Teil des Entwicklungsprozesses. Dh man sollte die 
Debugvorkehrungen schon beim Design der Hardware geplant haben.
Jetzt Nicht schrieb:
> Bei Strings sollte man eh die Laenge ergaenzen. Es macht wenig Sinn bei
> jeder Benutzung die Laenge neu zu zaehlen.

?

Ich weiss nicht wie du programmierst. Aber ich brauch bei 
Stringverarbeitung in den allerwenigsten Fällen die Länge des Strings 
als Zahlenwert.
Was man braucht, ist die Größe des Arrays in dem der String gespeichert 
ist bzw. in dem einer gespeichert werden kann. Aber die kann man nicht 
in diesem Sinne 'zählen'. Die weiß man per Definition.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.