Hi Leute,
Ich habe schon einige Projekte mit den AVR's gemacht und benutze als
Konfiguration für meine Geräte "ModBus" (incl. kleines selbst
geschriebenes Windows-Tool). Mit Hilfe von ModBus lässt sich alles
mögliche sehr leicht einstellen.
Da die AVR's ein EEPROM im Chip selber haben, habe ich die Daten direkt
vom ModBus-Handler ins EEPROM schreiben lassen. Das läuft zu 98% gut,
aber in den letzten 2 Projekten ist mir da zuviel Zeit verloren gegangen
und ich musste etwas improvisieren (leider konnte ich an der Wurzel des
Problems nichts ändern :-( ).
Heute benutze ich ein ARM7 von Atmel und habe dort nun keine Möglichkeit
Daten direkt im Chip abzulegen (ich will keine Flashpage verwenden!!!).
Also kleines SOT23-6 EEPROM genommen und neben den Rechner gebaut nimmt
ja kein Platz weg ;-).
Hier scheint nun das gleiche Problem aufzutauchen die Zeit! Bei sehr
langen Datensätzen verschiebt sich die Antwortzeit sehr nach hinten, da
ich später auch "ModBus over TCP" verwenden möchte kann ich mir keine
lange Antwortzeiten erlauben.
meine Lösung:
jedes Register bekommt ein zusätzliches Flag, das angibt ob es sich
geändert hat. Dieses Flag wird einmal pro Main-Loop geprüft.
( Da ich zur Zeit Platz für 300 Register habe, dachte ich mir immer 10
Register auf einmal zuprüfen(einstellbar))
Der ModBus-Handler schreib nur noch ins RAM und setzt gegebenenfalls das
Flag.
Wenn dies der Fall ist und der Wert im EEPROM gesichert werden muss,
wird der Wert von der Main-Loop aus, per I2C, ins EEPROM geschrieben.
SUPER alles läuft sehr gut und die Antwort ist direkt da.
jetzt das PROBLEM:
Wenn die Spannungsversorgung zu früh vom Gerät getrennt wird, kommt es
zum Verlust der der neuen Daten, da diese noch nicht geschrieben worden
sind.
Wie kann ich diese Problem nun umgehen???
Mit der Alten Version hatte der User die Rückmeldung "Daten fertig
geschrieben" vom Konfigurationsprogramm, wenn die Rückantwort vom ModBus
kam war alles gelaufen.
Bin für jede Hilfe dankbar.
Stephan
Ein EEPROM braucht um die 4ms pro byte zum Schreiben. Dh man kann mit
einem Systemtimer von 10ms jeweils ein neues byte Schreiben. Dann sollte
man sich darauf beschraenken nur die geaenderten Daten zu Schreiben.
Falls die paar ms zu langsam sinst sollte man sich ein Flash ueberlegen,
dort schreibt man eine ganze Seite alle 4ms.
indem Du die Betriebsspannung mit überwachst
und selbige aber auch pufferst ...
Der µC kann dann bei Spannungsabfall noch
schnell die Daten schreiben bevor das Licht ausgeht.
Sehr schöne Beispiel von "Denkste".
Ich suche nicht die Ursache des Problems, sondern nehme ne CPU mit "mehr
Power".
Oops, das Problem ist ja immer noch da.
Aber keine Angst, das Problem hatte ich auch. Ich habs aber ohne mehr
Power auf dem AVR gelöst.
Für die EEPROM-Daten habe ich ein Abbild im SRAM. Alle Routinen
schreiben und lesen immer diese Kopie und damit geht das sauschnell.
Bei jedem Schreiben wird aber noch eine Indexvariable auf das Ende der
EEPROM-Daten gesetzt. Und im Hintergrund prüft ein Timerinterrupt, ob
dieser Index nicht 0 ist und ein vorheriges Schreiben beendet. In dem
Fall wird ein Byte in den EEPROM geschrieben und der Index
runtergezählt. Erreicht er irgendwann wieder 0, ist die Kopie wieder
identisch mit dem EEPROM.
Der Vorteil ist, daß keine anderen Prozesse mehr behindert werden.
Externe EEPROMs würde ich Pageweise schreiben, dann ists noch schneller.
Große Daten würde ich im internen Flash ablegen, hab ich z.B. beim
ATmega168 so gemacht. Dazu muß natürlich die Applikation eine
Interruptpause von 5ms abkönnen (Timer, UART, laufen ja weiter).
Peter
Stephan schrieb:
> Wenn die Spannungsversorgung zu früh vom Gerät getrennt wird, kommt es> zum Verlust der der neuen Daten, da diese noch nicht geschrieben worden> sind.
Definiere mal "zu früh".
Bei mir hat immer die Zeit gereicht, die der Mensch vom Abschicken des
Konfigurationskommandos bis zum Betätigen des Ausschalters braucht.
In der Regel werden auch nicht sämtliche Bytes gleichzeitig geändert
(nicht geänderte werden übersprungen). Das Schreiben sollte daher <1s
dauern.
Peter
Hi.
Danke für die Antworten.
1 hmm.)Ja es werden nur geänderte Daten geschrieben, aber laut ModBus
sind bis ca. 120 Register möglich und das dauert! ( die 4 ms * 240 Byte
= 960 ms)
Das mit dem Flash-Speicher werde ich mir mal ansehen.
Da aber zur Zeit in EEPROM in der Schaltung ist, bleib ich erstmal
dabei.
2 Fhutdhb Ufzjjuz)Gute Idee. kannst du mir da mehr Infos zukommen
lassen??
Wo fange ich an die Schaltung mit gepufferter Energie zu versorgen und
wie berechne ich mir das ganze??? (Zeit s.o., Rechner, Speicher, RS232
Treiber usw.)
PS: RTC ist extra gepuffert!
3 Peter Dannegger) der neue RECHNER hat nichts mit dem Problem zu tun,
da der AMR7 und der AVR beide den I2C-Bus mit 100kHz betreiben hab ich
da keinen vorteil.
Der ARM7 ist ausschließlich wegen der Ethernet-Schnittstelle im Projekt.
Nun zu deinem Vorschlag, ist dein I2C-Bus nur für das EEPROM zuständig
oder hast du noch andere Sachen am Bus, werden diese dann auch über
diesen Interrupt gesteuert? Das mit dem Pageweise beschreiben werde ich
mir ansehen, hätte ich auch drauf kommen müssen. (danke)
Deinen letzten Satz verstehe ich nicht ganz: "Große Daten würde ich im
internen Flash ablegen, hab....", beschreibst du da das interne Flash
zur laufzeit???
Zu Früh:
also normaler weise steht das Gerät ca. 1m vom PC weg und da reicht die
Zeit. Leider hat ein Kumpel nicht das Gerät von der Versorgungsspannung
getrennt sondern hat gleich mein Netzteil neben dem PC ausgeschaltet und
da waren die Daten weg.
Bei kleinen Datenmengen läuft auch alles stabil, aber wie das so ist
liegt der Fehler im Detail und bei ca. 120 Register kann das schon
dauern.
Desweiteren ist in diesem Projekt auch ein Software-Reset vorgesehen,
der vom User ausgelöst werden kann(per ModBus). Der Button ist in der
PC-Software zwar etwas geschützt aber es gibt immer ein paar DAUs die 3
Buttons auf einmal drücken.
Danke.
Der RTC ist gepuffert ? Dann hat der sicher noch etwas RAM drin. Das
waere viel schneller als das EEPROM.
Alternativ. Falls die Primaerversorgung ausfaellt, einen Interrupt
generieren und waehrend die Speisung noch die kondensatoren leersaugt
kann man bequem ins EEPROM schreiben
Stephan schrieb:
> Nun zu deinem Vorschlag, ist dein I2C-Bus nur für das EEPROM zuständig> oder hast du noch andere Sachen am Bus
In einem älteren 8051-Projekt hatte ich den I2C noch anderweitig benutzt
und deshalb den EEPROM separat mit SW-I2C angesteuert (Pagewrite).
Am AVR habe ich keinen externen EEPROM mehr genommen.
> Deinen letzten Satz verstehe ich nicht ganz: "Große Daten würde ich im> internen Flash ablegen, hab....", beschreibst du da das interne Flash> zur laufzeit???
Ja, über nen Bootloader-Call. Es wird immer eine ganze Page (128Byte)
geschrieben.
> also normaler weise steht das Gerät ca. 1m vom PC weg und da reicht die> Zeit.
Selbst dann liefert das Schaltnetzteil doch noch einige Sekunden
Spannung.
> Desweiteren ist in diesem Projekt auch ein Software-Reset vorgesehen
Der sollte aber doch erst alles ordentlich abschließen bzw. ein Timeout
haben.
Peter
Als Alternative könnte auch ein F-Ram (www.ramtron.com) verwendet
werden, die gibt es bis 1MB in SO-8.
Die Beschaffung könnte aber etwas kompliziert werden, spontan habe ich
nur bei RS Components ein paat gefudenn - die haben aber SPI...