-
Serialin Buffer
Guten Morgen
Ich hab da mal eine Frage bezüglich des Buffers.
Gibt es eine möglichkeit den Serialen Buffer zuvergrößern?
Beim mitlesen einer Schnittstelle kommt es bei mir zu komplikationen da der größte Frame 260 Byte groß ist und keine CTS oder RTS benutzt werden.
Da das Programm noch anderweitig beschäftigt ist kann es passieren das nicht alle Daten gelesen werden.
Also kann man den Buffer vergrößern oder hat jemand eine Lösung?
Nur so neben bei. Wieso kann ich den dritten Serialen Buffer z.B eines Atmega2560 nur auf 254 Byte setzen. Normal müssten doch 255Byte gehen oder nicht?
MfG
-
Bascom verwendet nur Bytes als Pointer für den ringbuffer. dadurch fällt mal alles darüber aus.
wegen den 254 muss ich annehmen, dass er bei seinen berechnungen sonst Probleme kriegt, das müßt' ich analysieren. Aber das eine Byte hülfe dir ja eh nix.
Ich fürchte, den RIngbuffer auf größer mußt du zu Fuß machen. Kommst du damit zurecht ?
-
Das eine Byte hilft mir nicht da hast du recht. Mich interessierte es bloß weil er beim serialin und beim serialin3 aktzeptiert er die size von 255. Nur beim serialin1 und 2 meckert Bascom beim kompilieren.
Den Ringbuffer zu Fuß. :-k Da könnte ich einen anstoß gerbrauchen, arbeite noch nicht lange mit Bascom und meine Programmierwissen ist ein wenig eingerostet.
-
Ein Anstoss:
Code:
Dim Base As Word
Dim Top As Word
Dim Wrpnt As Word
Dim Rdpnt As Word
Dim One_w As Byte
Dim One_r As Byte
Dim Buffer(260) As Byte
Buf_init:
Base = Varptr(buffer(1)) 'mem-adr von Buffer-base
Top = Base + 260 'mem adr von bufer top
Wrpnt = Base 'write pointer
Rdpnt = Base 'read pointer
Return
Buf_write:
One_w = Udr ' byte from UART
Out Wrpnt , One_w ' into buffer
Incr Wrpnt ' pointer + 1
If Wrpnt >= Top Then Wrpnt = Base ' wrap around
Return
Buf_read:
interrupts disable
If Rdpnt = Wrpnt Then
interrupts enable
One_r = 0 ' no data
Else
interrupts enable
One_r = Inp(rdpnt) ' read from pointer
Incr Rdpnt ' pointer + 1
If Rdpnt >= Top Then Rdpnt = Base ' wrap around
End If
Return
"Buf-write" passiert eigentlich in der Interrupt-routine
"Udr" wird bei dir anders heissen
-
Cool danke.
Wenn ich das richtig verstanden habe müsste das in etwa wie folgt aussehen.
Code:
$regfile = "m2560def.dat"
$crystal = 14745600
$baud = 921600
Config Com3 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Enable Interrupts
Enable Urxc2
On Urxc2 Buf_write
Dim Base As Word
Dim Top As Word
Dim Wrpnt As Word
Dim Rdpnt As Word
Dim One_w As Byte
Dim One_r As Byte
Dim Buffer(260) As Byte
Buf_init:
Base = Varptr(buffer(1)) 'mem-adr von Buffer-base
Top = Base + 260 'mem adr von bufer top
Wrpnt = Base 'write pointer
Rdpnt = Base 'read pointer
Return
Do
'Main Programm
Loop
Buf_write:
One_w = Udr2 ' byte from UART
Out Wrpnt , One_w ' into buffer
Incr Wrpnt ' pointer + 1
If Wrpnt >= Top Then Wrpnt = Base ' wrap around
Return
Buf_read:
Disable Urxc2
If Rdpnt = Wrpnt Then
Enable Urxc2
One_r = 0 ' no data
Else
Enable Urxc2
One_r = Inp(rdpnt) ' read from pointer
Incr Rdpnt ' pointer + 1
If Rdpnt >= Top Then Rdpnt = Base ' wrap around
End If
Return
Mir schwebt grad noch eine Funktion in form des Ischarwaiting vor (bzw. ein FlagBit). Das sollte allerdings kein Problem sein.
Danke nochmal für deine Hilfe.
MfG
-
Dem "Ischarwaiting" entspricht dieser Vergleich:
If Rdpnt = Wrpnt Then ..
Das interrupt-disablen ist, weil bei eine 2-byte vergleich ein Durcheinander rauskommen kann. Aber ich glaub, das wußtest du eh.
Btw: Wenn deine Frames ein definiertes Ende haben, würde ich den Check, ob das Frame komplett ist, in die ISR legen und dann einen speziellen Flag für das HauptProgramm setzen. Das wäre effizienter
-
Ja stimmt das entspricht dem "Ischarwaiting".
Allerdings kann man im Hauptprogramm so noch nicht erkennen ob Daten vorliegen. Mir fehlte da einfach ein Flag. Bin ich gestern aber nicht so schnell drauf gekommen. Ausgeschlafen ging das einfach schnell.
Das mit den Interrupts war mir nicht ganz klar und ist es auch noch nicht ganz. Kurzer verweis oder erklärungen wären hilfreich.
Leider haben die Frames eine variable länge. Je nach Information.
Ersten beiden Bytes beinhalten die Länge letztes die CRC.
Habe dafür bisher eine eigene Routine geschrieben.
Muss mir halt noch überlegen ob man beides verbinden kann.
MfG
-
Wenn er ein Word mit zwei Bytes vergleicht, vergleicht er ja erst das eine und dann das andere. Wenn aber genau da ein Interrupt dazwischen fährt und die ISR den "WrPnt" verändert, ist der Vergleich nicht koscher. Daher wird während des Vergleichs der interrupt disabled und gleich danach wieder aufgedreht.
Die ISR hat Zustände
1 Warten auf frame-start
2 lesen frame-länge
3 lesen daten
(4) Frame-crc OK ->Frame ready (oder nicht)
je nachdem läuft es etwas anders ab, den CRC rechnest du gleich mit, und wenn die Daten alle gelesen sind, muss ja dein nachberechneter CRC grad genau den Startwert haben.
? Ist das ein bekanntes frame-format ?
? welche art crc
-
Ist es nicht etwas ungeschickt den "Frametest" in der ISR zu machen?
Man soll doch ISR kurz halten oder nicht?
Ich könnte mir vorstellen das wenn der Test zu lange dauert ein paar bytes verloren gehen. Oder die ISR neu Startet.
Meiner meinung nach würde der Frametest besser in den Buf_read passen.
Lasse mich gerne überzeugen das es auch im ISR geht. Vllt. denke ich einfach zu "langsam".
Den Test mache ich bereits in der Reihenfolge in einer eigenen Routine.
Das soll allerdings später noch besser zusammen gefasst werden.
Ob es ein bekanntes Format ist weiß ich nicht. Kenne mich da zu wenig aus.
Der Frame besteht aus Länge, einer Komplement der Länge, NxInformation und CRC
CRC = summe Informationsbytes modulo 256
MfG
-
Naja, in epischer Breite soll eine ISR nicht sein. aber sooooo viel sind die paar checks ja auch nicht
Aber da will ich dir nix einreden.