Verwendung von "volatile"

Hero_123

Mitglied
17. Sep. 2010
183
3
18
Sprachen
  1. ANSI C
Hallo!

Ich habe da eine Frage zu "volatile".
Ich weiß, dass eine globale Variable, die ich sowohl in einer ISR als auch im Hauptprogramm verwende, "volatile" deklariert und der Zugriff im Hauptprogramm auf diese Variable atomar sein muss, wenn sie >8Bit ist (Variable > 8Bit => mit cli(), sei() etc). Diese Mechanismen sind mir bekannt und klar.

Wenn ich aber in einem anderen File eine globale Variable habe, die ich in DIESEM anderen File verwende (z.B. befüllen eines Buffers durch eine RECEIVE ISR des USART) und diesen Buffer auch in einem weiteren, anderen "Hauptfile" verwende - muss diese globale Variable dann auch "volatile" sein?
Ich vermute schon, da auf diese Variable sowohl in der ISR als auch im Hauptprogramm zugegriffen wird und die ISR während des Zugriffs im Hauptprogramm durch die ISR geändert werden kann.

Allerdings habe ich da jetzt ein Problem - ist diese globale Variable NICHT als "volatile" deklariert, erhalte ich beim Kompilieren keine Warnung.
Ist diese Variable als "volatile" deklariert, erhalte ich eine Warnung:
"warning: passing argument 1 of 'strlen' discards qualifiers from pointer target type "

Das "Problem" ist die Variable "char rec_buf[BUF]"



CodeBox C

in *.h Datei
#define BUF 80            /* Char-Buffer Wert einlesen - Empfangsbuffer*/
extern char rec_buf[BUF];            /* Char-Buffer Wert per USART einlesen */

in lib:
char rec_buf[BUF];                /* Char-Buffer Wert per USART einlesen */

/* ISR - wenn Daten reinkommen - USART RX Interrupt */
extern ISR(UART0_RECEIVE_INTERRUPT) {
    c = UART0_DATA;                            /* BUF = 80 => 0.. 79 */
    if((rec_count < BUF)||(c !='e')) {        /* z.B rec_count =78 */
        rec_buf[rec_count] = c;
        rec_count++;                        /* rec_count = 79 => ENDE!!! */
    }
    if((rec_count == (BUF-1))||(c== 'e')) {    /* rec_count == 80-1 oder c = e */
        rec_buf[rec_count] = '\0';            /* Null-Zeichen fuer String-Ende */
        rec_flag = 1;                        /* Eintrag fertig -> Empfangs-Flag = 1*/
        rec_count = 0;
    }
}

im Hauptprogramm:
while(zahl < strlen(rec_buf)) {
            if(rec_buf[zahl] !='#') {
                temp_buf[temp_count] = rec_buf[zahl];
                temp_count++;
                zahl++;
            }



wenn die Variable "rec_buf[BUF]" "volatile" ist, erhalte ich die Warnung: "warning: passing argument 1 of 'strlen' discards qualifiers from pointer target type ",
und ich versteh' nicht, warum diese Warnung erzeugt wird, wenn die Variable "volatile" ist; ist sie es nicht => keine Warnung.

Vielleicht weiß jemand
- warum diese Warnung
- was mache ich da falsch
- was muss ich machen, damit diese Warnung nicht mehr erscheint

mfg
Hero_123
 
"warning: passing argument 1 of 'strlen' discards qualifiers from pointer target type "
Der Prototype von der Funktion erwartet nun mal kein Parameter mit dem Typ 'volatile'.
Versuch es mal mit einem casting bei der Übergabe.
 
Die Funktion strlen erwartet einen Pointer zu einem Char Array, nicht einen volatile Pointer, daher die Fehlermeldung (hatte gerade Janiiix auch erwähnt).

Der Inhalt des Strings (das Arrays) ist in der Hauptfunktion nicht bekannt, der Compiler wird if (zahl < strlen(rec_buf)) nicht wegoptimieren. Im Gegensatz zu einer uint8_t Variablen zum Beispiel.

Das heißt, definiere ohne volatile.

Bevor du auf rec_buf in der Hauptfunktion zugreifst, musst du noch dafür sorgen, dass die ISR den Inhalt des Arrays nicht ändert.

Außerdem musst du vorher (reg_flag == 1) prüfen, ansonsten hast du eventuell einen String ohne Stringendezeichen, strlen() schlägt dann fehl.
 
Hallo Janiiix3, hallo Dirk

Vielen Dank für Eure Hilfe :)

Ja, hätte ich auch drauf kommen können - hätte schreiben müssen strlen((char *)rec_buf) :rolleyes:

Der Inhalt des Strings (das Arrays) ist in der Hauptfunktion nicht bekannt, der Compiler wird if (zahl < strlen(rec_buf)) nicht wegoptimieren. Im Gegensatz zu einer uint8_t Variablen zum Beispiel.

Das heißt, definiere ohne volatile.

Bevor du auf rec_buf in der Hauptfunktion zugreifst, musst du noch dafür sorgen, dass die ISR den Inhalt des Arrays nicht ändert.

Außerdem musst du vorher (reg_flag == 1) prüfen, ansonsten hast du eventuell einen String ohne Stringendezeichen, strlen() schlägt dann fehl.

Ich hatte es erst ohne "volatile", war dann aber unsicher geworden.
Ist klar, dass bei Zugriff auf rec_buf die ISR den Inhalt nicht mehr ändert (ist so implementiert)
Auch die Abfrage auf reg_flag==1 ist so implementiert.

mfg

Hero_123
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)