Forum: Mikrocontroller und Digitale Elektronik ? zu Programmkonzept


von Thomas P. (topla)


Lesenswert?

Hallo zusammen,

ich benötige für ein Projekt etwas Starthilfe für das Programmkonzept, 
irgendwie habe ich da einen kleinen Hänger:
Ziel ist die Entwicklung eines Umsetzers für Daten aus einer Steuerung 
auf eine serielle Schnittstelle.

Die Daten werden über eine SPI-ähnliche Schnittstelle durch 
Software-Bitgewackel (also ohne Nutzung der SPI-Schnittstelle) an ein 
paar Pins in einen 20 Byte großen Puffer im RAM eingelesen.
Bedingung ist, dass auch kurzzeitige H-Pegel erkannt und gemeldet 
werden, egal, ob sie bei der Datenweitergabe noch anliegen oder nicht. 
Deshalb werden die "neuen" Daten mit den im Puffer schon vorliegenden 
Daten "Oder"-verknüpft.
Diese Schnittstelle wird durch einen Timer gesteuert und läuft ständig 
durch. Das funktioniert reibungslos.

Die serielle Schnittstelle auf der anderen Seite empfängt ein Kommando 
zur Abfrage der gepufferten Daten. Daraufhin werden die Daten 
prüfsummengesichert an den PC gesendet, der die Übertragung nach Prüfung 
der Prüfsumme als richtig oder falsch quittiert. Das funktioniert auch.

Meine (umgesetzte) Idee ist, jedes aus dem Puffer entnommene Byte mit 
einem Flag zu kennzeichnen, welches bei Eintreffen neuer Daten aus der 
Steuerung festlegt, ob die neuen Daten direkt (Flag gesetzt, also schon 
versandt) oder "Oder"-verknüpft (Flag nicht gesetzt, noch nicht 
versendet) eingetragen werden.

Das Dumme an dieser Idee ist nun, dass ich nicht weiß, wie ich mit 
diesem Konstrukt umgehe, wenn der PC die Übertragung als fehlerhaft 
abweist. Dann müsste ich ja die gesetzten Flags zurücknehmen. Allerdings 
können in der Zwischenzeit ja schon neue Daten aus der Steuerung 
eingetroffen sein, die die fehlerhaft verschickten Daten überschrieben 
haben - also irgendwie suboptimal, dabei können bereits erfasste 
High-Pegel verloren gehen.

Zeitlich ist das Ganze auch etwas kritisch. Auf die Anfrage des Pcs, die 
mit unterschiedlichen Abständen erfolgen kann, muss in einem engen 
Zeitfenster geantwortet werden, das vorherige Kopieren der 20 Bytes in 
einen zweiten Puffer ist da nicht drin und die PC-Seite kann ich nicht 
beeinflussen.

Hat da jemand eine Idee, wie ich das Problem angehen könnte? Ich stehe 
irgendwie auf dem Schlauch und habe ein Brett vor'm Kopf....

Danke für alle Anregungen
Thomas

von adsf (Gast)


Lesenswert?

a) Warum benutzt du keine interrupts zur Flankenerkennung
b) was soll denn passieren wenn die Prüfsumme falsch ist? Das fehlt 
irgendwie...

von Thomas P. (topla)


Lesenswert?

a)
Hmm, welche Flanken soll ich auswerten?
Die Daten aus der Steuerung hole ich timer(interrupt)gesteuert im 
Polling ab und auf die serielle Schnittstelle auf der PC-Seite reagiere 
ich auch interruptgesteuert.
b)
Wenn der PC einen Fehler meldet, sollen die Daten bei der nächsten 
Anforderung noch einmal übertragen werden, gemeinsam mit den bereits 
wieder aufgelaufenen Daten aus der Steuerung.
Irgendwie muss ich die Daten noch einmal puffern und das ganze Theater 
verwalten, habe aber keine brauchbare und performante Idee dazu.

Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas P. schrieb:

> Zeitlich ist das Ganze auch etwas kritisch. Auf die Anfrage des Pcs, die
> mit unterschiedlichen Abständen erfolgen kann, muss in einem engen
> Zeitfenster geantwortet werden, das vorherige Kopieren der 20 Bytes in
> einen zweiten Puffer ist da nicht drin

? Echt nicht? 20 Bytes.
Das kann ich mir kaum vorstellen.


> Irgendwie muss ich die Daten noch einmal puffern und das ganze
> Theater verwalten, habe aber keine brauchbare und performante Idee dazu.

Double Buffering mit einem Pointer der auf den jeweils relevanten Buffer 
zeigt?

von Thomas P. (topla)


Lesenswert?

Karl Heinz Buchegger schrieb:
> ? Echt nicht? 20 Bytes.
> Das kann ich mir kaum vorstellen.

Muss da vielleicht nochmal genau rechnen, aber ich bin mit dem AVR mit 
8MHz unterwegs und die intelligente Interfacekarte des Rechners verlangt 
eine Antwort "within 5µs". Ich muss ja auch die Flags 
kopieren/verwalten...

> Double Buffering mit einem Pointer der auf den jeweils relevanten Buffer
> zeigt?

Ja, auf irgend soetwas muss es hinauslaufen, aber mir fehlt die zündende 
Idee. ich glaube, ich gehe wohl erstmal eine Runde in die Kneipe...

Thomas

von holger (Gast)


Lesenswert?

>intelligente Interfacekarte des Rechners verlangt
>eine Antwort "within 5µs".

Naja, intelligent ist was anderes;) Ist das wirklich so?
Eine serielle Dtaenübertragung dauert doch schon länger.

von c-hater (Gast)


Lesenswert?

Thomas P. schrieb:

> Die Daten werden über eine SPI-ähnliche Schnittstelle durch
> Software-Bitgewackel (also ohne Nutzung der SPI-Schnittstelle) an ein
> paar Pins in einen 20 Byte großen Puffer im RAM eingelesen.
> Bedingung ist, dass auch kurzzeitige H-Pegel erkannt und gemeldet
> werden, egal, ob sie bei der Datenweitergabe noch anliegen oder nicht.
> Deshalb werden die "neuen" Daten mit den im Puffer schon vorliegenden
> Daten "Oder"-verknüpft.

Das hört sich nach einem reichlich kranken Konzept an.

> Die serielle Schnittstelle auf der anderen Seite empfängt ein Kommando
> zur Abfrage der gepufferten Daten. Daraufhin werden die Daten
> prüfsummengesichert an den PC gesendet, der die Übertragung nach Prüfung
> der Prüfsumme als richtig oder falsch quittiert. Das funktioniert auch.

Das ist auch krank. Nicht das eigentliche Konzept der seriellen 
Übertragung mit Prüfsumme, aber der fehlende Double Buffer. Die Daten 
können während der seriellen Übertragung und der Berechnung der 
Prüfsumme verändert werden. Meistens wird die also nicht stimmen, wenn 
das Zeug endlich alles beim Empfänger ist.

> Meine (umgesetzte) Idee ist, jedes aus dem Puffer entnommene Byte mit
> einem Flag zu kennzeichnen, welches bei Eintreffen neuer Daten aus der
> Steuerung festlegt, ob die neuen Daten direkt (Flag gesetzt, also schon
> versandt) oder "Oder"-verknüpft (Flag nicht gesetzt, noch nicht
> versendet) eingetragen werden.

Das ist nun endgültig völlig krank.

> Zeitlich ist das Ganze auch etwas kritisch. Auf die Anfrage des Pcs, die
> mit unterschiedlichen Abständen erfolgen kann, muss in einem engen
> Zeitfenster geantwortet werden, das vorherige Kopieren der 20 Bytes in
> einen zweiten Puffer ist da nicht drin

Bei double buffering kopieren nur Dumme den Pufferinhalt. Alle anderen 
switchen bloß pointer um. Wobei bei einem 20 Byte-Buffer der Unterschied 
zum Umkopieren noch nichtmal sehr groß ist.

Also nö, das Konzept insgesamt ist bescheuert. Wahrscheinlich kriegt man 
da nur Grund rein, wenn du die Eingangsdaten etwas näher beschreibst und 
definierst, was genau davon eigentlich relevant ist. Weil das mit der 
ODER-Verknüpfung scheint mir ziemlich sinnbefreiter Bullshit zu sein.

von Karl H. (kbuchegg)


Lesenswert?

Thomas P. schrieb:
> Karl Heinz Buchegger schrieb:
>> ? Echt nicht? 20 Bytes.
>> Das kann ich mir kaum vorstellen.
>
> Muss da vielleicht nochmal genau rechnen, aber ich bin mit dem AVR mit
> 8MHz unterwegs und die intelligente Interfacekarte des Rechners verlangt
> eine Antwort "within 5µs".

?
Was ist denn das für eine Karte?

Nur damit man anderen davon abrät.
5µs - das ist doch absichtlich Prügel zwischen die Beine werfen und dann 
auch noch heftig drauf rumhüpfen.

von holger (Gast)


Lesenswert?

>Nur damit man anderen davon abrät.
>5µs - das ist doch absichtlich Prügel zwischen die Beine werfen und dann
>auch noch heftig drauf rumhüpfen.

Das mit den 5us kann gar nicht stimmen.
Bei 8MHz schafft der ATMega8 max. 1MBaud.
In 5us kommt da nicht mal ein ganzes Byte rüber.

von Thomas P. (topla)


Lesenswert?

holger schrieb:
>>intelligente Interfacekarte des Rechners verlangt
>>eine Antwort "within 5µs".
>
> Naja, intelligent ist was anderes;) Ist das wirklich so?
> Eine serielle Dtaenübertragung dauert doch schon länger.

Ich habe die Karte jetzt nicht persönlich gefragt, aber da werkelt wohl 
irgendeine uralte Soft-UART und die erwartet eben den Beginn einer 
Datenübertragung auf ihre Anfrage im genannten Zeitraum oder meldet 
einen Timeout. Ich kann es nicht ändern und ich habe es auch nicht 
verzapft.

Thomas

von Karl H. (kbuchegg)


Lesenswert?

holger schrieb:
>>Nur damit man anderen davon abrät.
>>5µs - das ist doch absichtlich Prügel zwischen die Beine werfen und dann
>>auch noch heftig drauf rumhüpfen.
>
> Das mit den 5us kann gar nicht stimmen.
> Bei 8MHz schafft der ATMega8 max. 1MBaud.
> In 5us kommt da nicht mal ein ganzes Byte rüber.

Vielleicht reicht es der Karte schon, wenn nach dieser Zeit die Flanke 
vom Startbit kommt.

Trotzdem finde ich 5µs als Timeout heftig wenig.
Man muss ja auch bedenken, dass man eine Anfrage von der Gegenstelle 
erst mal parsen und auseinander nehmen muss, ehe man dann überhaupt erst 
mal weiß, was das Gegenüber überhaupt von einem will.

von Thomas P. (topla)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Trotzdem finde ich 5µs als Timeout heftig wenig.
> Man muss ja auch bedenken, dass man eine Anfrage von der Gegenstelle
> erst mal parsen und auseinander nehmen muss, ehe man dann überhaupt erst
> mal weiß, was das Gegenüber überhaupt von einem will.

Ich habe mir da bisher keine Gedanken drüber gemacht. Die Anfrage 
besteht aus zwei Byte und es gibt genau zwei mögliche Antworten; eine 
Art "ich bin da" und eben die Daten.
Da ist auch zeitlich überhaupt kein Problem und funktioniert, nur den 
Fall der Fehlermeldung als Quittung bekomme ich so nicht abgefrühstückt.

Thomas

von holger (Gast)


Lesenswert?

>> Naja, intelligent ist was anderes;) Ist das wirklich so?
>> Eine serielle Dtaenübertragung dauert doch schon länger.
>
>Ich habe die Karte jetzt nicht persönlich gefragt, aber da werkelt wohl
>irgendeine uralte Soft-UART und die erwartet eben den Beginn einer
>Datenübertragung auf ihre Anfrage im genannten Zeitraum oder meldet
>einen Timeout. Ich kann es nicht ändern und ich habe es auch nicht
>verzapft.

Mit welcher Baudrate arbeitest du da?

Mag sein, aber den ATMega8 mit 8MHz hast DU verzapft.
125ns pro Befehl (im günstigsten Fall). Das sind bei 5us
gerade mal 8 Befehle pro 1us. 40 Befehle in 5us.
Kein Wunder das du dich damit rumquälst. Nimm da mal
einen richtigen Rechenknecht mit 168MHz als Gegenstelle,
sprich einen ARM. Der langweilt sich da nur noch.

Auch wenn ich C-Hater nicht mag: Heute stimme ich ihm voll zu.
Es ist einfach krank was du da machst.

von Thomas P. (topla)


Lesenswert?

Ich habe das Gefühl, meine blödeste Idee am heutigen Tag war, hier nach 
einer Idee zu fragen.
Der eine erzählt was von irgendeiner Flankenerkennung ohne Zusammenhang 
zur gestellten Frage, der nächste kennt nur das Wort "krank" und stellt 
von außen gesetzte Randbedingungen in Frage und der letzte will mir 
einen 168MHz-Arm ans Ohr labern um mit einer Art Soft-SPI 20 Byte Daten 
abzuholen, nur weil die geforderte Reaktionszeit auf eine Anfrage auf 
der seriellen Schnittstelle etwas knapp ausfällt. Und ja, ein scheixx 
kranker ATMega8 reicht für diese Aufgabe dicke aus.

Das einzig Brauchbare kam von Karl Heinz Buchegger, dafür ausdrücklich 
herzlichen Dank, auch wenn ich noch nicht weiß, wie ich das am 
Geschicktesten umsetze - was die eigentliche Frage war.

Thomas

von Frank (Gast)


Lesenswert?

Vielleicht liegt es einfach nur an zu wenig Informationen. Aus deiner 
Sicht, hast vielleicht alles relevante beschreiben, aber für einen 
Außenstehenden könnte zu wenig sein um das ganze abstrakt zu erfassen 
und dir zu helfen... Mein Gedanke beim lesen war nur, "hä"!
Was soll das werden, Datenerfassung, dongle Ersatz oder spezielle 
industrieHW... Kind Ahnung und ohne solch unwichtige Information, wird's 
schwer sich das Problem selbst zu visualisieren und nach ner Lösung zu 
suchen...

Sry is wirklich nicht böse gemeint, aber DU kennst die 
Rahmenbedingungen, deine potetiellen Helfer leider nicht ;)

von Karl H. (kbuchegg)


Lesenswert?

Thomas P. schrieb:

> Das einzig Brauchbare kam von Karl Heinz Buchegger, dafür ausdrücklich
> herzlichen Dank, auch wenn ich noch nicht weiß, wie ich das am
> Geschicktesten umsetze - was die eigentliche Frage war.


Na komm.

uint8_t Buffer1[20];
uint8_t Buffer2[20];

uint8_t* primBuffer;
uint8_t* scndBuffer;


   primBuffer = Buffer1;
   scndBuffer = Buffer2;


Über primBuffer wickelst du erst mal den Schreibzugriff von der SPI ab. 
Die Daten landen in Buffer1.

kommt jetzt die Aufforderung, die Daten zu senden, dann schaufelst du 
dir die Daten frei.

   uint8_t* tmp = primBuffer;
   primBuffer = scndBuffer;
   scndBuffer = tmp;

prim und scnd haben die Plätze getauscht. Ab sofort landen die Bytes von 
der SPI über primBuffer in Buffer2. Währenddessen schaufelst du deine 
Daten über scndBuffer raus zu deiner ungeduldigen Hardware. Hinten nach 
noch die Hausaufgaben machen, wenn vom PC die Bestätigung bzw. ein 
Fehler kommt.
Im Fehlerfall müssen dann eben *scndBuffer und *primBuffer wieder 
zusammengeführt werden. Im OK Fall wird *scndBuffer ausgenullt, damit 
beim nächsten Bufferswap wieder alles bereit ist, damit die SPI Routinen 
wieder einen leeren Buffer vorfinden.

von Oliver (Gast)


Lesenswert?

holger schrieb:
> 40 Befehle in 5us.

Karl Heinz Buchegger schrieb:
> uint8_t* tmp = primBuffer;
>    primBuffer = scndBuffer;
>    scndBuffer = tmp;

plus UAR-Interrupt-Reaktionszeit plus UART-Interrupt plus etwas 
"rumgehüpfe drumrum" für die Logik, das wird arg eng.

Wenn etwas mehr Zeit wäre, hätte ich ja ein paar zusätzliche Puffer 
vorgesehen, die dann die nach einem Übertragungsfehler nochmals zu 
sendenden Daten halten.

Vielleicht kann mna ja auf eine Anfrage des PC's hin mehrfach "ich bin 
da" senden, um sich damit ein paar zusätzliche Zyklen Zeit zu 
verschaffen.

Wenn das nicht geht, sende halt Dummydaten mit fehlerhafter Prüfsumme ;)

Oliver

von holger (Gast)


Lesenswert?

>das vorherige Kopieren der 20 Bytes in
>einen zweiten Puffer ist da nicht drin und die PC-Seite kann ich nicht
>beeinflussen.

>Und ja, ein scheixx
>kranker ATMega8 reicht für diese Aufgabe dicke aus.

DU ALLEINE hast oben behauptet das er das eben NICHT kann.

von Thomas P. (topla)


Lesenswert?

holger schrieb:
>>das vorherige Kopieren der 20 Bytes in
>>einen zweiten Puffer ist da nicht drin und die PC-Seite kann ich nicht
>>beeinflussen.
>
>>Und ja, ein scheixx
>>kranker ATMega8 reicht für diese Aufgabe dicke aus.
>
> DU ALLEINE hast oben behauptet das er das eben NICHT kann.

Bitte nochmal und richtig lesen.
Ich habe geschrieben, dass mein Konstrukt funktioniert (auch der 
zeitkritische Teil) und mir nur unklar ist, wie ich den Umgang im 
Fehlerfall, also die empfohlene doppelte Pufferung, so geschickt 
einbauen kann, dass ich nichts kaputt mache. Der erste (ach so kranke!) 
Gedanke meinerseits war, den SPI-gefüllten Puffer bei Sendeanforderung 
zu kopieren, und genau das ist zeitlich eben nicht drin - wie ich oben 
schrieb.

Thomas

von Thomas P. (topla)


Lesenswert?

Oliver schrieb:
> plus UAR-Interrupt-Reaktionszeit plus UART-Interrupt plus etwas
> "rumgehüpfe drumrum" für die Logik, das wird arg eng.

Kann ich vielleicht etwas nach hinten verlegen, wichtig ist, dass das 
erste Zeichen in der geforderten Zeit kommt.

> Vielleicht kann mna ja auf eine Anfrage des PC's hin mehrfach "ich bin
> da" senden, um sich damit ein paar zusätzliche Zyklen Zeit zu
> verschaffen.

Nein, funktioniert so nicht. Der PC fragt entweder nach Daten oder nach 
dem Lebenszeichen und die Antwort sollte schon passen.

> Wenn das nicht geht, sende halt Dummydaten mit fehlerhafter Prüfsumme ;)

Nette Idee, aber das verschiebt das Problem auch nur nach hinten ;)

Thomas

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.