Forum: Mikrocontroller und Digitale Elektronik Abfrage ob Buffer voll, nur dann senden


von paule (Gast)


Lesenswert?

Hallo,

stehe vor einem Problem, was eigentlich ein C Problem ist.
Und zwar habe ich ein Protokoll in dem ein Token sitzt. Wenn jetzt ein 
Modul, den Buffer voll hat und das Token "1" ist soll er senden können, 
in den anderen Fällen natürlich nicht.

Wie kann ich einen Buffer auf Inhalt prüfen, meine Gedanke war:

if((databytes && (receive_buf[3]>>4)==1 ))

wobei databytes ein buffer mit 4 Bytes Inhalt ist.


Danke im voraus

Grüße
paule

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

paule schrieb:
> wobei databytes ein buffer mit 4 Bytes Inhalt ist.
Wenn databytes tatsächlich ein Puffer (also sowas:  char databytes[4]) 
ist, dann ist databytes ein Zeiger auf diesen Puffer...

von paule (Gast)


Lesenswert?

Hallo,

databytes ist ein char databytes[4].
Das heisst ich muss in einer for Schleife, die einzelnen Elemente prüfen 
ob = NULL ?

Gruß
paule

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

paule schrieb:
> Das heisst ich muss in einer for Schleife, die einzelnen Elemente prüfen
> ob = NULL ?
Das kommt darauf an, welche Werte in diesem Array abgespeichert sein 
können. Wenn da eine binäre/dezimale/hex 0 dabei ist, dann bringt deine 
Abfrage auf NULL auch nichts, denn NULL = 0 = 0x00 usw...

paule schrieb:
> stehe vor einem Problem, was eigentlich ein C Problem ist.
Nein, das ist kein C-Porblem. Ganz und gar nicht.
Es ist ein Verständnisproblem von dir...

Was hast du für Daten, wo kommen die her, wo gehen die hin?
Was ist dein Protokoll?
Welche Schnittstelle willst du verwenden?

von paule (Gast)


Lesenswert?

Hallo,

also ich möchte Daten über die UART rausschicken, mein Protokoll besteht 
aus:
Source, Destination, TLL, Token , MsgType, Databytes, CRC32

Ich sende diese Daten per Uart und möchte nach dem Senden den Puffer 
dann aber wieder leeren, bzw. ein Abbruchkriterium haben, damit das 
Senden zu Ende ist.

Standardmäßig bin ich im Receive Task, der beim Interrupt angesprungen 
wird. Dort werden die Daten dann gefiltert und falls destination != 
Source, werden die Daten direkt weitergesendet. So viel zur 
Empangsroutine.

Die Senderoutine erfolgt im selben Task. Beim Senden habe ich bis jetzt 
nur als Bedingung,das wenn das Token im Paket ist, Daten gesendet werden 
sollen. Jedoch soll ja das auch der Fall sein, wenn der Receive Buffer 
leer ist, dann habe ich ja auch nichts empfangen und könnte senden. Und 
damit ich nur einmal sende, dachte ich, ich lösche den Sende Buffer nach 
dem Senden.

Ich weiss nur nicht wie ich das handhaben soll.

Gruß
paule

von Karl H. (kbuchegg)


Lesenswert?

paule schrieb:
> Hallo,
>
> also ich möchte Daten über die UART rausschicken, mein Protokoll besteht
> aus:
> Source, Destination, TLL, Token , MsgType, Databytes, CRC32
>
> Ich sende diese Daten per Uart und möchte nach dem Senden den Puffer
> dann aber wieder leeren, bzw. ein Abbruchkriterium haben, damit das
> Senden zu Ende ist.

Das ist alles sehr unverständlich beschrieben.

> Standardmäßig bin ich im Receive Task, der beim Interrupt angesprungen
> wird.

Du empfängst also von irgendwo her was?

> Dort werden die Daten dann gefiltert und falls destination !=
> Source, werden die Daten direkt weitergesendet. So viel zur
> Empangsroutine.

Klingt für mich nach:

Du hast sowas wie einen Zwischenbaustein, der auf der einen Seite etwas 
empfängt und auf der anderen Seite etwas weiterschickt?

>
> Die Senderoutine erfolgt im selben Task. Beim Senden habe ich bis jetzt
> nur als Bedingung,das wenn das Token im Paket ist, Daten gesendet werden
> sollen.

Was für ein Token?

> Jedoch soll ja das auch der Fall sein, wenn der Receive Buffer
> leer ist, dann habe ich ja auch nichts empfangen und könnte senden.

Hä?

> Und
> damit ich nur einmal sende, dachte ich, ich lösche den Sende Buffer nach
> dem Senden.

Du brauchst normalerweise nichts löschen. Einfach eine Variable nehmen, 
die anzeigt ob Daten in einem Buffer gültig sind oder nicht. Hat man 
gültige Daten und bearbeitet sie, dann wird die Markierungsvariable 
wieder auf ungültig gesetzt und fertig.

Aber deine Beschriebbung dessen, was du eigentlich machen willst, ist 
mir zu schwammig, als das ich mich da jetzt aus dem Fenster lehnen 
würde. Das ist alles zu undurchsichtig bzw. zu schwammig beschrieben um 
erraten zu können was du eigentlich vor hast.

von Karl H. (kbuchegg)


Lesenswert?

paule schrieb:

> sollen. Jedoch soll ja das auch der Fall sein, wenn der Receive Buffer
> leer ist, dann habe ich ja auch nichts empfangen und könnte senden.

Widerspricht das nicht dem hier

> Wenn jetzt ein
> Modul, den Buffer voll hat und das Token "1" ist soll er senden können,
> in den anderen Fällen natürlich nicht.

von paule (Gast)


Lesenswert?

Hallo,

ich versuch es nochmal kurz zu beschreiben:

Also es gibt mehrere Module die untereinander vernetzt werden sollen, 
dazu soll eine Zugriffsregelung erfolgen und ein eigenes Protokoll 
benutzt werden. Das Protokoll habe ich oben ja beschrieben. Nun hat 
jedes Modul einen Sender und einen Empfänger.

Empfängt Modul B jetzt von A Daten, muss überprüft werden, ob die Daten 
überhaupt für B sind. Wenn nein werden sie zur Zeit in einer Receive 
Routine über den Sender von B rausgeschickt.

Möchte B jetzt aber auch mal Daten senden, dann muss B ja gerade frei 
fürs Senden sein und das Token muss bereit stehen. Und dieses "mal" 
Daten senden bereitet mir gerade Schwierigkeiten, da ich nicht genaus 
weiss, wie ich dann einen Sendeinterrupt auslösen soll.

Das mit dem Flag für Daten gültig oder nicht hört sich gut an. Aber 
woran würde ich das dann fest machen. Wenn die Daten einmal gesendet 
wurden, muss ich den Buffer dann ja als ungültig deklarieren.

Gruß
paule

von Karl H. (kbuchegg)


Lesenswert?

Kann es sein, dass du so etwas wie einen Token Ring bauen willst?

von paule (Gast)


Lesenswert?

Ja genau, so wollte ich den Zugriff regeln.

von Karl H. (kbuchegg)


Lesenswert?

Dann hast du da etwas misverstanden.

Der 'Token' ist eine reine Konzeptidee. Im Datenpaket ist der nicht 
enthalten. Sondern der Baustein, der gerade das Datenpaket hat, hat 4 
Möglichkeiten:

* das Paket ist überhaupt leer

     dann kann der Baustein entscheiden, ob er etwas hat, was er
     auf den Weg bringen will. Er füllt dann seine Daten in das
     Paket ein, markiert das Paket als nicht leer und schickt
     es an seinen Nachfolger weiter

* das Paket wurde von ihm abgesendet

     dann gibt es offenbar den Empfänger gar nicht im Ring.
     Der Baustein entfernt dann seine Daten aus dem Paket, markiert
     es als leer und schickt es weiter.
     Oder, wenn er andere Daten hat, dann setzt er diese in das Paket
     ein und schickt somit ein neues Paket auf die Reise

* das Paket wurde von jemanden anderen an ihn gerichtet

     er holt sich dann die Daten aus dem Paket, markiert das Paket
     als leer und schickt das leere Paket weiter zum nächsten.
     Oder aber, wenn er selber Daten hat, dann füllt er diese ins Paket

* das Paket ist nicht leer und nicht an ihn gerichtet

     dann gibt er es ganz einfach weiter.


Der Token ist ein Gedankenkonzept, aber kreisen tut immer das 
Datenpaket. Und nur wenn ein Teilnehmer im Besitz eines leeren 
Datenpakets ist, dann kann er selbst seine Daten da einsetzen und auf 
den Weg bringen. Leer werden kann ein Paket auf 2 Arten:
  entweder es war beim Empfang schon leer
  oder der Teilnehmer hat die Daten aus dem Paket herausgenommen
und nur dann wenn ein Teilnehmer im Besitz eines leeren Datenpaketes 
ist, dann kann er selber seine Daten ins Paket einsetzen.

Stell dir 4 Menschen vor, die an einem Tisch sitzen. Da gibt es einen 
Zettel der immer reihum kreist. Auf dem Zettel sind 3 Felder: Wer 
schickt wem welche Nachricht.  Derjenige, bei dem gerade der Zettel ist, 
der 'hat den Token' und er hat einen Bleistift und Radiergummi um auf 
dem Zettel Notizen zu machen. Und er hat natürlich noch einen 2.ten 
Zettel, auf dem er sich 'Zwischenspeichern' kann, was er an Daten 
weitergeben soll, während der Zettel gerade unterwegs ist. Erst dann, 
wenn er den Zettel hat und der Zettel leer wird (oder durch ihn leer 
gemacht wurde), kann er dann die zwischengespeicherten Daten in den 
Zettel übertragen und die Daten somit auf den Weg bringen.

Du als Programmierer gibst jetzt die Spielregeln aus, wie diese 4 Leute 
mit dem Zettel umgehen müssen, damit das 'Netzwerk' wie vorgesehen 
funktioniert.

von paule (Gast)


Lesenswert?

Hallo,

okay, klingt logisch das Ganze.
Ich habe mich ein bisschen daran orientiert und habe das so vor das ich 
ein Byte benutze, das anzeigt ob nach einem Datenpaket noch weitere 
Daten kommen oder ob der Sendevorgang nach diesem Paket fertig ist und, 
falls Daten vorliegen, derjenige selber senden kann, nachdem er das 
empfangene Paket weitergeleitet hat.

Das empfangene Paket leite ich auf jedenfall weiter, da ich damit 
mitbekomme ob ein Teilnehmer ausfällt oder nicht. Jeder Sender bekommt 
sein Paket also wieder zurück.

Meine Frage ist eben noch, wie prüfe ich "falls Daten vorliegen" ?

Gruß
paule

von Karl H. (kbuchegg)


Lesenswert?

paule schrieb:

> Meine Frage ist eben noch, wie prüfe ich "falls Daten vorliegen" ?

Na das weiß doch dein Programm, ob es Daten hat die es auf den Weg 
bringen will oder nicht. Im Regelfall werden die ja wohl in 
irgendwelchen Variablen zwischengespeichert worden sein, da die Daten ja 
asynchron zum umlaufenden Datenpaket anfallen. Meistens hat man dafür 
eine Queue, wenn man nicht garantieren kann, dass nicht kurzzeitig mehr 
zu sendende Daten anfallen.

von paule (Gast)


Lesenswert?

Hallo,

okay, ich habe mir dazu einen Buffer angelegt.

Da ich mit FreeRtos arbeite und bis jetzt nur einen Task habe, könnte 
ich dann in einem anderen Task eine Queue mit Daten beschreiben lassen, 
und wenn diese voll ist ein data-available flag setzen.

Gruß
paule

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
Noch kein Account? Hier anmelden.