Forum: Compiler & IDEs Was heißt __IO beim GCC


von Philipp (Gast)


Lesenswert?

Im Manual finde ich nichts darüber und Google läßt mich auch dumm 
sterben :-(

Philipp

von Naja (Gast)


Lesenswert?

Für sowas gibt es Suchmaschinen.
Du schreibst was von "Google". Das ist auch eine Suchmaschine.
Klick einfach auf den ersten Link.

von Philipp (Gast)


Lesenswert?

Danke für die Antwort. Wenn ich was brauchbares im Google gefunden 
hätte, dann würde ich hier nichts posten ;-)

Philipp

von yalu (Gast)


Lesenswert?

__IO ist ein Identifier und kann bspw. als Variablen-oder Funktionsname
verwendet werden.

Oder hast du den Eindruck, __IO wäre irgendetwas Besonderes, vielleicht
Compilerspezifisches? Wenn ja, wie entstand dieser Eindruck?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

__IO ist erst einmal ein reservierter Bezeichner.  Reserviert ist
er "for the implementation", d. h. die Gesamtheit aus Compiler und
Systembibliothek(en).

Der GCC selbst benutzt __IO nicht (zumindest nicht Version 4.3.1),
insofern dürfte es eher was aus der Systembibliothek sein.  Dafür
wiederum müsstest du uns verraten, auf welchem System / in welcher
Umgebung dein GCC so läuft.

von Hc Z. (mizch)


Lesenswert?

> Oder hast du den Eindruck, __IO wäre irgendetwas Besonderes, vielleicht
> Compilerspezifisches? Wenn ja, wie entstand dieser Eindruck?

Möglicherweise entstand er dadurch, dass Variablen, die mit __ beginnen, 
beim Winzigweich-Compiler für deren private Verwendung reserviert sind.

In den AVR-Header-Files findet sich nirgends ein __IO.

von Philipp (Gast)


Lesenswert?

Also ich verwende einen Cortex-Me von ST mit GCC als Compiler. Mit IO 
verbinde ich eigentlich aus der 8-Bit Zeit, daß es um den IO Bereich 
geht, aber das kann hier nicht stimmen.

So sieht der Codeteil aus :
1
__IO uint32_t NbrOfPage = 0x00;

Wobei es für mich insofern keinen Sinn ergibt, weil die Variable nur als 
Schleifenvariable genützt wird. Ich habe nur einen Verdacht im Internet 
gefunden, daß es dabei um eine Registervariable geht.

Philipp

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das müsste sich in der Spezifikation deines konkreten Compilers
finden.  Kann schon sein, dass damit ein IO register space gemeint
ist, und dass man die Schleifenvariable halt in einen solchen legen
lässt, weil der Zugriff auf den IO space besonders schnell ist.

Das ist aber nur eine Vermutung meinerseits, ich habe keinen blassen
Schimmer, wie so ein Cortex arbeitet.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

>Im Manual finde ich nichts darüber und Google läßt mich auch dumm
>sterben :-(
Welches Manual?

Wie auch immer: __IO ist in core_cm3.h (Teil von CMSIS) so definiert:
1
#define     __IO    volatile
steckt also kein Geheimnis dahinter.

>Also ich verwende einen Cortex-Me von ST mit GCC als Compiler.
In der StdPerLib für STM32 von ST ab V3.0.0 sind die CMSIS Dateien 
enthalten. Suche nach Zeichenkette __IO in den Dateien von STM hätte 
näher gelegen als Google oder Forum.

Die Verwendung der doppelten Unterstriche ist m.M. nicht erforderlich 
aber wurde halt so von ARM festgelegt. Die Hersteller übernehmen es, um 
ihre Treibersammlungen mit "CMSIS compatible" zu schmücken. Warum man 
überhaupt ein alias für volatile eingeführt hat, wissen wohl nur die 
CMSIS-Schöpfer.

zu CMSIS siehe z.B.: http://www.arm.com/products/CPUs/CMSIS.html
zu volatile siehe z.B.: http://en.wikipedia.org/wiki/Volatile_variable

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Martin Thomas schrieb:
> Warum man überhaupt ein alias für volatile eingeführt hat, wissen wohl
> nur die CMSIS-Schöpfer.

Ich zitiere mal aus der CMSIS Dokumentation:

"IO Type Qualifiers are indented to be used for automatic generation of 
debug information of peripheral registers."

Mit anderen Worten: Entwicklungswerkzeuge sollen damit in die Lage 
versetzt werden, normale volatile Variablen von "echten" Registern zu 
unterscheiden.

Gruß
Marcus
http://www.doulos.com/arm

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marcus Harnisch schrieb:

> Mit anderen Worten: Entwicklungswerkzeuge sollen damit in die Lage
> versetzt werden, normale volatile Variablen von "echten" Registern zu
> unterscheiden.

Dafür wiederum ist aber die hier gezeigte Verwendung kompletter Unfug.

Wahrscheinlich hätte es auch nichtmal eines volatile überhaupt
bedurft, wenn das Ganze nur ein Schleifenzähler ist, oder aber
es ist eine vorsätzliche Pessimierung, um damit eine Delay-Schleife
zu bauen.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Marcus Harnisch schrieb:
> Martin Thomas schrieb:
>> Warum man überhaupt ein alias für volatile eingeführt hat, wissen wohl
>> nur die CMSIS-Schöpfer.
>
> Ich zitiere mal aus der CMSIS Dokumentation:
>
> "IO Type Qualifiers are indented to be used for automatic generation of
> debug information of peripheral registers."
>
> Mit anderen Worten: Entwicklungswerkzeuge sollen damit in die Lage
> versetzt werden, normale volatile Variablen von "echten" Registern zu
> unterscheiden.

Danke für den Hinweis.

Muss zugeben, die CMSIS Dokumentation bis dato nur überflogen zu haben. 
Bin im Quellcode der STM32 StdPerLib an einigen wenigen Stellen (z.B. in 
system_stm32f10x.c, stm32f10x_flash.c V3.1.0) über die Verwendung von 
__IO gestolpert, wo keine Register der Hardware angesprochen werden aber 
der __IO Alias anstatt volatile gemeint ist. Daher - irrtümlich - 
vermutet, dass der Alias ein overengineering Resultat ist.

Jörg Wunsch schrieb:
> Marcus Harnisch schrieb:
>
>> Mit anderen Worten: Entwicklungswerkzeuge sollen damit in die Lage
>> versetzt werden, normale volatile Variablen von "echten" Registern zu
>> unterscheiden.
>
> Dafür wiederum ist aber die hier gezeigte Verwendung kompletter Unfug.
Hmm, das "hier" kann ich grade nicht interpretieren. Übliche Verwendung 
ist bei der STM32/CMSIS-library z.B. sowas:
1
typedef struct
2
{
3
  __IO uint32_t DR;
4
  __IO uint8_t  IDR;
5
  uint8_t   RESERVED0;
6
  uint16_t  RESERVED1;
7
  __IO uint32_t CR;
8
} CRC_TypeDef;
9
#define PERIPH_BASE           ((uint32_t)0x40000000)
10
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
11
#define CRC                   ((CRC_TypeDef *) CRC_BASE)
12
#define CRC_BASE              (AHBPERIPH_BASE + 0x3000)
Sehe darin grade keinen "Unfug" für volatile und die Verwendung des __IO 
Alias passt zumindest zur zitierten Erklärung.

> Wahrscheinlich hätte es auch nichtmal eines volatile überhaupt
> bedurft, wenn das Ganze nur ein Schleifenzähler ist, oder aber
> es ist eine vorsätzliche Pessimierung, um damit eine Delay-Schleife
> zu bauen.

"Pessimierung" trifft wahrscheinlich auf sowas zu (auch STM32F 
StdPerLib):
1
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
2
...
3
do
4
{
5
  HSEStatus = RCC->CR & RCC_CR_HSERDY;
6
  StartUpCounter++;  
7
} while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));
Ohne volatile ist das mglw. zu schnell, wenn der Compiler den Counter in 
einem Core-Register zugewiesen hat und man erhält nicht die gewünschte 
Verzögerung. Für den Zähler ist hier __IO statt volatile m.M. aber eher 
irritierend (wohl auch für den mir unbekannten "debug 
information"-Generator). Ähnlich hier:
1
...
2
*(__IO uint16_t*)Address = Data;
3
...
Ist eine Zeile aus einer Flash-Routine. Address ist eine Adresse im 
Speicher, kein HW-Register.

von Stefan E. (sternst)


Lesenswert?

Martin Thomas schrieb:

>> Dafür wiederum ist aber die hier gezeigte Verwendung kompletter Unfug.
> Hmm, das "hier" kann ich grade nicht interpretieren.

Das "hier" bezieht sich sicherlich hierauf:

> So sieht der Codeteil aus :
>
> __IO uint32_t NbrOfPage = 0x00;
>
> Wobei es für mich insofern keinen Sinn ergibt, weil die Variable nur als
> Schleifenvariable genützt wird.

von Philipp (Gast)


Lesenswert?

Vielen Dank, komplett auf CMSIS umsteigen war als nächstes dran bei mir. 
Eigentlich halte ich nicht viel davon, etwas zu verkomplizieren, aber 
wenn es dann einheitlicher ist ...

Rückwirkend betrachtet, habe ich volatile immer für Ports verwendet ... 
IO  :-)

ciao,
Philipp

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Martin Thomas schrieb:
> Muss zugeben, die CMSIS Dokumentation bis dato nur überflogen zu haben.

Wahrscheinlich hast Du bereits die ganze Doku gelesen. Die ist nur eben 
sehr dünn geraten :-)

Gruß
Marcus

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Martin Thomas schrieb:

> "Pessimierung" trifft wahrscheinlich auf sowas zu (auch STM32F
> StdPerLib):

> Ohne volatile ist das mglw. zu schnell, wenn der Compiler den Counter in
> einem Core-Register zugewiesen hat und man erhält nicht die gewünschte
> Verzögerung.

Schlimmer noch: der Compiler erkennt, dass die Variable nichts tut,
und eliminiert sie komplett.

Verzögerungsschleifen baut man am besten als inline asm (siehe
<util/delay.h> in der avr-libc), sofern man nicht den Compiler
davon überzeugen kann, irgendwas wie _delay_cycles() bereit zu
stellen.

Beim Hochzählen einer Variablen (auch bei volatile) kann man immer
nur raten, wie lange das wirklich dauern wird, die Zeit ist dann
mit und ohne Optimierung unterschiedlich usw. usf.

> Für den Zähler ist hier __IO statt volatile m.M. aber eher
> irritierend

Genau das meinte ich mit "hier".  Wenn schon, sollte man an dieser
Stelle wirklich volatile schreiben, damit wenigstens jeder gleich
den Hack erkennen kann.

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.