Hallo,
ich bin momentan dabei, einen Programm für ein uC zu schreiben, dass
Daten von einer IR-Fernbedienung empfängt und diese auswertet (ein
PIN-Code muss eingeben werden, wenn dieser richtig ist, soll eine LED
angehen). Das funktionierte soweit, bis ich das Program so erweitert
habe, dass man die PIN ändern kann. Seit dem wird die LED je nach Status
nicht mehr umgeschaltet. Wenn ich einen Teil des Codes aus der
if-Abfrage zuvor wegmache, funktioniert wieder alles. Welchen Teil ich
weg mache (den neuen, um die PIN zu ändern, oder den alten, der die
PIN-Eingabe erkennt), ist egal. Warum funktioniert das nicht, wenn der
ganze Code da ist?
Und falls das jemand wissen will, welche IR-Lib das ist:
http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html
-> daraus die nötigen Funktionen um IR-Daten des NEC-Protokolls zu lesen
(und für uC umgeschrieben, da diese Lib eigentlich für den Arduino ist).
Und in code.h sind nur Definitionen für die einzelnen Tasten der
verwendeten Fernbedienung.
EDIT: Also so wie der Code angehängt ist, schafft es der ATtiny84A bis
zu dem Punkt, wo die LED gesteuert wird. Wenn ich aber den
auskommentierten Teil wieder aktiviere, gehts net mehr.
EDIT2:
1
while (1) {
2
if (test = irrecv_decode(&res)) {
3
if (res.decode_type != NEC || res.value == REPEAT) {
Ah, und wenn ich alles "aktiviere" (nicht auskommentiere), dann hängt es
von folgendem Teil ab, ob der uC bis zu dem Teil, wo die LED gesteuert
wird, ankommt.
1
if (res.value == KEY_POWER)
2
state &= ~STATE_CODE_OK;
3
else if (res.value == KEY_B && (state & STATE_CODE_OK))
4
state |= STATE_ENTER_NEW_CODE;
Aber hier wird nicht irgendwie neuer Speicher gebraucht, weshalb der uC
"kein Bock" mehr hat ..
Wo ist der Fehler? Oder mein Denkfehle?
Vielleicht solltest du Bit0 in state auch mal setzen, anstatt es immer
nur zu löschen.
Dann würde diese Bedingung:
> if (res.value == KEY_B && (state & STATE_CODE_OK))> state |= STATE_ENTER_NEW_CODE;
auch einmal true werden und ermöglichen, daß Bit1 in state gesetzt wird,
damit die if-Bedingung
> if (state & STATE_ENTER_NEW_CODE)
ebenfalls mal true ist.
mfg.
Georg G. schrieb:> Lass es doch einfach mal im Simulator laufen, Schritt für Schritt. Dann> siehst du, wo es nicht nach deinen Wünschen weiter geht (und warum).
Eigentlich gute Idee, aber ich kann das ankommende IR-Signal nicht
simulieren .. wenn ich den Code so ändere, dass die Funktion
"irrecv_decode" immer einen bestimmten Wert zurückgibt funktioniert es
wieder (Code dahinter wird ausgeführt) -> Simulaion sinnlos .. :|
Thomas Eckmann schrieb:> Vielleicht solltest du Bit0 in state auch mal setzen
Wird gemacht, wenn der PIN-Code richtig eingeben wurde (momentan
auskommentiert). Aber eigentlich ist das egal, es geht darum, dass wenn
anscheinend "zu viel" Code in der if-Abfrage drin ist, das hintendran
nicht mehr ausgeführt wird. Mometan ist dieser Code "hintendran" so:
1
PORTB |= (1<<1);
2
delay_ms(test*500);
3
PORTB &= ~(1<<1);
4
delay_ms(50);
5
6
/*
7
if (state & STATE_CODE_OK)
8
PORTB |= (1<<1);
9
else
10
PORTB &= ~(1<<1);
11
//*/
.. also egal welchen Wert state hat, die LED sollte blinken (sofern ein
IR-Signal dekodiert werden konnte und da weiß ich, dass es
funktioniert). Oder steh ich grad so richtig aufm Schlauch !??
Also dieser "Test", den ich vorher gemacht hatte, war nicht soo
sinnvoll. Aber was ist jetzt das Problem? Ich hab mal diese ganzen alten
"Test" aus dem Code rausgemacht und ein paar Kommentare hinzugefügt.
Mein Problem jetzt ist in dem Code als Kommentar (der längste von allen)
beschrieben. Was ist da falsch?
@aks
Das hab ich mal ausprobiert -> es ändert nichts.
Aber ich habe noch was getestet ... so langsam versteh ich GAR NICHTS
mehr!
Also:
In meinem "neuen Code" ist einfach das
1
if (res.value == KEY_POWER)
2
state &= ~STATE_CODE_OK;
3
else if (res.value == KEY_B && (state & STATE_CODE_OK)) // pin entered and key for new pin code pressed ?
4
state |= STATE_ENTER_NEW_CODE;
durch folgendes ersetzt:
1
if (res.value == KEY_POWER)
2
state &= ~STATE_CODE_OK;
3
else if (res.value == KEY_B && (state & STATE_CODE_OK)) {
4
state |= STATE_ENTER_NEW_CODE;
5
//for(;;); // wenn ich diese zeile auskommentiere, geht es nicht; sonst schon !!?????
6
}
...... in dem Kommentar steht eigentlich alles drin ...
Wenn ich diese Endlosschleife (habe einfach irgendwas genommen)
miteinbaue funktioniert das Programm einwandfrei. Also PIN-Code wird
erkannt, LED geht an, ich kann die LED mit dem Power-Button wieder
ausschalten .. nur wenn ich den Knopf B drücke hängt der AVR .. logisch
(wegen der Endlosschleife) ....
Aber wenn ich die Endlosschleife wegmache, geht wieder NIX !?? (LED geht
nicht an)
WARUM !?? Ich versteh grad NICHTS mehr !??
EDIT: Ich hab mir gedacht, wenn es mit einer Endlosschleife hintendran
geht, teste ichs mal mit einem NOP-Befehl .. also:
1
if (res.value == KEY_POWER)
2
state &= ~STATE_CODE_OK;
3
else if (res.value == KEY_B && (state & STATE_CODE_OK)) {
4
state |= STATE_ENTER_NEW_CODE;
5
asm volatile ("nop");
6
//for(;;); // wenn ich diese zeile auskommentiere, geht es nicht; sonst schon !!?????
kopfkratz
Ganz ehrlich statt nun solange im Code herumzufummeln bis entweder was
halbwegs geht oder gar nicht mehr, setz Dich hin und zeichne Dir eine
Statemachine auf.
Dann selbige mit switch/case umsetzen und passende Funktionen für das
Lernen und Auswertung schreiben.
Du hast ja aktuell folgende Zustände:
LERNEN -> empfangene PINs in EEPROM ablegen
AUSWERTEN -> empfangene PINs mit EEPROM vergleichen
Welche Übergänge hast Du zwischen diesen Zuständen und welche Funktionen
müßtest Du implementieren ?
Jetzt machst Du erstmal eine Auszeit und schaust morgen Abend nochmal
drüber wenn Du keine Statemachine aufsetzen willst.
Ich will einfach nur wissen warum ein uC etwas bestimmtes nur dann
macht, wenn hinter einer Anweisung in einer if-Abfrage, die aufgrund
ihrer Bedingung nicht mal "ausgeführt" wird, eine Endlosschleife ist.
WARUM?? Steht ich irgendwie total aufm Schlauch oder wie?
EDIT: Bei dem Code selbes Problem ..
Jonathan K. schrieb:> Ich will einfach nur wissen warum ein uC etwas bestimmtes nur dann> macht, wenn hinter einer Anweisung in einer if-Abfrage, die aufgrund> ihrer Bedingung nicht mal "ausgeführt" wird, eine Endlosschleife ist.>> WARUM?? Steht ich irgendwie total aufm Schlauch oder wie?
Bist Du Dir sicher das die Endlosschleife nicht ausgeführt wird ?
Bei vielen verschachtelten ifs kommt es schon mal vor das eine
Klammerung sinnvoller wäre, von switch mal ganz abgesehen.
Aktuell bist Du nicht mehr in der Lage objektiv das Problem zu lösen,
z.B. via Debugger.
Daher mein Rat einfach aufzuhören, Dir einen schönen Abend zu machen und
wenn Du morgen dann nicht mehr irritiert und genervt bist das ganze
nochmal Punkt für Punkt durchzugehen.
Und mein Vorschlag mit der Statemachine kommt auch nicht von ungefähr
;-)
Ums mal direkt zu sagen: "GAAAAAANZ RUHIG Brauner !" ;-)
Mach was komplett anderes und wenn Du dann wieder unten bist gehe es
systematisch an ...
kopfkratzer schrieb:> Bist Du Dir sicher das die Endlosschleife nicht ausgeführt wird ?> Bei vielen verschachtelten ifs kommt es schon mal vor das eine> Klammerung sinnvoller wäre, von switch mal ganz abgesehen.> Aktuell bist Du nicht mehr in der Lage objektiv das Problem zu lösen,> z.B. via Debugger.
Also nochmal: Die Bedinung "res.value == KEY_B && code_ok" ergibt
false!! Weder der gesendete "IR-Code" ist die Taste B und der Code muss
dafür ja auch richtig eingeben sein. Also der Teil wird garantiert nicht
ausgeführt. Das habe ich auch schona anders getestet. Ich habe den uC so
programmiert, dass wenn "enter_new_code" true ist, eine LED angeht und
der uC in einer Endlosschleife landet. Dies ist aber nicht passiert;
daher bin ich mir zu 100% sicher, dass dieser Teil nicht ausgeführt
wird. Deshalb wunderts mich, dass dieser Teil das ganze Programm
beinflusst. Und ich wollte das ganze ja simulieren, aber dafür müsste
ich die Funktion "irrecv_decode" so verändern, dass sie den PIN-Code
richtig zurückgibt .. dann hört der Code aber nicht so auf so arbeiten,
wie er es machen würde, wenn diese eine "for(;;);"-Schleife fehlt ..
EDIT: Und wenn dieser Code ausgeführt werden würde, dann würde der uC ja
bereits bei der PIN-Code-Eingabe hängen bleiben (wegen der
Endlosscheleife) ..
Nochmal die Frage von vorher: Warum macht ein uC etwas bestimmtes nur
dann, wenn hinter einer Anweisung in einer if-Abfrage, die aufgrund
ihrer Bedingung nicht mal "ausgeführt" wird, eine Endlosschleife ist???
EDIT2: Was sagt ihr dazu (siehe neue Kommentare im Code)?
Jonathan K. schrieb:> kopfkratzer schrieb:>> Bist Du Dir sicher das die Endlosschleife nicht ausgeführt wird ?>> Bei vielen verschachtelten ifs kommt es schon mal vor das eine>> Klammerung sinnvoller wäre, von switch mal ganz abgesehen.>> Aktuell bist Du nicht mehr in der Lage objektiv das Problem zu lösen,>> z.B. via Debugger.>> Also nochmal: Die Bedinung "res.value == KEY_B && code_ok" ergibt> false!! Weder der gesendete "IR-Code" ist die Taste B und der Code muss> dafür ja auch richtig eingeben sein. Also der Teil wird garantiert nicht> ausgeführt. Das habe ich auch schona anders getestet. Ich habe den uC so> programmiert, dass wenn "enter_new_code" true ist, eine LED angeht und> der uC in einer Endlosschleife landet. Dies ist aber nicht passiert;> daher bin ich mir zu 100% sicher, dass dieser Teil nicht ausgeführt> wird. Deshalb wunderts mich, dass dieser Teil das ganze Programm> beinflusst. Und ich wollte das ganze ja simulieren, aber dafür müsste> ich die Funktion "irrecv_decode" so verändern, dass sie den PIN-Code> richtig zurückgibt .. dann hört der Code aber nicht so auf so arbeiten,> wie er es machen würde, wenn diese eine "for(;;);"-Schleife fehlt ..>> EDIT: Und wenn dieser Code ausgeführt werden würde, dann würde der uC ja> bereits bei der PIN-Code-Eingabe hängen bleiben (wegen der> Endlosscheleife) ..>> Nochmal die Frage von vorher: Warum macht ein uC etwas bestimmtes nur> dann, wenn hinter einer Anweisung in einer if-Abfrage, die aufgrund> ihrer Bedingung nicht mal "ausgeführt" wird, eine Endlosschleife ist???
OK,
dann poste doch mal bitte Deinen aktuellen Code als Anhang.
Ich schau dann morgen Abend drüber, denn ich bin gerade auch nicht in
der Lage objektiv Zeile für Zeile durchzugehen ;-)
Karl-Heinz ist wahrscheinlich im verdienten Urlaub ;-)
Achja und wie "simulierst" Du das Ganze denn eigentlich ?
Debug via LED ist OK, kannst Du das einfach erweitern, so das Du siehst
in welchem Programmteil es hängen bleibt ?
Ansonsten kennst Du jemanden mit Hardwaredebugger bzw. kannst Du nicht
einfach im "Simulator" die Variable beim Debuggen ändern ?
Oder Du nimmst meinen Vorschlag an und fängst komplett neu an mit einer
Statemachine ...
Und poste bitte ALLE Source Dateien!
Welche Toolchain benutzt Du?
Tritt das Problem umabhägig von der verwendeten "Optimierungsoption"
auf?
Erfahrungsgemäß sind "solche Effekte" die Auswirkung von ganz anderen
Stellen im Program :-). Auch wenn man denkt, das Problem "isoliert" zu
haben und glaubt einen Compiler Bug gefunden zu haben, stellt es sich
dann doch zu oft als Programmierfehler raus.
kopfkratzer schrieb:> Achja und wie "simulierst" Du das Ganze denn eigentlich ?
Ich hatte vor das in SimulAVR zu simulieren ..
Achim K. schrieb:> Tritt das Problem umabhägig von der verwendeten "Optimierungsoption"> auf?
Danke für den Tip!! Hab zuerst net dran geglaubt, aber es hat mein
Problem gelöst!!! Habe zuerst -Os und -O1 ausprobiert - selbes Ergebnis,
wie vorher .. aber mit -O2 funktioniert es; auch wenn das ganze jetzt
ein bisschen größer ist, es funktioniert!
Aber warum verhält sich ein Programm bei unterschiedlichen Optimierungen
komplett anders? :O
Jonathan K. schrieb:> Aber warum verhält sich ein Programm bei unterschiedlichen Optimierungen> komplett anders? :O
Wie "komplett anders" es ist, wird sich ja noch zeigen. Aber im Ernst:
Poste alle Source Dateien. Dann kann man sehen, wo es "kritisch ist".
Jonathan K. schrieb:> Aber warum verhält sich ein Programm bei unterschiedlichen Optimierungen> komplett anders? :O
Häufigstes Problem: du hast ein "volatile" vergessen und der Compiler
optimiert anders...
> Warum funktioniert das nicht, wenn der ganze Code da ist?
Weil du einen Programmfehler hast.
Vergiss bitte die Idee, dass dich der Compiler ärgern will und den
Bedingungsteil in einem if nur bis zu einer bestimmten Code-größe in
diesem if macht. Er tut es nicht.
Du hast einen Fehler im Programm - Punkt. So wie 99% aller anderer
Programmierer, die den Compiler verantwortlich machen wollen. Natürlich
kommt es vor, dass auch in einem Compiler Fehler enthalten sind. Ein
Compiler ist schliesslich auch nur ein Programm. Aber die
Wahrscheinlichkeit ist eher gering. Einen Compilerfehler fasst man erst
ins Auge, wenn man genau weiß, welche gewisse Funktionalität nicht
gegeben ist, was da eigentlich schief geht und wenn man keine Erklärung
für dieses Verhalten im Code finden kann. Wobei es meistens speziell an
letzterem scheitert - denn oft genug stellt sich heraus, dass der
Compiler recht hat und nur das C Wissen des Programmierers nicht gut
genug ist. So entstehen dann auch die 99% in denen der Compiler recht
hat obwohl der Programmierer die Sache ganz anders sieht.
Jonathan K. schrieb:> Danke für den Tip!! Hab zuerst net dran geglaubt, aber es hat mein> Problem gelöst!!!
Nein, Du hast Dein Problem nicht gelöst, Du hast es nur woanders hin
verschoben. Durch die Änderung der Optimierung hat der Compiler Deinen
Programmfehler (z.B. Überschreiben von Speicher, u.U. von Variablen) nur
woanders hingelegt.
Wenn es nun augenscheinlich nicht mehr auftritt, ist die Chance groß,
dass es nun woanders krachen wird. Und wenn Du gaaaaaanz viel Glück
hast, ist der Fehler nun tatsächlich im gesamten Programmablauf
irrelevant, weil Du zum Beispiel nun lediglich Speicher überschreibst,
wo gerade keine Variablen gehalten werden.
So löst man aber keine Programmfehler-Probleme, denn man kommt damit
nicht weit. Sobald Du irgendwann mal was änderst im Programm, ist ...
schwuppdiewupp ... der Fehler wieder da und Du kannst von vorn anfangen.
Fazit: Augen-zu-und-durch beim Programmieren ist tödlich! Sei froh, dass
Du den Fehler überhaupt reproduzieren kannst. Dann jage ihn denn auch!
Lothar Miller schrieb:> Häufigstes Problem: du hast ein "volatile" vergessen und der Compiler> optimiert anders...
Hmm, also die einzigste Variable, die in dem Interrupt-Handler
"gebraucht" wird, ist "irparams". Da hab ich aber kein volatile
vergessen .. und bei den anderen Variablen hab ich auch mal getestet
überall ein volatile dazuzuschreiben, was nichts gebracht hat.
Achim K. schrieb:> Poste alle Source Dateien.
Ist im Anhang.
Karl Heinz schrieb:> Weil du einen Programmfehler hast.Frank M. schrieb:> Nein, Du hast Dein Problem nicht gelöst, Du hast es nur woanders hin> verschoben.
Hmm, da habt ihr Recht .. das hatte ich mir auch schon irgendwie
gedacht, wusste aber nicht wo der Fehler ist. Code ist im Anhang, wäre
nett, wenn ihr mal gucken könnt ... momentan ist in dem Makefile die
Option -O2 drin, um den Fehler zu reproduzieren, einfach "-O2"
wegmachen; ich habe einen ATtiny84A (Fuses: L:0xE2; H:0xDF; E:0xFF)
verwendet und als IR-Receiver TSOP31238.
>if (irrecv_decode(&res)) { // decode> // hier "landet" man, wenn ein IR-Code empfangen wurde ....
Aber nur wenn du nicht hier unten dich in der Endlossschleife fängst,
wie willst du hier jemals rauskommen?
>for(;;); // wenn ich diese zeile auskommentiere, geht es nicht; sonst schon >!!?????
Wenn du hier unten schon auf die Änderung eines flags wartest (was im
interrupt gesetzt wird) musst du hier auch eine Prüfung darauf machen,
einfach so empfängst du genau einmal einen code und hängst dann für
immer in der for schleife du nase.
Gruß Jonas
Wahrscheinlich fehlt Dir hier
for (uint8_t i=0; i<code_len; i++)
eeprom_w32(1+sizeof(uint32_t)*i, code[i]);
noch ein eeprom_busy_wait nach der Schleife
Jonathan K. schrieb:> und bei den anderen Variablen hab ich auch mal getestet> überall ein volatile dazuzuschreiben, was nichts gebracht hat.
Meine Güte, wie oft denn noch?!? Programmieren tut man nicht durch
blindes Rumexperimentieren, sondern man muss schon mitdenken und
verstehen was man tut!
>Meine Güte, wie oft denn noch?!? Programmieren tut man nicht durch>blindes Rumexperimentieren, sondern man muss schon mitdenken und>verstehen was man tut!
Das muss es noch üben, sonst hätte er sich auch nicht so ne Falle gebaut
mit der for-schleife, ob das dann der letzte Fehler ist...
GRuß Jonas
Jonas Biensack schrieb:>>Code ist im Anhang?>> Wo?
Sorry hab ich vergessen.
Jonas Biensack schrieb:>>if (irrecv_decode(&res)) { // decode>> // hier "landet" man, wenn ein IR-Code empfangen wurde ....>> Aber nur wenn du nicht hier unten dich in der Endlossschleife fängst,> wie willst du hier jemals rauskommen?
Wie oft noch? In diese Endlosschleife kommt man erst gar nicht (weil man
dazu 1. den PIN-Code richtig eingeben müsste und 2. dann noch eine
bestimmte Taste drücken muss)!
Jonas Biensack schrieb:>>if (irrecv_decode(&res)) { // decode>> // hier "landet" man, wenn ein IR-Code empfangen wurde ....>> Aber nur wenn du nicht hier unten dich in der Endlossschleife fängst,> wie willst du hier jemals rauskommen?Hans schrieb:> Wahrscheinlich fehlt Dir hier>> for (uint8_t i=0; i<code_len; i++)> eeprom_w32(1+sizeof(uint32_t)*i, code[i]);> noch ein eeprom_busy_wait nach der Schleife
In der Funktion eeprom_w32 ist doch ein eeprom_busy_wait!?
Da Dieter schrieb:> Meine Güte, wie oft denn noch?!? Programmieren tut man nicht durch> blindes Rumexperimentieren, sondern man muss schon mitdenken und> verstehen was man tut!
Mir ist schon klar wozu z.B. volatile ist! Ich hatte mir auch schon
gedacht, dass dieser "Test" nichts bringt. Ich hatte aber nur keine
Ahnung wo der Fehler war, sodass ich so ziemlich alles (egal ob sinnvol
oder nicht) ausprobiert hab. Sont weiß ich, wann ich z.B. volatile
benutzen muss!
kopftisch
Code als tar.gz m(
OK da ich hier definitiv Lernresistenz sehe werde ich mir das nicht mehr
antun.
Was das sinnvollste wäre habe ich schon oben gepostet, da es aber
niemals nicht an dem "Ding" zwischen Stuhl und Tastatur liegen kann
holen wir uns mal die neue Version
"Jetzmachwasicheigentlichwillabernichtselberkann" ...
Besser wäre es natürlich wenn sich der OP mal hinsetzt und wirklich eine
einfachste Statemachine daraus macht, die entweder den Status "LERNEN"
oder den Status "ERKENNEN" hat.
Den IR Empfang braucht's für beides kann man also als eigene
Funktion/Prozedur implementieren ...
Jonathan K. schrieb:> In der Funktion eeprom_w32 ist doch ein eeprom_busy_wait!?
Wenn Du Deinen Kopf einschaltest, dann siehst Du das beim letzten
Zugriff kein Wait kommt, weil es in Deinen Funktionen am Anfang steht.
Offenbar bist Du Beratungs- und Lernresistent.
Hans schrieb:> Jonathan K. schrieb:>> In der Funktion eeprom_w32 ist doch ein eeprom_busy_wait!?>> Wenn Du Deinen Kopf einschaltest, dann siehst Du das beim letzten> Zugriff kein Wait kommt, weil es in Deinen Funktionen am Anfang steht.> Offenbar bist Du Beratungs- und Lernresistent.
Achsoo, hab da was falsch verstanden; du hast Recht!
Ganz ehrlich.,
Ich hab jetzt 20 Minuten damit verbracht, deine Codestruktur zu
analysieren.
Ohne es genau festmachen zu können: der Code ist irgendwie
unübersichtlich. Wenn ich den Code warten müsste, dann würde ich den mal
insofern überarbeiten, als ich ihn in Funktionen aufteile.
Das einzige, was mir ein bischen unkoscher aufgefallen ist, das ist die
Diskrepanz hier
1
uint32_tcode[CODE_MAX_LEN];
2
...
3
uint32_tnew_code[CODE_MAX_LEN+1];
new_code ist um 1 Element länger, was eigentlich nicht notwendig sein
sollte, wenn der Überlauf auf CODE_MAX_LEN korrekt abgefangen wird.
Lösch doch mal dein EEPROM, bzw. schreib da einen bekannten Code rein.
Im Sourcecode ist mir jetzt nichts großartiges aufgefallen, ausser das
ich ihn extrem unübersichtlich finde. Ich denke er funktioniert.
Was ich allerdings auch denke: du hast dich irgendwann mal mit einem
Code im EEPROM ausgesperrt, so dass du es jetzt nicht mehr schaffst, die
ein Code_ok zu holen, so dass du den Code wieder ändern kannst. Und da
du kein code_ok bekommst, siehst du deine LED auch nie leuchten.
Das ist meine momentane Arbeitshyopthese, wenn ich davon ausgehe, dass
es kein SRAM Overflow ist.
Hans schrieb:> Jonathan K. schrieb:>> In der Funktion eeprom_w32 ist doch ein eeprom_busy_wait!?>> Wenn Du Deinen Kopf einschaltest, dann siehst Du das beim letzten> Zugriff kein Wait kommt, weil es in Deinen Funktionen am Anfang steht.
Und?
Wenn kümmerts?
Das Busy Wait hat genau die Aufgabe, eine momentan gerade laufende
EEPROM Aktion abzuwarten. Abfrage davor ist also ok.
Im Grunde braucht er sich um solche Sachen auch überhaupt nicht kümmern.
Das machen die EEPROM-Funktionen aus eeprom.h schon ganz alleine.
Jonathan K. schrieb:> Hans schrieb:>> Jonathan K. schrieb:>>> In der Funktion eeprom_w32 ist doch ein eeprom_busy_wait!?>>>> Wenn Du Deinen Kopf einschaltest, dann siehst Du das beim letzten>> Zugriff kein Wait kommt, weil es in Deinen Funktionen am Anfang steht.>> Offenbar bist Du Beratungs- und Lernresistent.>> Achsoo, hab da was falsch verstanden; du hast Recht!
Hab nochmal nachgelesen, eigentlich müsste es so wie ich es gemacht hab
richtig sein .. wobei ich es wie Karl Heinz geschrieben hat auch hätte
weglassen können.
Karl Heinz schrieb:> new_code ist um 1 Element länger, was eigentlich nicht notwendig sein> sollte, wenn der Überlauf auf CODE_MAX_LEN korrekt abgefangen wird.
Das ist deshalb, weil man als letztes ein "Prüfziffer" eingeben muss
(Länge der neuen PIN). Das ist einfach sicherheitshalber, falls eine
Ziffer nicht erkannt wird, dass man nicht ausgesperrt wird.
Karl Heinz schrieb:> Lösch doch mal dein EEPROM, bzw. schreib da einen bekannten Code rein.
Habe ich bereits gemacht .. hab ihn auch keine Ahnung wie oft
zwischendurch immer wieder ausgelesen, um zu gucken, was drin steht. Es
war immer korrekt (in der Datei ir.tar.gz ist glaub ich auch noch eine
Datei Namens "eeprom").
Aber wenn es ein SRAM Overflow ein sollte, warum funktioniert es dann,
wenn in der Bedingung (die immer noch nicht zutrifft) eine
Endlosschleife ist? o.O
Der ATTiny hat 512 Bytes SRAM.
Wenn ich compiliere kommt:
"Data: 426 bytes (83.2% Full)
(.data + .bss + .noinit)"
Wenn man dann noch die zwei Arrays in main.c dazu nimmt, kommen 64 Bytes
hinzu => 490 Bytes. Und die anderen Stack Variablen habe ich noch nicht
drin !!!
!!! OUT OF RAM !!!
Der größte Brocken ist wohl
1
#define RAWBUF 100 // Length of raw duration buffer
Achim K. schrieb:> Versuch mal RAWBUF 50 oder so.
Hab ein bisschen rumprobiert für das von mir verwendete NEC-Protokoll
muss RAWBUF mindestens 68 sein. Und damit funktionierts (unabhänhig von
der Optimierung).
.. dass der AVR anfängt zu "spinnen" ist mir jetzt klar und ich weiß
auch warum (.. ähnliche Probleme hatte ich schon öfters). Aber warum
"spinnt" er nicht, wenn diese eine Endlosschleife im Code ist (deshalb
bin ich auch davon ausgegangen, dass es nicht daran liegt, dass der RAM
voll ist)?
Jonathan K. schrieb:>> Hab ein bisschen rumprobiert für das von mir verwendete NEC-Protokoll> muss RAWBUF mindestens 68 sein. Und damit funktionierts (unabhänhig von> der Optimierung).>
Na dann erstmal Gratulation!
> .. dass der AVR anfängt zu "spinnen" ist mir jetzt klar und ich weiß> auch warum (.. ähnliche Probleme hatte ich schon öfters). Aber warum> "spinnt" er nicht, wenn diese eine Endlosschleife im Code ist (deshalb> bin ich auch davon ausgegangen, dass es nicht daran liegt, dass der RAM> voll ist)?
Das Grundproblem von undeterministischem Verhalten ist, dass es
undeterministisch ist :-).
Jonathan K. schrieb:> Aber warum> "spinnt" er nicht, wenn diese eine Endlosschleife im Code ist
Vermutung: Weil der GCC erkennt, dass die Schleife nicht verlassen
werden kann. Aller Code danach ist "unreachable", und wird wegoptimiert.
Zusammen mit dem Code alle Variablen daraus => Speicher reicht wieder.
Jonathan K. schrieb:> Hab ein bisschen rumprobiert für das von mir verwendete NEC-Protokoll> muss RAWBUF mindestens 68 sein. Und damit funktionierts (unabhänhig von> der Optimierung).
Das hört sich ziemlich knapp an. Hast Du Dir mal IRMP angeschaut?
Das kommt mit wesentlich weniger RAM aus.
Pessimizer schrieb:> Vermutung: Weil der GCC erkennt, dass die Schleife nicht verlassen> werden kann. Aller Code danach ist "unreachable", und wird wegoptimiert.> Zusammen mit dem Code alle Variablen daraus => Speicher reicht wieder.
Klingt logisch ..
Frank M. schrieb:> Das hört sich ziemlich knapp an. Hast Du Dir mal IRMP angeschaut?> Das kommt mit wesentlich weniger RAM aus.
Sieht interessant aus guck ich mir mal an.