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
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.
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? ;-)
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.
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.
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.
Vielleicht wäre in kleines RTOS ideal. Eine Task bedient den Benutzer und eine andere (mit niederer Priorität) speichert die Werte.
>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.
Naja, in 8.5 ms kannste allemal den Leuten das Licht zwischendurch abdrehen (oder auch zuschalten ;-).
@ 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
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.
@ 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
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.
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:
1 | void eeprom_changed( void ) // write back needed |
2 | {
|
3 | ee_upd = EE_START; |
4 | }
|
5 | |
6 | |
7 | void eeprom_update( void ) // rewrite changed data |
8 | {
|
9 | if( EECR & 1<<EEWE ) // previous write not finished |
10 | return; |
11 | EEARL = 0; // address outside used data |
12 | |
13 | if( ee_upd > EE_END ) // update done |
14 | return; |
15 | |
16 | EEARL = ee_upd; |
17 | EEARH = 0; |
18 | EECR |= 1<<EERE; // read |
19 | if( EEDR != ((u8*)eedat)[ee_upd-EE_START] ){ // if changed |
20 | EEDR = ((u8*)eedat)[ee_upd-EE_START]; // update |
21 | cli(); |
22 | EECR |= 1<<EEMWE; |
23 | EECR |= 1<<EEWE; // start write |
24 | sei(); |
25 | }
|
26 | ee_upd++; // next address |
27 | }
|
Peter
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?
@ 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
>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.
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
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.
AVR104: Buffered Interrupt Controlled EEPROM Writes http://www.atmel.com/dyn/resources/prod_documents/doc2540.pdf Werner
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
sei(); im interrupt! wieso sollte das nicht gehen, peter
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.
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
@ 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
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
Ja, der Thread ist uralt. Hier aber ein Linkzur Lösung des Problems: http://avr.15.forumer.com/a/interruptdriven-eeprom-writes-gcc_post251.html
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.