Forum: Compiler & IDEs Problem mit abfrage ob "I" in SREG gesetzt ist ...


von Stefan Sczekalla (Gast)


Lesenswert?

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.

von Jörg Wunsch (Gast)


Lesenswert?

Sollte tun.  Ich würde allerdings statt der ,,magischen'' 7 den Namen
SREG_I benutzen, dann erklärt sich der Code besser.

von Chris (Gast)


Lesenswert?

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?

von Stefan Sczekalla (Gast)


Lesenswert?

@ Jörg

Danke !

Grüße, Stefan

von Jörg Wunsch (Gast)


Lesenswert?

Nein, eine Optimierung auf BRIE hat offenbar noch keiner geschrieben.
Sollte aber eigentlich machbar sein.

von peter dannegger (Gast)


Lesenswert?

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

von Stefan Sczekalla (Gast)


Lesenswert?

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

von peter dannegger (Gast)


Lesenswert?

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

von Jörg Wunsch (Gast)


Lesenswert?

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;
}

von Stefan Sczekalla (Gast)


Lesenswert?

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

von Chris (Gast)


Lesenswert?

Gibts da nicht so ein T-Flag in SREG, das für sowas missbraucht werden
kann? ;)

von Stefan Sczekalla (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.