SREG nicht definiert?

Gast #4465967
Lesenswert?

Hallo,

ich bin weiter dran mit Assembler und C.
Ich arbeite mit Atmel Studio 7 und dem Atmega32.
Ich habe ein Problem wo mir die Google-Suche auch nicht helfen konnte, 
bitte um Hilfe.

Ich möchte aus C eine Assembler-Funktion aufrufen.
Vor dem Aufruf möchte ich das Statusregister 'retten' und die Interrupts 
abschalten, hier mein Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
extern void firstfunc_asm(uint8_t* pArray);
5

6
uint8_t myArray[2];
7

8
int main(void)
9
{
10

11
  uint8_t sreg_prev;
12
  sreg_prev = SREG; // Statusregister retten
13
  cli();
14
  
15
  myArray[0] = 107;
16
  myArray[1] =  64;
17

18
  firstfunc_asm((uint8_t*)myArray);
19

20
  SREG = sreg_prev; // Statusregister wieder herstellen
21
        sei();
22

23
}

Wie im Anhang gezeigt ist SREG bei mir mit einer roten Schlange 
versehen.
SREG scheint nicht definiert zu sein - ich dachte das geht über die 
io.h!?!

Was mache ich falsch?
Angehängte Dateien:
#4466009
Lesenswert?

Vermutlich garnichts. Ob es rot unterstrichen ist ist Egal, nur 
Fehlermeldungen und Warnungen beim Kompiliren sollte man immer sind 
relevant. Stelle einfach sicher, dass der korrekte uc ausgewehlt ist, 
also beim Compileraufruf falls es gcc ist -mmcu=uc-name vorhanden ist. 
Vermutlich weiss deine IDE einfach nicht, das der Compiler dann ein 
Makro setzt, durch welches in avr/io.h SREG dediniert wird, und 
unterstreicht es darum. Tipp: Stelle Fehlermeldungen auf Maximum und 
setze den standard. Unter gcc nutze ich immer -Wall -Wextra -pedantic 
-Werror -std=c11

PS: Der cast (uint8_t*) ist überflüssig.
Gast #4466018
Lesenswert?

warum willst du überhaupt SREG sichern? Dafür gibt es doch überhaupt 
kein Grund. Nach jeder Anweisung steht wieder was anderes drin.

Der Cast ist auch nicht notwendig
1
firstfunc_asm((uint8_t*)myArray);

es sollte ohne genauso gehen:
1
firstfunc_asm(myArray);
Gast #4466182
Lesenswert?

Peter II schrieb:

> warum willst du überhaupt SREG sichern? Dafür gibt es doch überhaupt
> kein Grund.

Vermutlich will er den Code einer ISR in main() testen. Das ist u.U. 
keine ganz schlechte Idee, habe ich auch schon das eine oder andere Mal 
getan, einfach nur, um das Debugging zu erleichtern.

> Nach jeder Anweisung steht wieder was anderes drin.

Nein, längst nicht nach jeder Anweisung steht da was anderes drin. Sehr 
viele Anweisungen tangieren SREG überhaupt nicht.

> [c]

Ah, fuck. C... Naja. Da muss man natürlich mehr oder weniger raten, ob 
SREG betroffen sein könnte oder nicht. Maximal ist ein "educated guess" 
möglich oder die Lektüre des Assemblercodes, den der C-Compiler 
raushaut. Der aber schon bei der Verwendung einer anderen 
Optimierungsoption wieder völlig anders aussehen kann und erst recht bei 
Verwendung eines anderen Compilers. Im Allgemeinen wird man also in C 
SREG sichern müssen, wenn man den Einflussbereich des linearen 
Compilerlaufs verlässt...

In Asm hingegen absolut kein Problem: man schaut einfach in die 
"instruction set reference". Da steht das einfach für jede legale 
Anweisung eindeutig drin. Und zwar nicht nur OB SREG beeinflusst wird, 
sondern auch noch ganz genau WIE...

Das ist einer der Hauptvorteile von Asm. Volle Kontrolle der machine 
flags (lesend und schreibend). Ein erklecklicher Teil der in Asm 
erzielbaren Performancevorteile resultiert aus genau diesem Sachverhalt.
Gast #4466508
Lesenswert?

Wenn dein Compiler SREG nicht kennt, hast du ihm wichtige
Informationen vorenthalten: Erst mal schon die µC-spezifische
Header (.h)-Datei.

Ansonsten muss man SREG nur zum Beginn von Interruptroutinen,
die den Inhalt von SREG ändern können, sichern - und vor dem
Rücksprung wieder herstellen.
Da wird ein Programmablauf unterbrochen - und wenn der
Programmablauf wieder aufgenommen wird, muss das SREG (und
alles was sonst vom Programmablauf als verlässlich betrachtet
wird) wieder wie vor der Unterbrechung aussehen.

Und wer C benutzt, muss dem Compiler natürlich verraten,
wenn eine Funktion eine Interrupt-Service-Routine ist.
DANN kümmert sich der C-Compiler schon um SREG & Co.

Hachja - das gefährliche HALBWISSEN....
Gast #4466556
Lesenswert?

SREG ist definiert in avr/common.h
********************************************
avr/common.h wird immer included in avr/io.h
********************************************

Pfad:
****
x:\Atmel7\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\common.h

Definition:
**********
/* Status Register */
#ifndef SREG
#  if _AVR_ARCH_ >= 100
#    define SREG _SFR_MEM8(0x3F)
#  else
#    define SREG _SFR_IO8(0x3F)
#  endif
#endif
Gast #4466557
Lesenswert?

Ein NEUES Projekt mit
**************************************************
#include <avr/io.h>

int main(void)
{
  uint8_t sreg = SREG;

    /* Replace with your application code */
    while (1)
    {
    }
}

compiliert trotz markiertem SREG ohne Fehler.
*********************************************

"Goto implementation" findet keine Definition von SREG.
 *******************

Nach manuellem öffnen von avr/common.h verschwindet die Markierung unter 
SREG und "Go" findet die Definition.
Moderator Persönliche Seite #4537850
Lesenswert?

Falk B. schrieb:
> Wenn es das nicht tut, ist deine Toolchain defekt.

Das tut es schon, aber lies' dir doch mal das Eingangsposting durch:
es störte ihn, dass SREG nicht ordentlich von der IDE dargestellt
wird.  Einen Compilefehler bekam er ja nie.

Offenbar ist der in die IDE integrierte Parser bissel limitiert und
watschelt nicht die komplette Include-Hierarchie durch oder was auch
immer.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren