Forum: Compiler & IDEs avr-gcc 4.3.0 ohne no_inline buggy, mit no_inline korrekt


von Mehmet K. (mkmk)


Angehängte Dateien:

Lesenswert?

Servus allerseits

[gcc vers. 4.3.0 (WinAvr 20080610)]

In all den Jahren in denen ich dieses Forum verfolge, habe ich die 
Erfahrung gemacht, dass der Ausruf "Compiler-Fehler!!" meist mit einem 
betretenen Schweigen des Ausrufers beendet wurde.
Vermutlich werde auch ich mich unter diese "schweigende Mehrheit" 
einordnen müssen, aber was soll's: ich stecke fest und komme nicht 
weiter.

In der Beilage habe ich ein kleines Beispiel zusammengestellt.


main() Zeile 27:
1
Usart_0_Send_Paket( 0x01, (BYTE *)"Hallo", 5L );
Diese sendet zuerst einen Header bestehen aus 4 Bytes und dann die 
eigentlichen Daten; in diesem Fall "Hallo".

Wenn ich der Funktion Usart_0_send in Zeile 28 das Attribut 
no_inline verpasse, funktioniert es so, wie es soll: Die Funktion 
Usart_0_Send_Paket in Zeile 39 sendet zuerst den Header bestehen aus
1
0x02 0x01 0x05 0x00
und dann die eigentlichen Daten.

Ohne das Attribut no_inline wird irgendein Header(*) gesendet und dann 
die (korrekten) Daten.

(*) Der Header aendert sich, wenn ich im Code was aendere und neu 
compiliere. Solange ich nicht neu compiliere, wird stets der gleiche 
(falsche) Header gesendet.

MfG aus Istanbul

von yalu (Gast)


Lesenswert?

> Vermutlich werde auch ich mich unter diese "schweigende Mehrheit"
> einordnen müssen

Könnte sein :)

Zumindest hat auch dein Programm einen Fehler, der das Verhalten
erklären könnte:

Der Header wird in Usart_0_Send_Paket in der automatischen Variable
buffer aufgebaut und diese über Umwege an den Interrupthandler
übergeben. Wenn dieser in Aktion tritt, ist aber i.Allg.
Usart_0_Send_Paket schon längst beendet und damit buffer nicht mehr
existent.

Deklarierst du buffer als static, sollte die Sache funktionieren.

von Mehmet K. (mkmk)


Lesenswert?

Servus Yalu

".... Usart_0_Send_Paket schon längst beendet ..."
1
while(USART_0.TxD_BytesToSend) ;

buffer[] bleibt also bis zum Schluss existent.

von Andreas W. (andreasw) Benutzerseite


Lesenswert?

Deklariere mal die komplette Struct als volatile:
1
volatile struct stru_usart
2
{
3
  BYTE *TxD_ptr; 
4
  WORD TxD_BytesToSend;
5
  BYTE TxD_TimeOut;         
6
7
  WORD RxD_BytesReceived; 
8
  BYTE RxD_TimeOut;         
9
  BYTE Buffer[BUFFER_0_SIZE];
10
} USART_0;

PS: Ist aber ganz schön durch einander der Code ;-)

von Mehmet K. (mkmk)


Lesenswert?

Servus Andreas

Yessss, das war's.
[Kopfkratzen] Wo ist aber der Unterschied zwischen
1
volatile struct stru_usart
2
{
3
  BYTE *TxD_ptr; 
4
};

und
1
struct stru_usart
2
{
3
  volatile BYTE *TxD_ptr; 
4
};

?

von (prx) A. K. (prx)


Lesenswert?

In der zweiten Variante ist das Ziel von TxD_ptr volatile, in der ersten 
Variante die Variable TxD_ptr selbst. Die erste Variante entspricht also
1
struct stru_usart
2
{
3
  BYTE *volatile TxD_ptr; 
4
};
Gräm dich nicht - die Deklarationstechnik von C ist von vorneweg 
gründlich vermurkst worden. Basiert auf einer anfangs nett wirkenden 
Idee, nämlich die Deklaration wie die Nutzung aussehen zu lassen, 
stiftet sie jedoch weit eher Verwirrung.

von Mehmet K. (mkmk)


Lesenswert?

Danke für die Belehrung. Man lernt nie aus.

von Manuel S. (thymythos) Benutzerseite


Lesenswert?

Habs mal ins Tutorial aufgenommen.

von yalu (Gast)


Lesenswert?

> while(USART_0.TxD_BytesToSend) ;
>
> buffer[] bleibt also bis zum Schluss existent.

Tschuldigung, das hatte ich übersehen. Aber zum Glück (für dich und den
Compiler ;-)) ist das Problem ja jetzt trotzdem gelöst.

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.