Hallo Zusammen!
Ich nutze den AT90CAN128 als MCU, der mit 16 MHz arbeitet, um Signale
über ein CAN Interface PCAN-USB auf den CAN-Bus sowohl zu lesen als auch
zu schreiben. Mit Hilfe einer Bedienugsoberfläche werden folgende IDs
initialisiert:
NodeID, cmdID und StatusID
Von der Simulation bis zum Betrieb läuft alles perfekt und einwandfrei.
Die Daten können gesendet und empfangen werden, parallel können Weitere
Controller ins Netzwerk eingefügt werden und auf Befehle gut reagieren.
Problem: bei jedem Stromausfall oder Reset verliert der EEPROM sein
Name, da keine Steuerung nicht mehr möglich ist.
Das neue Initialisieren des IDs ist dann notwendig, um die Anlagen über
den Controller zu steuern. Dieses Verhalten ist ähnlich für alle
Controller.Das ist ziemlich antrengend jedes Mal die IDs für jeden
Controller zu intialisieren.
Übrigens die MCU muss nicht neu programmiert werden.
Hardwaremäßig haben wir, unter AVR Studio, das BODLEVEL auf 4.0 V
gesetzt, ursprünglich war es bei 2.5 V (empfohlen ist diesen Wert so
hoch wie möglich zu stellen). Am Ausgang liegt ein Elko mit 100 uF, der
für einen langsamen Abfall der Spannung sorgt. Die Spannungsversorgung
ist stabil.
Weiter unter AVR Studio, das Aktivieren der Funktion „EESAVE“ hat keine
Änderung gebracht.
Vielleicht hat jemand ein Idee oder Erfahrung mit solch einem Problem
gemacht. Ich wäre für weitere Hilfe dankbar.
Grüß Sonne
PS: Für die Anregungen habe ich nur der Programmsteil eingefügt (siehe
unten), der die EEProm-Routine betrifft.
1
// eeprom informations
2
#define DATA_VERSION 0x0001 // data version
3
#define EEPROM_DATA_HEADER_POS 0x0010 // start at address 0x10
Sonne Madiba schrieb:> Problem: bei jedem Stromausfall oder Reset verliert der EEPROM sein> Name, da keine Steuerung nicht mehr möglich ist.
Wie habt Ihr das überprüft? Habt Ihr einen JTAG Debugger, mit dem Ihr
den Systemstart im Einzelschritt durchsteppen könnt? Wenn nein, besorgt
Euch einen!
fchk
Hallo Frank. K
Danke für die schnelle antwort
>> Problem: bei jedem Stromausfall oder Reset verliert der EEPROM sein>> Name, da keine Steuerung nicht mehr möglich ist.>> Wie habt Ihr das überprüft? Habt Ihr einen JTAG Debugger, mit dem Ihr> den Systemstart im Einzelschritt durchsteppen könnt?
Ich habe leider keinen JTAG Debugger, wie schon erwähnt solange die
Versorgung vorhanden ist, läuft die Anlage einwandfrei.
warum sollen bei jedem Reset oder Stromausfall die IDs neu
initialisieren werden?
Deswegen bitte ich um Hilfe. Ich habe nur begrenzte Kenntnisse in
Software Sachen.
Grüß Sonne
Sonne Madiba schrieb:> PS: Für die Anregungen habe ich nur der Programmsteil eingefügt (siehe> unten), der die EEProm-Routine betrifft.
Hast du auch mal nur mit diesem Teil das Problem reproduiert? Wie
belegest du, dass a) die Daten mal im EEPROM waren und b) sie nicht mehr
im EEPROM sind?
ist keine gute Idee. Was soll das bringen? WEnn das EEPROM korrekt
gelesen werden konnte, dann schreibst du maximal das zurück, was du
sowieso schon gelesen hast. Besser wäre es, den entsprechenden
Schreibaufruf in die Leseroutine zu integrieren, und dann aufzurufen,
wenn die Leseroutine bemerkt, dass sie keine gültigen Daten lesen
konnte.
Denn: Beim EEPROM hast du nur eine relativ kleine beschränkte Menge an
Schreibvorgängen. D.h. du willst nur dann ins EEPROM schreiben, wenn es
auch notwendig ist. Konnte alles einwandfrei vom EEPROM gelesen werden,
dann ist es nicht notwendig zu schreiben.
Hast du denn irgendeine Form der Ausgabe zur Verfügung? LCD, Terminal,
irgendwas? Damit man sich mal in Byteform ansehen kann, was denn vom
EEPROM gelesen wurde. Ist es nur ein einzelnes Byte, in dem vielleicht
ein einzelnes Bit gekippt wurde? Oder ist das ganze EEPROM in Unordnung?
Kaputte Befehle funktionieren nicht. Ob das Programm schon alles sauber
geschrieben hat BEVOR der Strom weg ist? WO erkennt Deine Schaltung
rechtzeitig, daß in einigen ms der Strom weg ist? Reicht der Sieb-Elko
im Netzteil dafür?
Man kann das EEPROM m.W. auch per Programmer auslesen. Wär vielleicht
mal sinnvoll, konkrete Unterschiede vorher/nacher festzustellen. Jeder
Programmiervorgang per ISP enthält übrigens einen Reset.
Du schreibst recht oft ins EEPROM. Zweimal beim Init, einmal bei jeder
CAN-Message?
=> Ungünstig, das EEPROM verträgt nur eine begrenze Anzahl von
Schreibzyklen.
Dann: Weil du so oft schreibst, und jedem Schreibvorgang ein Erase
vorausgeht: Wenn der Strom/BOD genau dazwischen zuschlägt, ist der
Datenblock (das gerade geschriebene Byte) futsch.
ggfs. mit zwei kopien deines Structs im EEPROM arbeiten, wenn eine
kaputt ist, die andere Nehmen.
Und: Wenn schon so oft geschrieben wird, evtl eeprom_update_block statt
write_block verwenden, um die Hardware zu schonen.
Wenn's das alles nicht ist:
Speicherverbrauch checken! Nicht das im nicht-gezeigten Codeteil der
Stack überläuft, und dir deine Config-Daten überbügelt.
Werte, die häufig geschrieben werden, sollte man besser als Kombination
aus Seriennummer und Inhalt in einem Array als Rundumspeicher schreiben.
Beim Init sucht man darin die höchste S/N und inkrementiert diese für
jeden neuen Eintrag, der im nächsten Array-Slot landet. Am Ende des
Arrays wieder vorne anfangen.
Wenn man diesen Einträgen dann noch eine CRC8 hinzu fügt, dann kann man
eindeutig den letzten korrekt gespeicherten Wert finden. Und die
einzelnen EEPROM-Zellen werden viel weniger beansprucht.
Εrnst B✶ schrieb:> ggfs. mit zwei kopien deines Structs im EEPROM arbeiten, wenn eine> kaputt ist, die andere Nehmen.
Wobei dann eine Prüfsumme/CRC als Teil des jeweiligen Inhalts sehr
sinnvoll ist. Und zwar am Schluss der beiden Structs.
Auf jeden Fall wäre es jetzt erst mal wichtig, ein komplettes Programm
zu haben, welches tatsächlich genau so auf dem Mega läuft und bei dem
das beschriebene Verhalten auftritt.
Sonst ist das ein Stochern im Nebel, denn es könnte ja auch genausogut
sein, dass du im nicht gezeigten Code dir selber besagte Struktur
überschreibst.
Sonne Madiba schrieb:>> Wie habt Ihr das überprüft? Habt Ihr einen JTAG Debugger, mit dem Ihr>> den Systemstart im Einzelschritt durchsteppen könnt?> Ich habe leider keinen JTAG Debugger, wie schon erwähnt solange die> Versorgung vorhanden ist, läuft die Anlage einwandfrei.
Klar, dann durchläuft das Programm nicht die Initialisierungsroutine.
> warum sollen bei jedem Reset oder Stromausfall die IDs neu> initialisieren werden?
Das siehst Du mit einem passenden Debugger. Der spart Dir eine Menge
Zeit. Ich hoffe, Dein Board hat einen Anschluss für JTAG. Ansonsten
musst Du den dazufrickeln. Lies das Datenblatt des 90CAN128 und die
Onlinehilfe in AVR Studio für den jeweiligen Debugger.
Alternativ: Hat das Board einen seriellen Port? Dann hänge einen PC mit
Terminalprogramm (putty, zoc, zur Not Hyperterm) dran, wo Du
Debugausgaben machst. Lasse Dir an wichtigen Stellen den EEPROM-Inhalt
und/oder den Inhalt wichtiger Variablen in Textform auf der seriellen
Schnittstelle ausgeben. So kannst Du herausfinden, ob Dein Programm
bestimmte Teile ausführt und den Grund herausfinden. Mit einem
JTAG-Debugger geht es einfacher, ohne dass Du noch Code schreiben musst,
aber wenn Du keinen kaufen kannst, dann ist das eine Notlösung.
fchk
Εrnst B✶ schrieb:
>Du schreibst recht oft ins EEPROM. Zweimal beim Init, einmal bei jeder>CAN-Message?
richtig
ich kann deine Anregungen leicht nachvollziehen, ich überlege mir
gerade, wie ich das Ganze anders gestalten kann.
Karl Heinz schrieb:
>Hast du denn irgendeine Form der Ausgabe zur Verfügung? LCD, Terminal,>irgendwas? Damit man sich mal in Byteform ansehen kann, was denn vom>EEPROM gelesen wurde. Ist es nur ein einzelnes Byte, in dem vielleicht>ein einzelnes Bit gekippt wurde? Oder ist das ganze EEPROM in Unordnung?
mit dem controller steuere ich Motoren, die entsprechend auf alle
Befehle gut und richtig reagieren.
Peter Dannegger schrieb:> Du müßtest ne Warnung kriegen, daß can_WriteStatus() hinter der Mainloop> toter Code ist.
es gibt zum Glück keine Warnung, das Compilieren erfolgt fehlerfrei
oszi40 schrieb:> WO erkennt Deine Schaltung> rechtzeitig, daß in einigen ms der Strom weg ist?
Gern gemachte Fehler bei externem EEPROM und batteriegepuffertem SRAM,
das Schaltungsdesign. Die Pins am EEPROM können mal zufällige Werte
annehmen, was es als Befehl interpretiert, die es dann zufällig löschen.
In einem Bastelbuch von 1988 habe ich noch eine Uhrenschaltung mit 8051
und RTC58321. Dort versah man den Enable des Uhrenbausteins wenigstens
mit einem Handumschalter, um komische Dinge bei Hoch- und Runterfahren
der Betriebsspannung zu vermeiden.
Karl Heinz schrieb:> Auf jeden Fall wäre es jetzt erst mal wichtig, ein komplettes Programm> zu haben, welches tatsächlich genau so auf dem Mega läuft und bei dem> das beschriebene Verhalten auftritt.> Sonst ist das ein Stochern im Nebel, denn es könnte ja auch genausogut> sein, dass du im nicht gezeigten Code dir selber besagte Struktur> überschreibst.
Das komplettes Programm hat insgesamt 13 Dateien, für eine bessere
Analyse kann ich dir das zuschicken.
Hallo,
ich finde die ganze Diskussion dreht sich um ein falsches Problem. IDs
sind doch im Prinzip für die Lebensdauer einer Steuerung einzugeben,
d.h. sie ändern sich selten oder nie. Sowas speichert man im EEProm
unmittelbar nach der Eingabe und rührt dann erst wieder dran, wenn sie
geändert werden müssen, also so gut wie nie.
Solche Parameter erst wegzuschreiben wenn der Strom schon ausgefallen
ist, ist eine absolute Schnapsidee und alle Probleme damit sind
überflüssig.
Gruss Reinhard
Sonne Madiba schrieb:> es gibt zum Glück keine Warnung, das Compilieren erfolgt fehlerfrei
Fehlerfrei Compilieren ist nur eine ganz klitze kleine Voraussetzung für
fehlerfrei Funktionieren.
Entweder Du hast die Warnung überlesen oder den Warning-Level zu niedrig
gesetzt oder irgendwas zufälliges gepostet, nur nicht den exakten Code.
Alles kein Grund, Glück zu vermuten.
Das einzige, was der Compiler ohne Warnung hinter der Mainloop
wegoptimiert, ist das "return 0;".
Reinhard Kern schrieb:> Hallo,>> ich finde die ganze Diskussion dreht sich um ein falsches Problem. IDs> sind doch im Prinzip für die Lebensdauer einer Steuerung einzugeben,> d.h. sie ändern sich selten oder nie. Sowas speichert man im EEProm> unmittelbar nach der Eingabe und rührt dann erst wieder dran, wenn sie> geändert werden müssen, also so gut wie nie.>> Solche Parameter erst wegzuschreiben wenn der Strom schon ausgefallen> ist, ist eine absolute Schnapsidee und alle Probleme damit sind> überflüssig.>> Gruss Reinhard
Danke sehr für diesen Beitrag. Ich denke damit ist das Problematik für
weitere Anregungen klar.
Es geht um Speicherung von IDs, die nach dem Reset wideraufrufbar sein
sollen.
schöne Grüße Sonne
Sonne Madiba schrieb:> Karl Heinz schrieb:>> Auf jeden Fall wäre es jetzt erst mal wichtig, ein komplettes Programm>> zu haben, welches tatsächlich genau so auf dem Mega läuft und bei dem>> das beschriebene Verhalten auftritt.>> Sonst ist das ein Stochern im Nebel, denn es könnte ja auch genausogut>> sein, dass du im nicht gezeigten Code dir selber besagte Struktur>> überschreibst.>> Das komplettes Programm hat insgesamt 13 Dateien, für eine bessere> Analyse kann ich dir das zuschicken.
Brauchst du gar nicht.
Ihr habt Probleme. Also finde ich es auch für euch zumutbar, euer
Programm so abzuspecken, dass es dieses Verhalten und sonst nichts
anderes zeigt.
Du hast die Hardware vor dir. Schreib ein Programm welches den EEPROM
ausliest und irgendwie signalsiert ob die WErte noch vorhanden sind oder
nicht. ABgesehen davon gibt es in diesem Testprogramm SONST NICHTS!
Und dann machst du einen Reset.
Wenn dann die Werte immer noch vorhanden sind, dann wird das Problem
wohl anderweitig zu suchen sein. Sind die Werte aber weg, dann hast du
ein kleines Programm von vielleicht 50 oder 60 Zeilen, mit dem man mal
untersuchen kann, was da vor sich geht - unabhängig von allem anderen im
Original-Programm, welches für diese Analyse erstmal nur weitere
(unbekannte) Fehlerquellen darstellt.
Karl Heinz schrieb:> Du hast die Hardware vor dir. Schreib ein Programm welches den EEPROM> ausliest und irgendwie signalsiert ob die WErte noch vorhanden sind oder> nicht. ABgesehen davon gibt es in diesem Testprogramm SONST NICHTS!
So wie es aus sieht, ist er aber der Servicetechniker, nicht der
Programmierer.
Hier:
Sonne Madiba schrieb:> Deswegen bitte ich um Hilfe. Ich habe nur begrenzte Kenntnisse in> Software Sachen.
Wilhelm F. schrieb:> Karl Heinz schrieb:>>> Du hast die Hardware vor dir. Schreib ein Programm welches den EEPROM>> ausliest und irgendwie signalsiert ob die WErte noch vorhanden sind oder>> nicht. ABgesehen davon gibt es in diesem Testprogramm SONST NICHTS!>> So wie es aus sieht, ist er aber der Servicetechniker, nicht der> Programmierer.
Dann muss er sich eben mit seinem Programmierer kurzschliessen, dass sie
gemeinsam auf Fehlersuche gehen.
Was sollen wir hier aus der Ferne diagnostizieren, wo in 1000 Zeilen
Code, von denen wir 950 nicht sehen, ein Problem stecken könnte?
Wohlgemerkt 'könnte', nicht 'muss'.
Aber bei Fehlersuche erst mal irgendetwas grundsätzlich auszuschliessen,
ist IMHO fahrlässig. Wenn das Programm zu umfangreich ist, um damit eine
halbwegs verlässliche Hardware-Diagnose machen zu können, dann muss man
eben abspecken. Das war vor 30 Jahren auch nicht anders als heute.
(das richtet sich mehr an Sonne, als an dich Wilhelm. Nicht falsch
verstehen)
Auch wenn ich mich jetzt wiederhole, solange diese Frage nicht mit ja
beantwortet wird, erübrigen sich alle weiteren Diskussionen:
Oliver schrieb:> Habt ihr auch den Brownout-Reset aktiviert?
Oliver
Oliver schrieb:> Auch wenn ich mich jetzt wiederhole, solange diese Frage nicht mit ja> beantwortet wird, erübrigen sich alle weiteren Diskussionen:>> Oliver schrieb:>> Habt ihr auch den Brownout-Reset aktiviert?>> Oliver
der Browout-Reset ist aktiviert
>So wie es aus sieht, ist er aber der Servicetechniker, nicht der>Programmierer.
Ich bin zwar ein Hardwareentwickler, zum Thema Programmierung hatte ich
C-Grundlagen Kenntnisse. Inzwischen habe ich viel über C für
Mikrocontroller gelesen und verschiedenen Tutorium gemacht. Ich habe
sogar das Programm erweitern können, ohne die Grundfunktion zu stören.
Natürlich habe ich noch viel zu lernen. Probieren und Übungen machen den
Meister.
Der Programmierer ist leider nicht mehr erreichbar, ich muss das Ganze
nachvollziehen und meistern, Das will ich auch
Karl Heinz schrieb:> Dann muss er sich eben mit seinem Programmierer kurzschliessen, dass sie> gemeinsam auf Fehlersuche gehen.> Was sollen wir hier aus der Ferne diagnostizieren, wo in 1000 Zeilen> Code, von denen wir 950 nicht sehen, ein Problem stecken könnte?
Eben, genau das.
ganz wichtig ist das Datenblatt genau zu prüfen.
Oft passiert es trotz BOD dass ein Flash/EEPROM überschrieben /
teilweise gelöscht wird und das unabhängig vom MCU. Und zwar genau dann
wenn die MCU außerhalb der Spec betrieben wird. Ein plötzlicher
Stromausfall ist eine sehr häufige Ursache welche eine MCU in
nicht-spezifizierten Bereich legt.
Speziell im Falle wenn die Spannung nicht ganz unter einen bestimmten
Wert fällt, beim AT90CAN128 muss z.b. der Wert Vpot falling
unterschritten werden BEVOR die Spannung wieder über dem BOD level
anliegt. Ist das nicht der Fall, entscheidet der Zufall was dann
passiert.
The Power-on Reset will not work unless the supply voltage has been
below VPOT (falling). Power on Reset und BOD sind immer sehr verzahnt.
Sehr typisch bei Solar betriebenen Anwendung, fällt die Spannung ab,
greift ja zunächst der BOD und kein Code wird ausgeführt. Fällt die noch
weiter runter, aber nie unter den Vpot fallling wert, sondern geht kurz
vorher wieder hoch (da ja nun plötzlich die Sonne scheint), wurde somit
die Spec gebrochen, da die Spannung ja nie unter VPot falling ging.
Ich würde in solchen Fällen also immer den Spannungsverlauf prüfen, bei
manchen MCU ist der Vpot falling recht nah an 0, bei anderen ist dieser
Wert großzügig. Je näher an 0, desto schwieriger einen vernünftigen
Reset nach Spec durchzuführen. Je nachdem wie lange der Stromausfall
dauerte, und wie die Zeit zum Teil überbrückt wurde, kann dies ein Grund
für EEPROM/FLash corruption sein.
Sonne Madiba schrieb:> Der Programmierer ist leider nicht mehr erreichbar, ich muss das Ganze> nachvollziehen und meistern, Das will ich auch
Gut.
Dann akzeptier bitte, dass man zur Fehlersuche auch schon mal ein
eigenes Testprogramm schreibt, in dem es sich nur um einen bestimmten
Problemkreis dreht.
Du hast das EEPROM in Verdacht. Wie immer gibt es 2 Möglichkeiten:
Hardware oder Software.
Aus deiner Fehlerbeschreibung geht nicht hervor, dass man irgendeines
der beiden ausschliessen könnte. Du weisst noch nicht einmal 100%
sicher, dass sich der EEPROM Inhalt tatsächlich geändert hat. Du denkst
nur, dass das so ist (und das mag durchaus auch begründet sein), weil
die 'Steuerung dann nicht mehr reagiert'. OK, das mag so sein, dass das
aufgrund verloren gegangener Id genau so ist. Aber 100% sicher weißt du
es nicht. Ergo: Das muss man erst mal nachsehen, ob diese Annahme
stimmt.
Grundsätzlich: Das wahrscheinlich wichtigste in der Fehlersuche ist es,
einen Blick hinter die 'Kulissen' zu kriegen. Alles ist dazu tauglich,
solange es dir das ermöglicht. Das fängt bei einfachen LED an, und geht
über LCD bis hin zu UART. In deinem Fall kommt noch das Auslesen des
EEPROMS mittels ISP dazu.
Egal wie, aber eine Ausgabemöglichkeit ist enorm wichtig um Fehler zu
suchen. Ohne eine solche, wird alles 300 mal so schwer, weil man ständig
um die Ecke denken muss und mit Hypothesen arbeiten muss.
Daher: Eine Ausgabemöglichkeit muss her!
Und wenn das bedeutet, dass du deinen Motor zwischendruch abklemmst,
dann ist das so. Wenn das bedeutet, dass du dir mit einem Meter Draht
eine 'Notverbindung' zu einem LCD an ein paar freien Pins zusammenlötest
und an die Platine heftest, dann ist das so. Wenn es bedeutet, dass du
denselben fliegenden Aufbau mit einem MAX232 an eine RS232 machst, dann
ist das so. Zur Fehlersuche ist alles erlaubt, solange es dem Zweck
dient und nach Beendgung der Fehlersuche wieder rückgängig gemacht
werden kann.
Weiters.
Es ist meist recht sinnlos ein komplexes Programm als ganzes auf den
Prüfstand zu schicken. Du hast den Verdacht, dass dein EEPROM Ärger
macht. Gut. Dann mach dir ein Testprogramm mit dem du genau das (und nur
das) testen kannst. Ob der PID Regler für den Motor korrekt arbeitet, ob
das CAN Interface korrekt arbeitet, das alles ist völlig irrelevant,
wenn die Fragestellung lautet: Ist mein EEPROM zuverlässig oder nicht?
Daher: raus damit. In deinem Testcode willst du möglichst wenig
zusätzliche Komponenten haben, die ihrerseits für Fehler verantwortlich
sein können. Daher willst du die gleich erst gar nicht in deinem
Testcode haben. Jaaaaa, das bedeutet, dass man Code schreibt, den man
nach ein paar Tagen, wenn das Problem behoben ist, oder wenn man davon
überzeugt ist an der falschen Stelle nach dem Problem zu suchen,
schlicht und ergreifend wegschmeisst. Gewöhn dich daran. So ist das nun
mal. Es kommt gar nicht so selten vor, dass man Code auch schon mal
wegwirft. Nur Anfänger kleben an einmal geschriebenem Code, wie das Pech
auf der Haut. Für den Profi ist Code nur ein Werkzeug und wenn es nicht
mehr gebraucht wird, dann wird es eben wieder entfernt. Wenn man
natürlich für 3 Zeilen Code 2 Stunden vor dem Editor sitzt, dann tut das
weh - das versteh ich schon. Hilft aber nichts.
Sinn der ganzen Sache ist es, Licht ins Dunkel zu bringen. Jedes Mittel
das dazu tauglich ist, ist ok. Es wird nichts von vorne herein
ausgeschlossen. Jede Annahme bleibt solange im Status 'Annahme', bis man
mit einem Test abgeklärt hat, ob der Fall ausgeschlossen werden kann
oder nicht. Du hast das EEPROM in Verdacht? ok, dann prüfe es! Ein
Verdacht oder eine Annahme reicht nicht. Wir wollen Gewissheit.
Und auch das gibt es: das einen Vorversuche, die zu nichts führen, dann
doch auf eine Idee bringen und dann stellt sich genau diese Idee als
heiße Spur heraus.
Hallo,
an alle vielen Dank für eure konstruktiven Beiträge, diesen haben meine
Neugier geweckt weiter zu forschen, sowohl Hardware-, als auch
softwaremäßig.
Karl Heinz schrieb:
>Zur Fehlersuche ist alles erlaubt, solange es dem Zweck>dient und nach Beendigung der Fehlersuche wieder rückgängig gemacht>werden kann.
Ich werde mir klein Testprogramm schreiben, um die Teilfunktionen zu
prüfen. Natürlich werde ich auch einen JTAG Debugger einsetzen.
ich werde mich in einem späteren Zeitpunkt wieder melden, wenn ich so
weit bin.
Bis dahin ist das Thema für mich noch offen.
Grüß Sonne
Hallo Sonne Madiba,
entschuldige bitte, ich habe nur schnell gelesen: Wurde das EEPROM schon
benannt?
Ich hatte einen ähnlichen Fall vor langer Zeit mit einem EEPROM 24xxx
(bzw. kompatibel) mit 128 Byte, bzw, 256 Byte.
Immer wurde die Speicherzelle 0 (Null) korrumpiert, nach einem "Crash".
Manchmal war auch noch die nächst Zelle betroffen.
Frage 1: Typ?
Frage 2: Welche Zelle?
Gruß
Bernd
Sonne Madiba schrieb:> Peter Dannegger schrieb:>> Du müßtest ne Warnung kriegen, daß can_WriteStatus() hinter der Mainloop>> toter Code ist.>> es gibt zum Glück keine Warnung, das Compilieren erfolgt fehlerfrei
Sind denn die Warnings überhaupt eingeschaltet beim Compilieren (-Wall)?
Daniel schrieb:> Speziell im Falle wenn die Spannung nicht ganz unter einen bestimmten> Wert fällt, beim AT90CAN128 muss z.b. der Wert Vpot falling> unterschritten werden BEVOR die Spannung wieder über dem BOD level> anliegt. Ist das nicht der Fall, entscheidet der Zufall was dann> passiert.
Das wäre allerdings schlecht, und steht eindeutig im Gegensatz zu dem,
was im Datenblatt steht.
Oliver
Reinhard Kern schrieb:> ich finde die ganze Diskussion dreht sich um ein falsches Problem. IDs> sind doch im Prinzip für die Lebensdauer einer Steuerung einzugeben,> d.h. sie ändern sich selten oder nie. Sowas speichert man im EEProm> unmittelbar nach der Eingabe und rührt dann erst wieder dran, wenn sie> geändert werden müssen, also so gut wie nie.
Genau so machen wir es auch und es gab nie Probleme mit dem EEPROM.
Schreibzugriffe auf den EEPROM erfolgen nur durch Bedienereingabe.
Und falls dochmal die CRC nicht stimmen sollte, wird der EEPROM mit
default Werten aus dem Flash geladen.
Bernd B. schrieb:> Hallo Sonne Madiba,>> entschuldige bitte, ich habe nur schnell gelesen: Wurde das EEPROM schon> benannt?
Laut Code ist es das interne des AT90CAN.
> Ich hatte einen ähnlichen Fall vor langer Zeit mit einem EEPROM 24xxx> (bzw. kompatibel) mit 128 Byte, bzw, 256 Byte.>> Immer wurde die Speicherzelle 0 (Null) korrumpiert, nach einem "Crash".> Manchmal war auch noch die nächst Zelle betroffen.
Ja, das Problem hatten die ganz altenAVRs, das Adr 0 geschrottet wird
wenn der Reset ungünstig kommt.
(Schlimmer ist allerdings ein fehlender BOD -- Amoklaufender CPU-Core
hat bei uns z.B auch schon Flash gelöscht)
> Frage 1: Typ?> Frage 2: Welche Zelle?>> Gruß>> Bernd
Peter Dannegger schrieb:> Reinhard Kern schrieb:>> ich finde die ganze Diskussion dreht sich um ein falsches Problem. IDs>> sind doch im Prinzip für die Lebensdauer einer Steuerung einzugeben,>> d.h. sie ändern sich selten oder nie. Sowas speichert man im EEProm>> unmittelbar nach der Eingabe und rührt dann erst wieder dran, wenn sie>> geändert werden müssen, also so gut wie nie.>> Genau so machen wir es auch und es gab nie Probleme mit dem EEPROM.> Schreibzugriffe auf den EEPROM erfolgen nur durch Bedienereingabe.>> Und falls dochmal die CRC nicht stimmen sollte, wird der EEPROM mit> default Werten aus dem Flash geladen.
.. wenn man genügend EEP frei hat kann man auch einfach 2x speichern ...
So fängt man ganz elegant interrupted writes ab und kommt wieder auf die
Füße...
Default-Werte wären dann nochmal eine Fallback-Ebene
Daniel schrieb:> The Power-on Reset will not work unless the supply voltage has been> below VPOT (falling). Power on Reset und BOD sind immer sehr verzahnt.
Nein.
VPOT ist rrlevant bei aktivierten BOD, Ausserdem V_BOD > B_POT
Zum BOD ist das Datenblatt klar:
"When the BOD is enabled, and VCC decreases to a value below the trigger
level (VBOT- in Figure 7-5), the Brown-out Reset is immediately
activated."
(VBOT+ in Figure 7-5), the delay counter starts the MCU after the
Time-out period tTOUT has expired. The BOD circuit will only detect a
drop in VCC if the voltage stays below the trigger level for longer than
tBOD given in Table 7-3.
Die Zeit t_bod ist 2µs -- Wenn man nat. schaft von BOD knapp über POT in
wesentlich kleiner als 2µs zu kommen und wieder hoch über BOD kanns
kritisch werden... Dass nennt man dann allerdings Designfehler.
Wenn die IDs sich so häufig ändern, sollte der TO eventuell überlegen,
ob der EEPROM überhaupt das richtige Speichermedium ist. Eventuell ist
ja ein batteriegepufferter SRAM da das Mittel der Wahl.
Joerg F. schrieb
> Wenn die IDs sich so häufig ändern, sollte der TO eventuell überlegen,> ob der EEPROM überhaupt das richtige Speichermedium ist.
Die IDs ändern sich nicht häufig, sie müssen nur nach dem Start jedes
Mal neu initialisiert werden, ziemlich anstrengend, wenn viele
Controller angeschlossen sind.
solange der Strom fließt bleiben sie unverändert
Wahrscheinlich wäre ein kleiner Speichertest auch eine Idee, um erst mal
festzustellen ab welcher Zelle das Übel bei Reset/Spannungsausfall
auftritt. Schreib zum Test eine bekannte Zahlenfolge hinein und prüfe
nach Reset ab wo diese immer falsch ist.
kann es sein, dass der Compiler das Schreiben auf die globale Variable
etwas anders gestaltet, als man zunächst vermutet. Es kann sein, dass
die Zuweisungen erst beim Verlassen des Blocks tatsächlich Auswirkung
auf die globale Variable haben. Also vor der Aufruf von
main_SaveEEProm().
Bei der Datenabhängigkeitsanalyse wird der Compiler feststellen, dass
weder die Parameter noch m_DataHeader nach der Zuweisung explizit
benutzt werden und fügt sie dann in optimierter Form vor dem return ein.
Versuch mal m_DataHeader mit volatile zu deklarieren. Das hat allerdings
den Nnachteil, dass Funktionen, die oft darauf zugreifen, langsamer
weden.
Alternative: änder die Funktion main_SaveEEProm() ab
Oliver schrieb:.
> Das wäre allerdings schlecht, und steht eindeutig im Gegensatz zu dem,> was im Datenblatt steht.
So auch hier. Setze Datenblatt = C-Standard.
Function calls sind Sequence Points.
Oliver
Nachtrag: Und selbst wenn es keine Sequence Points wären,,dürfte der
Compiletär höchstens zu dem Schluß kommen, daß er keine Ahnung hat, ob
die Funktion irgend etwas mir den globalen Variablen macht, und das er
büdie Zuweisung daher doch besser vorher macht.
Wäre das nicht so, würden an die 100% aller existierenden Programme
nicht funktionieren.
Oliver
oszi40 schrieb:> Wahrscheinlich wäre ein kleiner Speichertest auch eine Idee, um> erst mal> festzustellen ab welcher Zelle das Übel bei Reset/Spannungsausfall> auftritt.
Ich wette jetzt einfach mal, daß es beim ausschalten Speicherstelle 0
zersemmelt, dann nach dem Einschalten die dort stehende Versionsid nicht
erkannt, und daher der default-Datensatz geschrieben wird.
Und das alles deutet nunmal auf fehlenden Browm-out hin.
Aber der ist ja angeblich eingeschaltet...
Oliver
Solche optimierungen sind mir leider schon untergekommen.
Liegt wohl an punkt 5. Bei punkt 2 klingt das ja noch ganz gut:
ISO/IEC 9899:1999
5.1.2.3 Program execution
2 Accessing a volatile object, modifying an object, modifying a file, or
calling a function that does any of those operations are all side
effects,11) which are changes in the state of the execution environment.
Evaluation of an expression may produce side effects. At certain
specified points in the execution sequence called sequence points, all
side effects of previous evaluations shall be complete and no side
effects of subsequent evaluations shall have taken place. (A summary of
the sequence points is given in annex C.)
5 The least requirements on a conforming implementation are:
— At sequence points, volatile objects are stable in the sense that
previous accesses are complete and subsequent accesses have not yet
occurred.
[...]
Du musst schon den ganzen Abschnitt lesen. Wenn main_SaveEEProm in der
selben Compilationseinheit steht, muß der Compiler erkennen, daß da die
aktuellen Werte der globalen Variablne gebraucht werden, und die
Zuweisung vorher ausführe. Wenn main_SaveEEProm nicht in der selben
Compilationseinheit steht, muß er es sowieso machen.
Egal, was du da für Effekte gehabt hast, wenn dein Compiler Code der
Art:
1
GlobalVar=3;// nicht volatile
2
machWasMitGlobalVar();
kaputtoptimiert, dann ist das entweder ein Compilerfehler, oder der
Fehler steckt ganz woanders.
Oliver
@ Softwareverwickler (Gast)
@ Oliver (Gast)
>Ich wette jetzt einfach mal, daß es beim ausschalten Speicherstelle 0>zersemmelt, dann nach dem Einschalten die dort stehende Versionsid nicht>erkannt, und daher der default-Datensatz geschrieben wird.
ich werde mal die Speicherstelle für die Version anstatt auf Null (0)
woanders hinlegen.
Danke für den Vorschlag
Sonne Madiba schrieb:> ich werde mal die Speicherstelle für die Version anstatt auf Null (0)> woanders hinlegen.
Ist doch schon der Fall:
#define EEPROM_DATA_HEADER_POS 0x0010 // start at address 0x10
Jetzt schau doch endlich mal nach, welche Bytes im EEPROM hinterher
falsch sind und welchen falschen Wert sie haben.
Fast in den Bereich des Voodoo würde der Workaround fallen, nach jedem
Eeprom-Zugriff noch einen weiteren EEprom-Read auf Addresse 0 zu machen.
Idee dahinter: Wenn es beim Brown-Out, Spikes auf Vcc oder sonstigen
Fiesheiten das EEProm zersemmelt, dann
warscheinlich/hoffentlich/vielleicht die Stelle, auf die das
EEprom-Address-Register gerade zeigt.
Aber: Dann kann man auch gleich Klanglack auf den µC pinseln ...
Und, um nochmal ganz an den Anfang zurückzukehren:
Den µC hast du mal getauscht, oder?
Nicht dass du hier die ganze Zeit mit dem Exemplar herumdoktorst, dass
schon Jahre im Einsatz war und durch die ununterbrochenen EEProm-Writes
endlich seine Zellen-Lebensdauer überschritten hat? Geplante
Obsoleszenz?
Εrnst B✶ schrieb
> Idee dahinter: Wenn es beim Brown-Out, Spikes auf Vcc oder sonstigen> Fiesheiten das EEProm zersemmelt, dann> warscheinlich/hoffentlich/vielleicht die Stelle, auf die das> EEprom-Address-Register gerade zeigt.> Den µC hast du mal getauscht, oder?
Ja, mehrmals sogar
> Nicht dass du hier die ganze Zeit mit dem Exemplar herumdoktorst, dass> schon Jahre im Einsatz war und durch die ununterbrochenen EEProm-Writes> endlich seine Zellen-Lebensdauer überschritten hat? Geplante> Obsoleszenz?
Die Eintragungen im EEPROM sind doch nicht falsch oder?
version @ offset 0x11/12 = 0x0002
node_id @ offset 0x13 = 0x01
cmd_id @ offset 0x14/15 = 0x000A = 10
status_id @ offset 0x16/17 = 0x000B = 11
Unter der Annahme, dass die Versionsnummer nun 2 ist und das bisher
erste Byte wie angekündigt übersprungen wurde, passt es.