- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Semaphoren Lock für Variablenzugriff

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332

    Semaphoren Lock für Variablenzugriff

    Anzeige

    Powerstation Test
    Hallo Zusammen,

    mein Programm greift via Interrupt auf interne Variable des Atmel atMega32 zu. Hierbei handelt es sich um die Datentypen, byte, word, long und float.

    Problemlos ist eigentlich nur die Bytevariable, da diese im Schreibzugriff nicht unterbrochen werden kann.

    Gibt es eine einfach Methode einen sicheren Zugriff auf Variablen innerhalb einer Interrupt-Routine sicherzustellen.

    Generell habe ich alle Variablen, welche in der Interruptroutine abfrage, als "volatile" deklariert.

    Nur was passiert, wenn das Hauptprogramm gerade das erste Byte Long einer Variable geschrieben hat,
    und dann ein Interrupt eintritt.

    Unter Linux kann ich hierbei auf Semaphoren zugreifen, gibt es sowas auf für atmega32 ?

    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Du musst bei Zugriffen, die atomar erfolgen sollen, Interrupts kurz ausschalten. Die avr-libc bringt bereits in util/atomic.h entsprechendes Werkzeug mit.

    Codebeispiel:
    Code:
    #include <util/atomic.h>
    
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
        // Tu was atomar
    }
    mfG
    Markus

    PS: Du kannst natürlich auch einfach selbst vor dem zu schützenden Bereich mit cli() Interrupts deaktivieren und danach mit sei() wieder Anschalten.
    PPS: Beide Varianten müssen im Normalfall nur im Hauptprogramm eingesetzt werden, ISRs sind ohne eigenes Zutun nicht unterbrechbar und benötigen damit einen solchen Schutz nicht.
    Tiny ASURO Library: Thread und sf.net Seite

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von markusj Beitrag anzeigen
    PS: Du kannst natürlich auch einfach selbst vor dem zu schützenden Bereich mit cli() Interrupts deaktivieren und danach mit sei() wieder Anschalten.
    Besser ist es, sich den Interruptstatus zu merken, dann ihn zu deaktivieren und am Ende den alten Zustand wiederherzustellen. Das kann dann gefahrlos auch verwendet werden, wenn mal aus anderen Gründen der Interrupt gesperrt ist.

    Ich kenne jetzt die avr-libc nicht, aber der Name "ATOMIC_RESTORESTATE" klingt, alsob es da so gemacht wird.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hi,
    hat jemand schon mal eine Funktion geschrieben, welche einen Variablenwert "Atomic" ändert ?

    Hier würde ich dann auch das ab/an Schalten des Interrupts einfügen. Wild cli() / sei() setzen ist nicht mein Ding.
    Kaum macht man es richtig, schon funktioniert's ...

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Zitat Zitat von Klebwax Beitrag anzeigen
    Besser ist es, sich den Interruptstatus zu merken, dann ihn zu deaktivieren und am Ende den alten Zustand wiederherzustellen. Das kann dann gefahrlos auch verwendet werden, wenn mal aus anderen Gründen der Interrupt gesperrt ist.
    Das erfordert mehr Aufwand, den man in manchen Situationen nicht bereit ist zu leisten.

    Zitat Zitat von Klebwax Beitrag anzeigen
    Ich kenne jetzt die avr-libc nicht, aber der Name "ATOMIC_RESTORESTATE" klingt, alsob es da so gemacht wird.
    Genau so ist es.

    @Ritchie: Warum? Dafür braucht es keine Funktion.
    Code:
    // tu was und berechne foo
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      bar = foo; // atomare Zuweisung
    }
    Tiny ASURO Library: Thread und sf.net Seite

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von markusj Beitrag anzeigen
    Das erfordert mehr Aufwand, den man in manchen Situationen nicht bereit ist zu leisten.
    Naja, so aus der Erinnerung : Das Register mit dem Globalen Enable mit PUSH auf den Stack, disable Interrupt, .... POP Register ( drei Zeilen statt zwei) und schon hat man Stunden beim Debuggen gespart.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hi,
    das sieht ja doch ganz gut aus.

    Ich habe jetzt nur evtl. ein Problem mit meiner Impulsmessung der Encoder. Dieser werden auch per Interrupt eingelesen. Schalte ich hier die Interrupts entsprechend ab, laufe ich Gefahr, das ich Impuls verliere (was ich noch testen müsste).

    Wozu ich die ganze Sache benötige?
    Ich habe einen Hauptrechner, welcher Parameter an die Motorsteuerung sendet. Dies sind z.b. aktuelle Position in der Karte, Zielposition, Ausrichtung, Geschwindigkeit, etc...

    Gleichzeitig werden Werte aus der Motorsteuerung zurück an den Hauptrechner gemeldet, wie aktuelle Position, aktuelle Ausrichtung, Status, etc...

    Positionen sind im Integer Format (2Byte) und Winkel in float (4byte) abgelegt.

    Wenn die Motorsteuerung einen Wert aktualisiert, kann es sein, das gleichzeitig, das Hauptprogramm den gleichen Wert abfragt.
    Ich habe zeitweise -30491 als Wert im Logfile, statt 2277, obwohl ich diese Abfrage im Standby mache (also Stillstand!).

    Ich dachte bin jetzt immer, das hier ein Übertragungsfehler vorliegt, dieser wird aber nicht vom Hauptprogramm gemeldet.
    Der falsche Wert muss also auch im Kontroller so vorhanden sein.
    Wenn dies zu einem falschen Zeitpunkt passiert (Übernahme von Parameter), kommt das garnicht gut.

    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.09.2009
    Ort
    Berlin (Mariendorf)
    Beiträge
    1.023
    Vielleicht kannst du die konkurrierenden nicht-atomaren Zugriffe auf die Mehrbyte-Variablen in Schattenvariablen puffern und den Austausch mit den "heissen" Variablen in einen kürzest-möglichen Programmabschnitt zusammenlegen. Die ISR setzt bei jedem Durchlauf ein Freigabeflag ("ISR was here"), auf das in der Hauptprogrammschleife gewartet wird. Man könnte dann sozusagen im zeitlichen Windschatten der ISR den Datenaustausch flink vollziehen, sobald die wieder einmal durch ist und für eine bestimmte minimale Zeitdauer garantiert nicht in die Quere kommen kann. Vor dem nächsten kritischen Zugriff wird das Flag vom Hauptprogramm gelöscht und wieder darauf gepollt, bis dieses "von Geisterhand" gesetzt wird ...
    Erweiterungsmöglichkeit: Die ISR akzeptiert ihr eigenes "ISR was here"-Flag als Zugriffsverbot und überspringt ggf. den kritischen Abschnitt. Das entspräche in etwa einem acknowledge oder hand shake.

    Gruß
    Christian.

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hi,
    generelle scheint mir Deine Idee ein gangbarer Weg zu sein, da nur hier die volle Kontrolle der Daten vorhanden ist. Schalte ich den Interrupt up, weiss ich nicht, welche Daten ich verliere, da auch die Messwertverarbeitung via Interrupt arbeitet.
    Dies entspricht auch mehr der Vorgehensweise eines "Semaphore-Lock".
    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

  10. #10
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von Ritchie Beitrag anzeigen
    Schalte ich den Interrupt up, weiss ich nicht, welche Daten ich verliere, da auch die Messwertverarbeitung via Interrupt arbeitet.
    Wieso glaubst du überhaupt, irgendetwas zu verlieren, wenn du Interrupts kurz ausschaltest? Welcher Interrupt soll es denn sein, der da während einer Handvoll Takte gleich mehrmals kommen soll?
    MfG
    Stefan

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Memory Lock Bits
    Von dj5am im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 09.11.2011, 17:31
  2. mega32 - Lock and Fusebits - Frage
    Von dirtyklaus im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 10.04.2008, 22:27
  3. Fuse-/Lock Bits beim ATmega32
    Von quad im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 16.02.2006, 21:05
  4. Fuse-/Lock Bits beim ATmega162
    Von quad im Forum AVR Hardwarethemen
    Antworten: 9
    Letzter Beitrag: 20.09.2005, 14:24
  5. Lock- und Fusebits bei M32
    Von Nico99 im Forum Schaltungen und Boards der Projektseite Mikrocontroller-Elektronik.de
    Antworten: 14
    Letzter Beitrag: 13.02.2005, 15:43

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress