Forum: Compiler & IDEs Wie finde ich den Fehler (PORT wird überschrieben)


von Pier S. (bigpier)


Lesenswert?

Guten Tag,
ich habe ein Problem. Ich habe ein Programm geschrieben mit einer RS485 
Kommunikation.
Dieses Programm funktioniert im Normalfall und macht was es soll.
Nun zu meinem Problem in Unregelmäßigen Intervallen Wird mein 
Sendeenable Ausgang (RS485 Treiber) von irgendwem gesetzt.
Dieser Pin wird von mir in der Sendefunktion gesetzt und vom Trasmit 
Complete Interrupt ausgeschaltet.
So schon auf vielen Schaltungen realisiert.
Fakt ist das hier irgendwer oder irgendwas den Ausgang setzt.
Zur Hardware ich verwende einen ATMEGA 164PA
Und das AVRStudio 7.
Wie finde ich diesen Fehler? wie sucht man sowas?
Kann ich irgendwie mit einem Pointer auf diesen einen Pin kommen?
Wenn ich mit dem Debugger das Programm anhalte und den PIN D2 ausmache 
läuft das Programm wieder ganz normal weiter.
Hilft es wenn ich das Projekt in ein Zip stecke und hier anhänge?

Lg
Peter

von Pier S. (bigpier)


Lesenswert?

Noch eine Frage
Sollen schreibe Zugriffe auf die Ports Automar sein?

Lg
Peter

von A. S. (Gast)


Lesenswert?

Pier S. schrieb:
> Dieser Pin wird von mir in der Sendefunktion gesetzt und vom Trasmit
> Complete Interrupt ausgeschaltet.

Dann ist es wahrscheinlich, dass es in der Sendefunktion gesetzt wird 
und der Transmit Complete Interrupt nicht kommt. Weil
- das Pin-Setzen erst nach dem abschicken erfolgt, oder
- Transmit schon abgeschaltet ist, oder
- ein Überlauf das Senden eines Bytes verhindert, oder
- ein einfacher Programmierfehler, oder
- ein Hardware-Bug (die gibt es bei seriellen Schnittstellen des 
Öfteren, vor allem gefühlt mit Rx/Tx gleichzeitig und 8 Bit + Parity).


Also: Code Posten.

von A. (Gast)


Lesenswert?

Hast du einen ICE Debugger? Damit kanst du Variablen überwachen und eine 
Unterbrechung auslösen, sobald sich hier ein Wert ändert. Dann siehst du 
sofort, wo das im Quellcode passiert ist.

von Pier S. (bigpier)


Angehängte Dateien:

Lesenswert?

A. schrieb:
> Hast du einen ICE Debugger?

Ja habe ich aber wie soll ich den breakpoint setzen?
Im Anhang der Code
Lg

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. schrieb:
> eine Unterbrechung auslösen, sobald sich hier ein Wert ändert

Funktioniert leider nicht für IN/OUT auf einen Port.  Das funktioniert
nur für RAM-Bereiche.

Allerdings könnte man sich natürlich das Disassembly-Listing ansehen
und schauen, ob es potenzielle Kandidaten gibt, die via OUT auf den
Port gehen.

Pier S. schrieb:
> Noch eine Frage Sollen schreibe Zugriffe auf die Ports Automar sein?

Schreibzugriffe sind atomar, aber Bitmanipulationen müssen es nicht
unbedingt sein.  Sie können auch als read-modify-write implemenetiert
sein.  Wenn du die Compileroptimierungen nicht gerade ausschaltest,
sollten jedoch Bitmanipulationen, deren Werte zur Compilezeit konstant
sind, bei einem ATmega164 durch den Compiler als SBI/CBI implementiert
werden und damit atomar sein.

von Stefan E. (sternst)


Lesenswert?

Dein Problem steckt vermutlich in der Funktion Map_Out. Dort sind 
mehrere nicht-atomare RMW-Zugriffe auf PORTD enthalten.

von Stefan E. (sternst)


Lesenswert?

Jörg W. schrieb:
> Wenn du die Compileroptimierungen nicht gerade ausschaltest,
> sollten jedoch Bitmanipulationen, deren Werte zur Compilezeit konstant
> sind, bei einem ATmega164 durch den Compiler als SBI/CBI implementiert
> werden und damit atomar sein.

Ja, aber nicht wenn mehrere Bits auf einmal gesetzt/gelöscht werden. 
Dann hilft das "zur Compilezeit konstant" auch nicht. ;-)

von Pier S. (bigpier)


Lesenswert?

Jörg W. schrieb:

>
> Schreibzugriffe sind atomar, aber Bitmanipulationen müssen es nicht
> unbedingt sein.  Sie können auch als read-modify-write implemenetiert
> sein.  Wenn du die Compileroptimierungen nicht gerade ausschaltest,
> sollten jedoch Bitmanipulationen, deren Werte zur Compilezeit konstant
> sind, bei einem ATmega164 durch den Compiler als SBI/CBI implementiert
> werden und damit atomar sein.

Ich HAbe die Optimierung auf auf Og gestellt.

Jörg W. schrieb:
> Allerdings könnte man sich natürlich das Disassembly-Listing ansehen
> und schauen, ob es potenzielle Kandidaten gibt, die via OUT auf den
> Port gehen.

Welches File ist das?


Stefan E. schrieb:
> Ja, aber nicht wenn mehrere Bits auf einmal gesetzt/gelöscht werden.
> Dann hilft das "zur Compilezeit konstant" auch nicht. ;-)

Also ist sowas gefährlich?
1
 PORTD |= (1<<Out_1)| (1<<Out_2);

Lg

Peter

von Stefan E. (sternst)


Lesenswert?

Pier S. schrieb:
> Also ist sowas gefährlich?

Ja, daraus wird ein RMW-Zugriff, den du davor schützen musst, dass der 
Interrupt da "mitten rein" fällt.

von Pier S. (bigpier)


Lesenswert?

Stefan E. schrieb:
> Ja, daraus wird ein RMW-Zugriff, den du davor schützen musst, dass der
> Interrupt da "mitten rein" fällt.

Mit der ATOMIC Function?

Danke Lg

von Pier S. (bigpier)


Lesenswert?

so in etwa?
1
ATOMIC_BLOCK(ATOMIC_FORCEON) 
2
{
3
    PORTD |= (1<<Out_1)| (1<<Out_2); 
4
  }

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan E. schrieb:
> Ja, aber nicht wenn mehrere Bits auf einmal gesetzt/gelöscht werden.

Stimmt natürlich.

Pier S. schrieb:
>> Allerdings könnte man sich natürlich das Disassembly-Listing ansehen
>> und schauen, ob es potenzielle Kandidaten gibt, die via OUT auf den
>> Port gehen.
>
> Welches File ist das?

avr-objdump -d <ELF-file>

Falls deine Toolchain eine .lss-Datei erstellt: das ist auch ein
Disassembly, bei dem der Disassembler nach Möglichkeit den zugehörigen
Quellcode mit hineinsetzt.

von Pier S. (bigpier)


Lesenswert?

Jörg W. schrieb:
> Stefan E. schrieb:
>> Ja, aber nicht wenn mehrere Bits auf einmal gesetzt/gelöscht werden.
>
> Stimmt natürlich.
>
> Pier S. schrieb:
>>> Allerdings könnte man sich natürlich das Disassembly-Listing ansehen
>>> und schauen, ob es potenzielle Kandidaten gibt, die via OUT auf den
>>> Port gehen.
>>
>> Welches File ist das?
>
> avr-objdump -d <ELF-file>
>
> Falls deine Toolchain eine .lss-Datei erstellt: das ist auch ein
> Disassembly, bei dem der Disassembler nach Möglichkeit den zugehörigen
> Quellcode mit hineinsetzt.

@Jörg W.
Danke für die Erklärung.
@Stefan E.
Danke Dir für die schnelle Hilfe und das finden des Fehlers.

Es sieht so aus als ob es jetzt funktionieren würde.
Noch eine letzte Frage, Wenn ich das schreiben der zwei Bit aufteile 
würde der zugriff atomic sein?

LG
Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Pier S. schrieb:
> Wenn ich das schreiben der zwei Bit aufteile würde der zugriff atomic
> sein?

Ja, jeder für sich natürlich.

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.