Archiv verlassen und diese Seite im Standarddesign anzeigen : FIFO Ringbuffer Assembler
Hallo zusammen
ich suche Quellcode für einen Ringbuffer in Assembler bzw. Codesnipsel oder sonstigen Hilfen dazu.
Habe mich bereits selbst daran versucht, doch bisher ist es mir noch nicht gelungen. Wie kann ich auf Erreichen des Pufferende nachfragen?
Ich verwende einen ATMega32.
Bin für jede Hilfe dankbar.
Ich weiß zwar nicht was ein Ringbuffer ist; jedoch weiß ich dach es im Wiki eine Fifo-Lib gibt. Diese arbeitet aber meines Wissens nicht sehr ökonomisch, aber es ist sicher eine gute Anleitung wie man es Programmieren kann...
Hallo ebby,
eigentlich mache ich eher 'C' aber ich kann mal das Prinzip beschreiben:
Für einen Ringpufferpuffer musst du erst mal Speicher für die Daten reservieren. Dann brauchst einen Merker, für die Stelle in Deinem Speicher an die Du das letzte mal geschrieben hast und einen Merker, für die Stelle in Deinem Speicher, von der Du das letzte mal gelesen hast. Das wars auch schon.
Jetzt musst Du nur noch jedesmal, wenn Du was in den Ringpuffer rein schreibst Deinen "SchreibeMerker" um eins erhöhen und wenn Du was Rausliest, Deinen "LeseMerker" um eins erhöhen.
Wenn Du jetzt noch nach dem Erhöhen von einem Merker den Merker wieder auf dan Anfang von Deinem Speicher setzt, wenn der Merker zu groß ist, bist Du fertig.
Das Erreichen des Pufferendes kannst Du erkennen, indem Du Deinen Merker mit der Endaddresse Deines Puffers (Startaddresse +Länge des Puffers) vergleichst.
Ich versuchs mal in pseudo 'C' vielleicht hilft es Dir...
Speicher reservieren:
------------------------
uint8 Puffer[GROESSE];
uint8 *LeseMerker;
uint8 *SchreibeMerker;
Init:
----
LeseMerker=&Puffer[0];
SchreibeMerker=&Puffer[0];
Schreiben:
-----------
SchreibeMerker++;
if( SchreibeMerker>=&Puffer[GROESSE] )
{ SchreibeMerker=&Puffer[0]; }
*SchreibeMerker=ZuSchreibenderWert;
Lesen:
------
LeseMerker++;
if( LeseMerker>=&Puffer[GROESSE] )
{ LeseMerker=&Puffer[0]; }
AusgelesenerWert=*LeseMerker;
Drew
PS.: Du kannst das ganze noch erweitern, in dem Du beim Lesen die beiden Merker vergleichst und so herausfinden, ob Du von einer Stelle liest, in die auch schon was geschrieben wurde, oder nicht (Overflow Error).
Am einfachsten dürfte das mit indizierten Lese und Schreibbefehlen mit Auto Inkrement gehen.
LDI XL,low (Startadresse) ;X Register mit Startadresse füttern
LDI XH,high (Startadresse)
....
LDI R16,konstante
CALL Schreibloop
.....
Schreibloop:
ST X+,R16 ; Den Wert von R16 im Speicherplatz ablegen und X um 1 erhöhen
LDI R17,low (maxAdress) ; R17 und R18 auf das Ende des Ringpuffers einstellen
LDI R18,high(maxAdress)
CP R17,XL ; Vergleichen ob das Ende des Ringpuffers erreicht ist
CPC R18,XH
BRCC ENDE ; Das Ende ist nicht erreicht -> nächster Wert
LDI XL,low (Startadresse) ; Das Ende ist erreicht -> wieder am Anfang beginnen
LDI XL,high (Startadresse)
ENDE:
Return ; Wieder in die aufrufende Routine zurück gehen.
Die Ausleseroutine kann analog z.B. mit dem Y Register erfolgen.
In die Schreibroutine müsste noch eine Überwachung, das der Schreibzeiger, den Lesezeiger nicht überholt. -> Nach dem Schreiben darf der Schreibzeiger nicht gleich dem Lesezeiger sein.
Das würde Datenverlust zur Folge haben ( Buffer Overflow )
Wenn der Lesezeiger den Schreibzeiger erreicht hat ist der Ringpuffer wieder geleert.
Du kannst natürlich auch die aktuellen Schreib- und Leseadressen in einem RAM Speicherplatz ablegen, damit die Routine zerteilen und bei Bedarf den Schreib- bzw. Lesebegfehl ausführen.
Wenn Du das X und Y Register exklusiv für die Indizierung der Adressen nutzen kannst (wie im Beispiel oben), bleibt Dir das Laden und Abspeichern der Adressen in das RAM erspart.
Ich hoffe ich hab das einigermassen Verständlich rübergebracht, wenn nicht poste mal wo es hakt.
Danke für die Antworten
habe jetzt einen ersten Versuch hin. Allerdings ohne Überwachung des Schreibzeigers. Habe einfach den Ringbuffer relativ groß gemacht. Die Daten dürften schnell genug gelesen werden.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.