www.mikrocontroller.net

Forum: Compiler & IDEs [AVR] per Interrupt ins EEPROM schreiben


Autor: Bernt Hullen (bernt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Hat einer schon mal bei einem AVR mit GCC eine Interrupt Routine
geschrieben, um Werte in das EEProm zu beschreiben.

Hintergrund dazu ist:
In meinem Projekt muss ich Daten mit 25kHz Byte-Takt verschicken.
(Das wird per Interrupt gemacht.)
Normales Schreiben ins EEProm dauert laut Datenblatt bis zu 8,5ms.
Daher kann ich die Funktion eeprom_write_byte aus der avrlib nicht
benutzen um konfigurierbare Parameter abzuspeichern.

Ciao,
Bernt

Autor: 2920 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und du denkst mit dem interrupt geht es schneller ?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2920 wrote:

> Und du denkst mit dem interrupt geht es schneller ?

Nein, aber du musst nicht warten, bis das Byte fertig ist, sondern
kannst in der ISR gucken, ob noch mehr zu schreiben ist.

Funktioniert nicht viel anders als eine UART-Senderoutine.

Autor: Bernt Hullen (bernt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vor allem wenn ich eine Scene mit DMX-Werten abspeichern will:
512 Werte * 8.5 ms = 4.352 Sekunden.
Soll ich dann Kerzen verteilen damit die Leute was sehen,
während ich eine Scene abspeichere?

daher muss mit dem Interrupt schon sein ... aber bei über 4 Sekunden
werd ich wohl auch ne Rückmeldung aufs LCD brauchen ...
... der nächste Aufbau wird mit externen RAM, 4k sind echt wenig ...

daher die Frage: hat das schon jemand gemacht, oder betrete ich hier
absolutes Neuland? ;-)

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich würde ja einfach Flash-Speicher nehmen. Da kann man dann auch 
schön den internen FiFo beschreiben (z.B. 32 Worte) und ihn dann den 
Rest machen lassen. Und schneller ist er auch als ein EEPROM. Wenn du 
pins sparen willst kannst ja auch ein serielles Flash nehmen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timmo H. wrote:

> Und schneller ist er auch als ein EEPROM.

Nur durch den Pagemode.

Dafür hat er eine Zehnerpotenz weniger Zyklenlebensdauer.

Wenn die 4 Sekunden insgesamt egal sind, ist die Interruptvariante
sicher so schlecht nicht.  Ich glaube auch, dass die Schreibzeiten
worst-case-Zeiten sind, sodass der Interrupt auch eher triggern
kann (die Gesamtzeit also sinkt).  Das könnte u. U. spannungsabhängig
sein (bei höherer Spannung geht es schneller), weiß nicht, wie das
genau in der Hardware implementiert ist.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Timmo H. wrote:
>
>> Und schneller ist er auch als ein EEPROM.
>
> Nur durch den Pagemode.

Nicht unbedingt: Es gibt verschiedene Typen, vergleiche z.B. mal einen 
29Cxxx und einen 29Fxxx. Der 29F wird Byte für Byte beschrieben, mit 
meist um die 10µs Schreibzeit, der 29C im Page Modus mit rund 5-10ms 
Schreibzeit.

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht wäre in kleines RTOS ideal.
Eine Task bedient den Benutzer und eine andere (mit niederer Priorität) 
speichert die Werte.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kanonen und Spatzen?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Vor allem wenn ich eine Scene mit DMX-Werten abspeichern will:
>512 Werte * 8.5 ms = 4.352 Sekunden.

Die Frage ist doch was passiert wenn du einen Schreibzyklus
gestartet hast ? Hast du eine Menge Sachen zu erledigen
bevor der beendet ist und das mit einem Interrupt
gemeldet wird ? Falls nicht bringt es nichts. Du schiebst
das Problem zeitlich nur ein klein wenig vor dir her.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, in 8.5 ms kannste allemal den Leuten das Licht zwischendurch
abdrehen (oder auch zuschalten ;-).

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Bernt Hullen (bernt)

>Vor allem wenn ich eine Scene mit DMX-Werten abspeichern will:
>512 Werte * 8.5 ms = 4.352 Sekunden.

Naja, die meisten EPROMS besitzen einen Page Mode, da kann man 16 oder 
32 Bytes gleichzeitig speichern, dauert dann auch nur 8,5ms. Damit 
verringert sich deine Spreicherzeit auf 1/16 bis 1/32, sprich  ca. 270 
bzw 135ms.

>Soll ich dann Kerzen verteilen damit die Leute was sehen,
>während ich eine Scene abspeichere?

???
Ich kenn mich mit DMX nicht aus, aber sollte das Speichern nicht 
parallel zum Normalbetrieb laufen? Das geht auch ohne Interrupt.

MFG
Falk

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:

> Ich kenn mich mit DMX nicht aus, aber sollte das Speichern nicht
> parallel zum Normalbetrieb laufen?

Genau das ist doch sein Punkt: er möchte den EEPROM-Interrupt
(statt der busy-wait-Routinen aus der avr-libc) benutzen, damit
das Speichern im Hintergrund ablaufen kann.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Jörg Wunsch (dl8dtl)

>Genau das ist doch sein Punkt: er möchte den EEPROM-Interrupt
>(statt der busy-wait-Routinen aus der avr-libc) benutzen, damit
>das Speichern im Hintergrund ablaufen kann.

Schon klar, aber selbst MIT Nutzung der normalen Funktionen der avr-libc 
kann man das praktisch "parallel" erledigen. Klar dass man nicht ohne 
Pause alle 512 Bytes schreiben darf!

MFG
Falk

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, OK, jetzt verstehe ich, was du willst...  Aber das mit dem
EEPROM-Interrupt kann auch nicht der Akt sein.  Wie ich schon schrieb,
ist das doch eigentlich nichts anderes, als eine interruptgesteuerte
UART-Senderoutine.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich in den EEPROM was schreiben muß, benutze ich ne Struktur im 
SRAM, wo die Änderungen gemacht werden.
Das Rückschreiben in den EEPROM erfolgt dann im Hintergrund per Polling 
im Main.
Hier mal ein Programmauszug:
void eeprom_changed( void )             // write back needed
{
  ee_upd = EE_START;
}


void eeprom_update( void )              // rewrite changed data
{
  if( EECR & 1<<EEWE )                  // previous write not finished
    return;
  EEARL = 0;                            // address outside used data

  if( ee_upd > EE_END )                 // update done
    return;

  EEARL = ee_upd;
  EEARH = 0;
  EECR |= 1<<EERE;                              // read
  if( EEDR != ((u8*)eedat)[ee_upd-EE_START] ){  // if changed
    EEDR = ((u8*)eedat)[ee_upd-EE_START];       // update
    cli();
    EECR |= 1<<EEMWE;
    EECR |= 1<<EEWE;                            // start write
    sei();
  }
  ee_upd++;                                     // next address
}


Peter

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verstehe nicht, warum hier nur alle alle möglichen Alternativ-
vorschläge bringen müssen.  Was bitte ist an einem interrupt-
gesteuerten Schreiben denn so schlimm, dass alle das meiden wie
der Teufel das Weihwasser?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Jörg Wunsch (dl8dtl)

>vorschläge bringen müssen.  Was bitte ist an einem interrupt-
>gesteuerten Schreiben denn so schlimm, dass alle das meiden wie
>der Teufel das Weihwasser?

Coitus interruptus?

duckundwech

SCNR
Falk

P.S. Was Wikipedia alles weiss!

http://de.wikipedia.org/wiki/Coitus_interruptus

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Was bitte ist an einem interrupt-
>gesteuerten Schreiben denn so schlimm, dass alle das meiden wie
>der Teufel das Weihwasser?

Gar nichts, solange es was bringt. Wie ja bereits 2920 in der
ersten Antwort richtig bemerkte: Das schreiben an sich wird
dadurch nicht schneller. Ob man nun einen Interrupt benutzt
oder die Polling Methode, es bleibt dabei das das reine
schreiben ins EEPROM ca. 4 Sekunden dauert. Vermutlich ist
es wesentlich weniger weil 8,5ms als maximale Schreibzeit
angegeben ist. Bei der Interrupt Methode kann man sicherlich
die Zeit bis zum Ende des Schreibzyklus besser ausnutzen. Bei
der Polling Methode geht das aber auch einigermaßen.
Man fängt halt erst an zu pollen wenn man andere Sachen
erledigt hat.

Wenn die 512 Bytes aber eins nach dem anderen schnell reinkommen
bevor ein EEPROM Schreibzyklus beendet ist, muss er diese
Daten im RAM puffern. Das bleibt ihm einfach nicht erspart.

Das EEPROM ist halt kein RAM-Ersatz.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Ich verstehe nicht, warum hier nur alle alle möglichen Alternativ-
> vorschläge bringen müssen.  Was bitte ist an einem interrupt-
> gesteuerten Schreiben denn so schlimm, dass alle das meiden wie
> der Teufel das Weihwasser?

Die Frage ist wozu?

EEPROM Schreiben ist meistens was total unwichtiges, warum soll ich mir 
dann damit die Latenz von andern Interupts versauen?

Es reicht, daß es irgendwann fertig ist und daher mache ich es mit 
Polling in der Mainloop.
Durch die nicht benötigte Registerrettung ist auch der Code kleiner.

Es ging ja nur darum, die gesamte Schreibzeit nicht unnötig zu 
verwarten, sondern die Mainloop die Zeit nutzen zu lassen.


Peter

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

> EEPROM Schreiben ist meistens was total unwichtiges, warum soll ich mir
> dann damit die Latenz von andern Interupts versauen?

Musst du nicht.  Du kannst die Interrupts sofort wieder freigeben.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR104: Buffered Interrupt Controlled EEPROM Writes

http://www.atmel.com/dyn/resources/prod_documents/...

Werner

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Musst du nicht.  Du kannst die Interrupts sofort wieder freigeben.

Kannst Du eben nicht, das Interruptflag wird bei Eintritt nicht 
gelöscht!
Ist das gleiche Dilemma, wie bei UART oder I2C.
Nur in Timerinterrupts kann man andere Interrupts freigeben.


Meistens ist es sogar unerwünscht, daß EEPROM-Daten immer sofort 
zurückgeschrieben werden. Es würden nur unnötig viel Schreibzyklen 
verbraten.

Deshalb lege ich für EEPROM-Daten eine Struktur im SRAM an, dort kann 
man dann beliebig rumändern.
Und erst, wenn man die Taste Speichern drückt, wird dann wirklich in den 
EEPROM zurück geschrieben, immer ein Byte nach dem anderen, sobald die 
Mainloop die Schreibroutine pollt.
Und durch das vorherige Lesen, werden auch nur geänderte Bytes 
geschrieben.


Peter

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sei(); im interrupt! wieso sollte das nicht gehen, peter

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

>> Musst du nicht.  Du kannst die Interrupts sofort wieder freigeben.

> Kannst Du eben nicht, das Interruptflag wird bei Eintritt nicht
> gelöscht!

Stimmt, ist ja wirklich unschön gelöst.

Autor: Ha Jo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:
> Jörg Wunsch wrote:
>> Musst du nicht.  Du kannst die Interrupts sofort wieder freigeben.
>
> Kannst Du eben nicht, das Interruptflag wird bei Eintritt nicht
> gelöscht!
> Ist das gleiche Dilemma, wie bei UART oder I2C.
> Nur in Timerinterrupts kann man andere Interrupts freigeben.

@Peter und Jörg:
Könnt Ihr mir hier bitte auf die Sprünge helfen? Warum soll das
freigeben der Interrupts nicht funktionieren?
Es gibt doch sogar:
ISR(XXX_vect, ISR_NOBLOCK)

Und warum auch bei UART und I2C?
So verstehe ich das nicht.
Danke für den Tip.

Hajo

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Ha Jo (hajo)

>> Ist das gleiche Dilemma, wie bei UART oder I2C.
>> Nur in Timerinterrupts kann man andere Interrupts freigeben.

>Könnt Ihr mir hier bitte auf die Sprünge helfen? Warum soll das
>freigeben der Interrupts nicht funktionieren?

Weil bei UART und TWI der Interrupt nicht beim Anspringen des Interrupts 
automatisch gelöscht wird, sondern erst nach Lesen der Daten vom 
UART/TWI. Dann erst kann man die Interrupts dort wieder freigeben.

MFG
Falk

Autor: Ha Jo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vor die stirn klatsch

Klaro. Ich bin einfach nicht drauf gekommen. Dachte mir nur,
wiese sollte das nicht gehen? Aber es leuchtet natürlich ein :-)

Danke für den "Schlag auf den Hinterkopf" :-)

Hajo

Autor: ras (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, der Thread ist uralt. Hier aber ein Linkzur Lösung des Problems:

http://avr.15.forumer.com/a/interruptdriven-eeprom...

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.