Forum: Compiler & IDEs Funktionsaufruf


von Udo S. (Firma: allround) (1udo1)


Lesenswert?

Hallo,

habe in meinen bisherigen Programmen zahlreiche Funktionen geschrieben, 
die auch funktionieren.

Aber diese simple Funktion void wait() klappt nicht. PC0 wird nicht 
angesprochen. Wo ist der kapitale Fehler?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <inttypes.h>
4
#define  F_CPU  12000000
5
6
7
volatile int16_t  waiter;
8
9
10
void wait()
11
{
12
  waiter++;
13
  
14
  if(waiter==30000) // 30 000 mal 0,17ms = 5,1 Sekunden
15
    {
16
    PORTC ^= ( 1 << PC0 );
17
    waiter=0;
18
    }
19
}
20
21
22
//###################### TIMER 0 #######################################
23
24
ISR(TIMER0_OVF_vect)    // TOV alle 170µs bei 12 MHZ und Teiler 8
25
{
26
  void wait();
27
  PORTC ^= ( 1 << PC7 );
28
} // Ende ISR
29
30
31
// ##################### TIMER0 initialisieren ############################
32
33
void init(void)
34
{
35
  TIMSK =  (1<<TOIE0) ;
36
  TCCR0 = (1<<CS01);    // Takt/8
37
38
  DDRC=0xff;
39
  PORTC= 0xff;
40
  sei();
41
}
42
43
// ###################################### main ###########################
44
45
int main(void)
46
{
47
  
48
  init();
49
  
50
  while(1)
51
  {
52
  }
53
  return 0;
54
} // Ende main
55
56
57
//########################################################################

von Stefan E. (sternst)


Lesenswert?

1
  void wait();
1
  init();
Fällt dir da nicht irgendwie ein Unterschied auf?

von 123 (Gast)


Lesenswert?

Welchen Wert hat waiter, wenn du wait() aufrufst?

von Karl H. (kbuchegg)


Lesenswert?

@TO

Stefan meint diese Stelle
1
ISR(TIMER0_OVF_vect)    // TOV alle 170µs bei 12 MHZ und Teiler 8
2
{
3
  void wait();
4
  PORTC ^= ( 1 << PC7 );
5
} // Ende ISR

Das ist KEIN Funktionsaufruf!
Das ist die Vereinbarung einer Funktion, ein Prototyp.

von Peter II (Gast)


Lesenswert?

> void wait()

also so würde ich es nun nicht schreiben, keine ahnung ob das ein 
Problem ist.


wait();

so ist es zumindest üblicher.


Außerdem ist es sehr ungünstig in der ISR selber noch eine funktion 
aufzurufen, damit müssen alle Register gesichert werden. Das sollte man 
vermeiden.

waiter muss auch nicht volatile sein.

von Udo S. (Firma: allround) (1udo1)


Lesenswert?

Danke Euch allen! Funktioniert.

Manchmal läuft man neben der Spur!!

von Dirk (Gast)


Lesenswert?

Peter II schrieb:

> Außerdem ist es sehr ungünstig in der ISR selber noch eine funktion
> aufzurufen, damit müssen alle Register gesichert werden. Das sollte man
> vermeiden.
Quatsch!
Es wird nur das gerettet was notwendig ist!

von Peter II (Gast)


Lesenswert?

Dirk schrieb:
> Quatsch!
> Es wird nur das gerettet was notwendig ist!

nein, sobal ein funktionsaufruf drin ist, werden alle Register gerettet. 
Der compiler weiss das nicht mehr was gebraucht wird.

von Karlo (Gast)


Lesenswert?

Der TE hat nur eine Kompiliereinheit, mit Optimierung sollten nur die 
wirklich notwendigen Register gesichert werden, anstatt alle.

von Peter II (Gast)


Lesenswert?

Karlo schrieb:
> Der TE hat nur eine Kompiliereinheit, mit Optimierung sollten nur die
> wirklich notwendigen Register gesichert werden, anstatt alle.

ja, weil due funktion hoffentlich ge-inlined wird. Dann ist es aber kein 
funktionsaufruf mehr. Sobald ein funktionsaufruf nach der optimierung 
drin bleibt werden alle Register gesichert.

von Karl H. (kbuchegg)


Lesenswert?

Karlo schrieb:
> Der TE hat nur eine Kompiliereinheit, mit Optimierung sollten nur die
> wirklich notwendigen Register gesichert werden, anstatt alle.

Wenn der Compiler die Funktion inlined, dann schon.
Wenn nicht, dann sichert er alles.
Ein C-Compiler ist nicht verpflichtet, den Inhalt anderer Funktionen zu 
analysieren, wenn es darum geht, was der Aufrufer zu tun hat und was 
nicht.

Und im Falle des gcc gibt es ein API, welches besagt, dass es eine Reihe 
von Registern gibt, die eine Funktion benutzen darf, ohne sie selber 
sichern und wiederherstellen zu müssen.

Damit geht der gcc im nichtinline Fall pragmatisch vor, und sichert am 
ISR Anfang genau diese Register und stellt sie am Ende wieder her. Das 
einzige was sicher ist: wenn es keinen Funktionsaufruf gibt und die 
Register auch sonst in der ISR nicht benutzt werden, dann müssen sie 
auch nicht gesichert/restauriert werden.

von LassWonadersDefinen (Gast)


Lesenswert?

Peter II schrieb:
>> void wait()
>
> also so würde ich es nun nicht schreiben, keine ahnung ob das ein
> Problem ist.

Mensch Peter, ob I oder II, les doch mal den Kommentar von Karl Heinz 
vor deinem!!

                          P R O T O T Y P !!!

von Peter II (Gast)


Lesenswert?

LassWonadersDefinen schrieb:
> Peter II schrieb:
>>> void wait()
>>
>> also so würde ich es nun nicht schreiben, keine ahnung ob das ein
>> Problem ist.
>
> Mensch Peter, ob I oder II, les doch mal den Kommentar von Karl Heinz
> vor deinem!!
>
>                           P R O T O T Y P !!!


schau dir mal die Zeiten an und überlege was passiert sein könnte? Es 
haben alle zur gleichen Zeit den Kommentar verfasst. Dabei kann so etwas 
passieren.

von LassWonadersDefinen (Gast)


Lesenswert?

Peter II schrieb:
> ... keine ahnung ob das ein Problem ist.

Nix da Freundchen, keine Ausflüchte(siehe Zitat).
Bei uns hieß es immer, wenn man keine Ahnunge hat, einfach mal die 
Klappe halten.

von Peter II (Gast)


Lesenswert?

LassWonadersDefinen schrieb:
> Bei uns hieß es immer, wenn man keine Ahnunge hat, einfach mal die
> Klappe halten.

Ich hatte die Lösung noch mit geschrieben, und ja ich bin wirklich nicht 
sicher was passiert wenn man ein Prototype innerhalb ein funktion 
deklariert. Denn C oder C++ unterstützen meines wissens keine "Nested 
function".

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:

> Ich hatte die Lösung noch mit geschrieben, und ja ich bin wirklich nicht
> sicher was passiert wenn man ein Prototype innerhalb ein funktion
> deklariert. Denn C oder C++ unterstützen meines wissens keine "Nested
> function".

Das hat damit nichts zu tun. Funktionsdeklarationen bzw. Prototypen 
kannst du schreiben, wo du willst.

In meiner Anfangs Kernighan&Ritchie Zeit war es (für mich) gang und gebe 
zb zu schreiben
1
#include <stdio.h>
2
3
int main()
4
{
5
  double a;
6
  double cos();
7
8
  for( a = 0; a < PI; a += 0.01 )
9
  {
10
    printf( "%f %f\n", a, cos(a) );
11
  }
12
}

* math.h wurde nicht inkludiert.
* Der Protoyp war notwendig, damit der Compiler wusste, dass die 
Funktion cos keinen int liefert, sondern einen double. Bei Funktionen, 
die sowieso einen int lieferten, wurde auf die Funktionsdeklaration 
komplett verzichtet.
* Auf die Datentypen der Argumente wurde geschi... verzichtet, da der 
Compiler das double-Argument sowieso aus dem Aufruf ermitteln konnte.
* void? Was ist void? void gab es noch nicht. Also brauchte man sich 
auch keinen Kopf darüber zu machen. Alles was der Compiler irgendwie 
annehmen musste, war automatisch ein int.

Tja. Nachdem ich dann oft genug damit auf die Schnauze gefallen war, bin 
ich dann dazu übergegangen:
Header Files zu inkludieren, wenn es sie gab.
Funktionsdeklarationen und später dann Protoypen an den Anfang der 
C-Datei zusammenzufassen.

Dann wurde es besser. Die Fehler aufgrund fehlerhaften Argumente an 
Funktionen nahmen drastisch ab.

Das war übrigens keineswegs irgendwie verpönt. Funktionsdeklarationen 
mitten unter den restlichen Variablendefinitionen waren damals gang und 
gäbe und nichts, worüber man sich groß gewundert hätte.
Irgendwo muss ja der schlechte Ruf, der C heute noch nachhängt, ja auch 
herkommen :-)

Damit da keine Missverständnisse aufkommen. Das war 1987/88/89. In 
meiner Sturm und Drang Zeit.
Heute ist sowas völlig inakzeptabel.

von J.-u. G. (juwe)


Lesenswert?

Peter II schrieb:
> Denn C oder C++ unterstützen meines wissens keine "Nested
> function".

Du hast vollkommen recht. Da wir uns aber hier im gcc-Unterforum 
befinden, sei die Bemerkung gestattet, dass gcc "nested functions" 
mittels Erweiterung unterstützt (für C).

von Druckkopfschmerz (Gast)


Lesenswert?

Jouuu: gefunden auf gcc.org

6.4 Nested Functions
A nested function is a function defined inside another function. Nested 
functions are supported as an extension in GNU C, but are not supported 
by GNU C++.

von Druckkopfschmerz (Gast)


Lesenswert?


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.