Hi, ist folgender Code "richtig" ? ------------------------- (...) if ( (SREG & ( 1 << 7 ) == 0 ) { (....) // wird ausgeführt wenn Interrupts disabled } (...) -------------------------- Geht es evtl besser anders/Eleganter ? Ich benutze WinAVR / gcc.
Sollte tun. Ich würde allerdings statt der ,,magischen'' 7 den Namen SREG_I benutzen, dann erklärt sich der Code besser.
Frage (nur falls es jemand weiß, ich möchte es jetzt nur nicht ausprobieren): Erkennt der gcc, dass er bei obigem Code "BRIE" benutzen kann?
Nein, eine Optimierung auf BRIE hat offenbar noch keiner geschrieben. Sollte aber eigentlich machbar sein.
Mich würde mal interessieren, wozu man sowas braucht ? Die einzige Anwendung, die ich mir vorstellen könnte, wäre das Kapseln von nicht unterbrechbarem Code. Aber dazu sichert man einfach das SREG komplett: { char savesreg = SREG; cli(); // tue irgendwas SREG = savesreg; } Peter
Hallo Peter, ich möchte das SREG_I Flag nutzen, um zu erkennen, das das Einlesen eines Bitstroms ( geschieht per Interrupt ) abgeschlossen ist. Ich mach das mit ner State-Machine und im letzten State wird am Ende das cli(); ausgeführt. Das gelöschte SREG_I Flag ist soll quasi mein "Daten sind da - bitte verarbeiten Flag" sein. Grüße, Stefan
Du weißt aber schon, daß ein cli() innerhalb eines Interrupts wirkungslos ist ? Auch wenn es ein paar Bytes mehr kostet, würde ich ein Flag immer als Variable anlegen, da es die saubere Lösung ist. Man sieht oft, daß Programme so angefangen werden, als ob man felsenfest davon überzeugt ist, nie eine Änderung oder Erweiterung machen zu müssen. Glaub mir, die Praxis sieht völlig anders aus, z.B. bleibt es bestimmt nicht bei einem einzigen Interrupt. Deshalb sollte man beim Vergewaltigen global wirkender Ressourcen sehr vorsichtig sein, ob man die Seiteneffekte verkraftet oder später überhaupt noch erinnert. Peter
Wenn es wirklich nur ein Bit sein soll (obwohl das vermutlich zwar RAM spart, aber CPU-Zyklen kostet), dann empfiehlt sich ein globales bit field: volatile struct { uint8_t int1: 1; uint8_t int2: 1; } intbits; SIGNAL(SIG_ONE) { ... intbits.int1 = 1; } ... int main(void) { ... for (;;) { if (intbits.bit1) { intbits.bit1 = 0; ... } } return 0; }
Peter Dannegger Schrieb: > Du weißt aber schon, daß ein cli() innerhalb eines Interrupts > wirkungslos ist ? Äh - nein - ?! Schhhhh.... das hab ich dann wohl im Tutorial überlesen !? @ Jörg: Danke für den Code. ... Schade das die AVRs keinen Bitaddressierbaren bereich wie die 80C31 Familie haben ... Ansonsten komme ich aber prima mit dem AVR's klar. hab nur ca 4-6 Jahre nicht mehr aktiv Programmiert - das letzte war Assembler auf der PIC Familie... Grüße, Stefan
Gibts da nicht so ein T-Flag in SREG, das für sowas missbraucht werden kann? ;)
So, nochmal nachgelesen, im Tutorial und in der Doku zur AVR-Lib hab ich nichts "Ausdrückliches" dazu gefunden. - aber - Bei Verwendung von Signal(händler) {...} steht ja dabei, das die Interrupts ( global ? ) disabled und hinterher wieder enabled werden - im gegesatz zu Interrupt(händler) {...} ... da wird dann das cbi(); gerade wieder von einem sbi(); überschrieben ... da hab ich wohl nicht genug um die Ecke gedacht ... :-) Grüße, Stefan
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.