Hallo, ich habe mir vor einiger Zeit das Pollin AVR Board in der Version 2.0 gekauft und habe dnan angefangen ein paar kleinigkeiten dait zu machen. Mein aktuelles Ziel ist es das ich ein Datenpacket (4Bytes) an den µC sende und dieser eine entsprechende aktion ausführt. Das ganze hat mit pollen funktioniert, allerdings ist das Ziel das es über interrupts geht. Dazu habe ich mir den angehängten Code ausgedacht. Dabei habe ich mir das wie folgt gedacht: 1) Es gibt einen lese und einen schreib index. 2) Ich warte im hauptprogramm darauf das der schreib index ungleich dem lese index ist. Ist dies der fall lese ich ein Byte aus einem globalen array und erhöhe den lesezeiger. 3) Im EMpfangsinterrupt des µC speichere ich die empfangenen daten im array ab und erhöhe den schreib zeiger. So kann ich wie in einem ringpuffer das array immer wieder durchgehen. Zu Debug-Zwecken habe ich mir mal die positionen ausgeben lesen, doch die Zeiger verändern sich nicht. (Durch einen uart_putc('0'+schreib_index)) Allerdings wird die LED die ich im Interrupt Blinken lasse entsprechend an und aus geschaltet. Kann mir villeicht jemand helfen. Irgend etwas muss ich ja grundlegend noch falsch machen? Ich habe mcih dazu auch slebst informaiert und google u.ä. angestrengt, aber leider nichts gefunden was mir die Frage beantworten könnte. Einen fertigen code möchte ich ungerne nutzen, da ich verstehen möchte warum meine heranngehensweise nicht geht. Gruß, Andre´ P.s.: Ich benutze das Pollin AVR Bard 2.0 (ATMega32 16Mhz) Einen Bootloader (http://hubbard.engr.scu.edu/embedded/avr/bootloader/index.html) Einen USB RS232 Wandler (HugePine?) Das AVR Studio 4.13 Build 528 WinAVR-20080512
Siehe: Beitrag "AVR-GCC: UART mit FIFO" Fallgrube 2. Da Deine Indexe 16-bittig sind, trifft auch Fallgrube 3 zu. Peter
@Peter Dannegger Hallo Peter, viele Dank für deine Antwort. Wenn ich heute Zeit finde werde ich versuchen deine Hinweise umzusetzen. Zwei frage habe ich aber noch, warum ist esschlimm wenn ich mit 16 Bit Zahlen arbeite? Ich weis zwar das es theoretisch möglich wäre das eine Operation mit der Zahl nicht Atomar ist und somit theoretisch unterbrochen werden kann, aber warum stellt das ein problem dar? Werden Register nicht vorher gesichert bevor sie in anderen Routinen wieder verwendet werden? Meine Zweite Frage wäre, aus welchem Grund werden die Zugriffe (puffer_schreiben++) weg optimiert? Gruß Andre´
Andre F. wrote: > Zwei frage habe ich aber noch, warum ist esschlimm wenn ich mit 16 Bit > Zahlen arbeite? Warum soll es schlimm sein? Es ist nur Verschwendung von Flash und SRAM. > Ich weis zwar das es theoretisch möglich wäre das eine Operation mit der > Zahl nicht Atomar ist und somit theoretisch unterbrochen werden kann, > aber warum stellt das ein problem dar? Nicht nur theoretisch, das passiert auch praktisch. Und wenn ein Fehler nur einmal am Tag auftritt und die Software ausrastet, dann viel Spaß beim Debuggen. Fehlervermeidung ist 1000-mal effektiver als Fehler debuggen. > Werden Register nicht vorher > gesichert bevor sie in anderen Routinen wieder verwendet werden? Welche Register, es geht um Variablen. Wenn z.B der Interrupt einen 2-Byte Wert von 0x01FF auf 0x0200 ändert und das genau zwischen den 2 Bytezugriffen des Main passiert, dann kriegt das Main einen völlig anderen Wert, wie 0x02FF oder 0x0100, je nach Lesereihenfolge. > Meine Zweite Frage wäre, aus welchem Grund werden die Zugriffe > (puffer_schreiben++) weg optimiert? Woher weißt Du das, auf welche Codezeile bezieht sich das? Peter
@ Peter Dannegger: >> Meine Zweite Frage wäre, aus welchem Grund werden die Zugriffe >> (puffer_schreiben++) weg optimiert? > > Woher weißt Du das, auf welche Codezeile bezieht sich das? Ich vermute, er bezieht sich auf diesen Satz: > Fallgrube 2: > Da hier Interrupts mit main-Funktionen kommunizieren, müßten die Indexe > als volatile definiert werden, damit sie der AVR-GCC nicht wegoptimiert. und hat als Beispiel eine Codezeile, wo auf den Index zugegriffen wird, rausgesucht. @ Andre F.: Es geht dabei nicht darum, dass Code wegoptimiert wird, sondern dass Speicherzugriffe wegoptimiert werden. Eine kritische Zeile in deinem Code ist z.B. diese:
1 | while(puffer_schreiben==puffer_lesen) {} |
puffer_schreiben wird nur einmal am Anfang der Schleife aus dem Speicher gelesen, und danach werden nur noch Registerinhalte verglichen. Mit "volatile" sagst du dem Compiler, dass sich der Inhalt von puffer_schreiben auch zwischendurch ändern kann, und er erzeugt dann Code, der den Wert in jedem Schleifendurchlauf neu aus dem Speicher liest.
Hallo, ersteinmal vielen Dank für eure Hilfe. Ihr habt mit beide sehr weiter gegholfen und ich glaube das ich das Problem jetzt auch verstanden habe. Sollte ich diesbezüglich noch Probleme haben werde ich heute abend nochmal schreiben, aber ich denke das ist das jetzt auch alleien hin bekomme. Danke nochmal
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.