Forum: Compiler & IDEs Bei doppeltem Aufruf von Unterfunktion bleibt µc hängen


von M. H. (dbzwerg)


Lesenswert?

Hallo,

ich möchte int werte über die eingebaute uart meines atmega8 ausgeben, 
soweit so gut.
Ich benutze dafür die lib von fleury,dass funktioniert auch eigentlich 
problemslos ,ich habe mir zur Ausgabe meiner integerwerte eine kleine 
unterfunktion gebaut,die mir zuerst die Werte in lesbar zeichen umsetzt, 
siehe hier.
1
...
2
3
#include <stdlib.h> // enthällt die Umwandlung von int zu char (itoa)
4
5
...
6
7
//Deklaration der Funktionsprototypen
8
9
void send_int_uart(int value); // Deklaration für UART INt SEND Unterfunktion
10
11
...
12
13
//Unterfunktion Integerwert über uart ausgeben
14
void send_int_uart(int value)
15
{
16
char buffer [33];
17
itoa (value,buffer,10);
18
uart_puts(buffer);
19
uart_puts("\n\r");
20
21
}
22
...

Nun zu meinem Problem:


Ich verwende diese Funktion in einer ISR des Timer0.
Wenn ich ich das so compiliere..
1
...
2
3
      //uart_puts("Wert1:");
4
      //send_int_uart(wert1);
5
      uart_puts("Wert2:");
6
      send_int_uart(wert2);
7
      count_1s = 0;
8
...
läuft alles wunderbar und der wert2 wird ausgegeben, wenn ich nun wert1 
mitausgeben will
1
...
2
3
      uart_puts("Wert1:");
4
      send_int_uart(wert1);
5
      uart_puts("Wert2:");
6
      send_int_uart(wert2);
7
      count_1s = 0;
8
...

bekomme ich vom compiler kein error/warning, aber mein µc hält einfach 
an sobald er zu dieser Stelle kommt.

Nun der Gretchenfrage... wo steckt der Fehler?

Muss dazu sagen das die ISR der Overflowroutine meines Timers ist , die 
alle 100us kommt, ist das evtl. zu viel für meinen Chip( betreibe den 
mit einem externen 8 Mhz Quarz, fusebits sind auch richtig gesetzt).

Ich benutz zum kompilieren winavr, optimierungsstufe ist S.


So hoffe ich habe alle nötigen Angaben gemacht und jemand findet meinen 
denkfehler.

MFG

von Karl H. (kbuchegg)


Lesenswert?

M. H. schrieb:

> Nun der Gretchenfrage... wo steckt der Fehler?

Daran, dass du versuchst innerhalb einer ISR eine Ausgabe zu machen. Die 
Fleury-Lib wickelt ihre Ausgaben über Interrupts ab. Der auszugebende 
Text wird in einen Zwischenbuffer gesteckt und dann nach und nach über 
Interrupts ausgegeben. Ist allerdings der Buffer voll, dann wartet die 
Ausgaberoutine darauf, dass wieder Platz geschaffen wird (durch die 
Ausgabe in der USART Interrupt Routine). Nur: Das passiert nie.
Du machst deine Ausgaben in einer ISR und da sind Interrupts gesperrt. 
Also läuft auch nie der UART Interrupt, der Platz im Buffer schaffen 
würde. Ergo wartet die Ausgaberoutine bis zum Sankt Nimmerleinstag 
darauf, dass endlich wer ein paar Zeichen aus dem Buffer an die UART 
ausgibt, damit sie ihre letzten Zeichen reinstecken kann. Deine ISR 
hängt somit in einer Endlosschleife, wird nie fertig und gibt daher auch 
nie die Interrupts wieder frei, die dafür sorgen würden, dass der Buffer 
entleert würde. Du hast dir da einen schönen Deadlock eingehandelt.

UART Ausgaben macht man nicht in einer ISR!

von Peter D. (peda)


Lesenswert?

M. H. schrieb:
> Muss dazu sagen das die ISR der Overflowroutine meines Timers ist , die
> alle 100us kommt, ist das evtl. zu viel für meinen Chip

Das fragt man nicht, das rechnet man ganz einfach aus:
Nehmen wir an, Du willst 20 Zeichen senden, ein Zeichen ist 10Bit lang.
Dann ergibt das als kleinst mögliche Baudrate:

20 * 10 / 100µs = 2MBaud.


Peter

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.