www.mikrocontroller.net

Forum: Compiler & IDEs Pointerschreibweisen


Autor: Micha Obi (obiwahn4)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eine Frage:

Ich muss den Port eines Atmels in einer Funktion übergeben (dient als CS 
bei SPI).
Das habe ich gemacht wie im GCC-Tutorial.
Also :

void fkt(volatile uint8_t *port, uint8_t pin)
{
  *port &= ~(1<<pin);
}

fkt(&PORTB, PB2);

So weit so gut...

Nun möchte ich der Übersicht wegen bei mehreren Slaves die Geräte mit 
structs initialisieren und nur noch diesen übergeben müssen.
Ungefähr so:

typedef struct
{
  volatile uint8_t *port;
  uint8_t pin;
} TsFlash;

void initTsFlash(TsFlash *sFlash, volatile uint8_t *port, uint8_t pin)
{
  sFlash -> port        = port;
  sFlash -> pin         = pin;
}

Main
{
  TsFlash serialFlash;
  initTsFlash(&serialFlash, &PORTB, PB2);
}

Jetzt die Frage, wie ich die Zeile programmiertechnisch in der Funktion 
fkt() richtig umsetzte.
Der Compiler akzeptiert folgende 4 Varianten:

void fkt(TsFlash *sFlash)
{
  *sFlash -> port   &= ~(1 << sFlash -> pin);
  (*sFlash -> port) &= ~(1 << sFlash -> pin);
  sFlash -> port[0] &= ~(1 << sFlash -> pin);
  (*(*sFlash).port) &= ~(1 << sFlash -> pin);
}

Sind die alle gleich und überhaupt richtig ?
Wenn ja, welche wäre die eleganteste ?

Gruß Micha

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha Obi schrieb:

> Sind die alle gleich und überhaupt richtig ?

Sind alle gleichwertig und auch alle richtig

> Wenn ja, welche wäre die eleganteste ?

Ich würds so schreiben

  *(sFlash->port) &= ~(1 << sFlash->pin);

Die Klammern sind zwar syntaktisch nicht notwendig, -> hat einen höheren 
Rang als *, klären aber beim schnellen Lesen darüber auf, wies gemeint 
ist ohne dass man sich lange den Kopf über Operatorenreihenfolge 
zerbrechen muss.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
>
>   *(sFlash->port) &= ~(1 << sFlash->pin);
>

Hier ist zu beachten, daß das zu nicht-atomarem Code führt, was zu 
Race-Conditions führen kann, wenn man einen Port (zB PORTB) sowohl in 
einer ISR verändert (zB PortB.5 setzt) und in der Anwendung (zB effektiv 
über den indirekten Zugriff PortB.0 setzt).

Das geht auf AVR unter den gegeben Umständen nicht anders. Man sollte 
sich also immer darüber klar sein, daß hier möglicherweise ein fieser, 
sporadischer Bug lauert.

Johann

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.