www.mikrocontroller.net

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


Autor: Stefan Sczekalla (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (Gast)
Datum:

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

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Stefan Sczekalla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jörg

Danke !

Grüße, Stefan

Autor: Jörg Wunsch (Gast)
Datum:

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

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan Sczekalla (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Stefan Sczekalla (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Chris (Gast)
Datum:

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

Autor: Stefan Sczekalla (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.