-
        

Ergebnis 1 bis 8 von 8

Thema: Wie einen Ringbuffer in Bascom programmieren?

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2006
    Beiträge
    11

    Wie einen Ringbuffer in Bascom programmieren?

    Anzeige

    Hallo Bascom und C Experten,

    ich will mit GCC als auch in einem Bascom Programm einen Ringbuffer für serielle 3 Byte Befehle per RS232 anlegen. Hat jemand ein bisschen Code oder gar eine Lösung für mich? Meine Versuche sind alle kläglich gescheitert weil es immer irgendwo Hänger gab.


    Euer junger Hirsch
    Alterbursch

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Naja, Althirsch, weiß nicht, wo du da hängenbleibst ?
    Code:
    const bufsize = nn
    DIM buffer(bufsize] as byte
    DIM Wrindex AS BYTE
    DIM Rdindex AS BYTE
    
        Wrindex = 1
        Rdindex = 1
    
    
    
    
    
    reinschreiben:
        buffer(Wrindex) = 1.byte
        gosub Incr_wrindex
        buffer(Wrindex) = 2.byte
        gosub Incr_wrindex
        buffer(Wrindex) = 3.byte
        gosub Incr_wrindex
        return
    
    
    
    
    Incr_wrindex:
        incr Wrindex
        if Wrindex > bufsize then 
           wrindex = 1
        end if
        return
    
    
    rauslesen:
        if Rdindex = Wrindex then 
               is_nix_da
        else
              1.byte = buffer(Rdindex)
              gosub Incr_rdindex
              2.byte = buffer(Rdindex)
              gosub Incr_rdindex
              3.byte = buffer(Rdindex)
              gosub Incr_rdindex
       end if
       return
    
    
    
    
    Incr_rdindex:
        incr rdindex
        if rdindex > bufsize then 
           rdindex = 1
        end if
        return
    Ist die Grundform. wenn "bufsize" ein vielfaches von 3 ist, kann man auch ein bißchen sparen
    Zu klären ist beim reinschreiben, ob überhaupt Platz ist und beim lesen, was is, wenn nix da ist.

    Kommt auf die Anwendung an.

    In C ist das genauso, nur daß Wrindex und Rdindex von 0 beginnen.


    Für C gibts beispiele in unserer Wiki
    http://www.roboternetz.de/wissen/ind...FO_mit_avr-gcc
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2006
    Beiträge
    11
    Hallo Picnick
    Ich bleibe nicht hängen, das Programm bleibt hängen Erst dann hängen wir beide.

    Das Problem besteht vermutlich darin das Daten auch dann eingehen wenn ich gerade Daten entnehme. Treten diese Konflikte bei dir nicht auf wenn Daten schnell fortlaufend eingehen?

    Euer junger Hirsch
    Alterbursch

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Typische Anwendung ist ja sowas wie "serialin=buffered", d.h. im Interrput kommen Daten rein, und von außen werden sie ausgelesen.
    Da der Schreiber und der Leser ja jeder nur seinen Pointer(Index) verwenden, vertragen sie sich im Prinzip ja.
    Heikel ist nur der Vergleich der Pointer (ob was da ist). Bei Byte-Index, ist das kein Problem, aber (wenn) 16-Bit Words verwendet werden, isses geraten,
    vor dem Vergleich ein "disable interrupts"
    und nachher wieder ein "enable" zu machen.

    Bei 3-Byte "Blöcken" ist die Sache etwas gemischter, denn eigentlich dar der "write pointer" erst verändert werden, wenn wirklich 3 Bytes da sind.

    Ich mach das mit einem zusätzlichen "temp" Pointer. d.h. erst wird über den geschrieben, und erst wenn die Message komplett ist, wird der "write" pointer gesetzt.
    d.h. Für den Leser sind entweder alle 3 byte da oder garnix.

    Klingt wirr, isses auch
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    02.03.2005
    Ort
    OWL
    Beiträge
    216
    Hallo junger Hirsch!

    Ich habe für eine Frässteuerung folgendes gemacht:
    Code:
    'Fehlercodes
    Const Error = 0
    Const Ok = 1
    Const Overflow = 2
    
    'einen Ringspeicher definieren
    Const Arraymax = 30
    Dim Cmd(arraymax) As Byte
    Dim Pakt As Byte , Pend As Byte, I As Byte
    
    'den Ringspeicher initialisieren
    Pend = 1
    Pakt = 1
    Pakt ist sowas wie ein Zeiger auf die aktuelle Position und Pend enthält den Index der letzten Position (die ja immer eine andere sein kann).
    Beim Hinzufügen von Daten schreibe ich folgendes:
    Code:
        I = Pend + 1
        If I > Arraymax Then I = 1
        If I = Pakt Then
            Printbin Overflow ;            'Fehlercode senden (Überlauf des Stacks)
        Else                                  'kein Überlauf
            Pend = I                            'letzter Satz ist i
            Cmd(pend) = Udr_byte(1)             'Das Kommando übergeben
            Printbin Ok ;
        End If
    Ich sende also jedesmal eine Bestätigung, ob ein Kommando abgelegt werden konnte oder nicht. Wenn ich kein weiteres Kommando ablegen kann, weil der Ringspeicher voll ist, versuche ich solange zu senden, bis das Senden mit Ok bestätigt wird, also eigentlich ganz einfach.
    Wichtig ist noch, dass beim Abarbeiten eines Kommandos der Zeiger Pakt erhöht wird, also:
    Code:
                Incr Pakt                                       'Zeiger auf aktuellen Satz erhöhen
                If Pakt > Arraymax Then Pakt = 1                'wenn Überlauf, dann erneut beginnen

    Kannst Du damit was anfangen?
    Ich gebe zu, PicNicks Lösung ist schöner...

    Ruppi

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2006
    Beiträge
    11
    Die Lösung mit Temp-Zeiger könnte passen da es ja 3 Bytes sind, hast du dafür zufällig ein größeren Auszug deiner Ringverwaltung parat?

  7. #7
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    naja, eigentlich jein. Ich hab das für das Network-Project durchgezogen,
    die entsprechenden Bascom-libraries bzw. Sourcen kannst du gerne haben.
    Aber dabei ist eben unser Level-0 binär-data protokoll (f. UART) implementiert,
    http://www.roboternetz.de/wissen/ind...ller/PC_Praxis
    das mischt die Sache einigermassen auf und macht sie wohl schwer leserlich.
    (die Messages sind variabel lang, also keine fixe Länge wie bei Dir)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    02.10.2006
    Beiträge
    11
    Schade. Na dann werde ich mich durchbeißen und noch mal etwas coden. Dein Networkprojekt blicke ich nicht so ganz, ist aber für meine Zwecke sicher auch zu überfrachtet. Ich will nur einen starken Getriebemotor vernünftig steuern.

Berechtigungen

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