Hallo, ich versuche mich am At90Can128 den Can einsatzfähig zu kriegen! Das Senden habe ich soweit hinbekommen. Das heißt die Hardware und die Bautrate stimmt;-) Nun möchte ich mir eine kleine lib schreiben! weiß aber nicht wie ich diese Aufbauen soll! Für das senden der Mobs soll ich mir eine globale Variable anlegen die nach dem Senden von der ISR das frei sein signalisiert? Wie geht das mit dem empfangen? wie macht man das am sinnvollsten? damit keine Pakete verlohren gehen? Ich habe einfach ein grundsätzliches Struktur Problem:-\ Vielen lieben Dank
Schau doch einfach mal wie es andere machen: http://www.kreatives-chaos.com/artikel/universelle-can-bibliothek bzw. https://github.com/dergraaf/avr-can-lib
Noch was zum lesen: http://www.avrfreaks.net/forum/tut-using-8-bit-avr-controller-area-network-can-register
Würde es aber gern selber richtig machen ohne lib von anderen! Ist denke ich eine gute Übung!!! Danke werde es mir durchlesen!
am grundsätzlichstem schrieb: > Würde es aber gern selber richtig machen ohne lib von anderen! > Ist denke ich eine gute Übung!!! !!! Dann kopier die Lib halt nicht sonder schau Dir die Sourcen an und versuch sie zu verstehen !!!
Also kann man es nur so machen wie in der Lib? Oder gibt es auch andere Wege? Um etwas licht im Konzeptbau wäre ich Dankbar! Lg und Danke
am grundsätzlichstem schrieb: > Also kann man es nur so machen wie in der Lib? Es gibt niemals nur einen Weg. Aber in den Sources der Bibliothek kannst du dich mit den Funktionsprinzipien vertraut machen. Wenn du es dann verstanden hast, kannst du es auch selbst implementieren in einer Art und Weise, die dir zusagt.
So als Idee: struct _tData { char data[8]; uint32 canId; uint msgLen; //0 for RTR }tData; typedef int (*tRxCallback)(int, *tData); Can_SetBaudrate(uint32 Baudrate, bool elfBitOr29Bit); Can_ConfigureTxMob(int mobIdx); Can_ConfigureRxMob(int mobIdx, uint32 acceptanceMask, tRxCallback* pFunc); int Can_GetErrorCount(); Can_StartRx(); Can_StopRx(); Can_Send(int mobIdx, tData* txData); Can_Reset(); Du müsstes halt noch überlegen, ob du zum Bearbeiten der empfangenen Daten kurz den Empfangsinterrupt sperren willst oder einen Ringbuffer einrichtest oder ob du einfach zyklisch abfragst - Frage der Anforderungen und des Designs...
Guido schrieb: > uint msgLen; //0 for RTR Man kann auch Datentelegramme mit Länge 0 senden. Wird z.B. bei CANopen für das Sync-Telegramm genutzt. Dann schon eher eines der oberen Bits als RTR Flag nutzen. Desweiteren mußt du zu allererst festlegen, welches Detailwissen die darüberliegende Applikation haben soll. Bei dir ist die Applikation für die Aufteilung der MOBs zuständig. Kann man so machen oder aber auch verbergen. Hier konfigurierst du etwas: Can_ConfigureTxMob(int mobIdx); Hier Can_Send(int mobIdx, tData* txData); aber den Rest. Ich würde entweder bei Can_Send() alles machen oder bei deiner Aufteilung in Can_ConfigureTxMob() alles außer den eigentlichen Daten. Kommt auf deinen Anwendungsfall an. Die Baudrate Can_SetBaudrate() hat keinen bezug zu Base Frames (11 bit) oder Extended Frames (29 Bit). Willst Du das global einstellen, würde ich eine Init() Funktion erstellen. Normalerweise kann man aber beide Typen gemischt einsetzen, auch wenn es nicht so empfohlen wird. CANopen nutzt für zusätzliche Flags die Bits 29..31 in der 32Bit CAN-ID Variablen.
Steffen R. schrieb: > Man kann auch Datentelegramme mit Länge 0 senden stimmt, war mir entfallen, er braucht also auch ein RTR Flag >Baudrate Can_SetBaudrate() hat keinen bezug zu Base Frames (11 bit) >oder Extended Frames (29 Bit) ja das stimmt auch. Aber manche Controller können nur 29 oder 11bit senden aber beides empfangen. So einen hatte ich vor Augen, als ich die Funktion aufgeschrieben hatte. Aber ein Can_Init wäre da besser, stimmt schon. ...war ja auch nur so eingetippt, als Denkanstoss für den Kollegen ;) >Hier konfigurierst du etwas: >Can_ConfigureTxMob(int mobIdx); > >Hier >Can_Send(int mobIdx, tData* txData); >aber den Rest. Mit Can_ConfigureTxMob konfigueriert man ein Mob als Tx-Objekt, mit modIdx sagt man welches. Mit Can_Send sagt man, was man auf welchem Mob senden will finde ich erstmal nicht anstössig. Es gibt ja auch mehrere Wege, die zum Ziel führen... >Desweiteren mußt du zu allererst festlegen, welches Detailwissen die >darüberliegende Applikation haben soll. Ich tendiere immer dazu, erstmal die Hardware abzubilden. Mehr wollte ich mit meinem Denkanstoss erstmal nicht bezwecken. Man kann ja immer nochmal eine Schicht drüber zu legen, die noch mehr und weiter abstrahiert.
Danke für die Anregung! Ich bin aber glaube ich noch auf einen niedrigen Niveau! Weiß einfach nicht wie ich das empfangen handeln soll damit ich Keine Botschaft verliere! Danke
aus meiner Sicht gibt es 2 Konzepte, die erwähnenswert sind: 1. asynchon "multi-threaded" Empfangs-Interrupt: Botschaften auslesen und in einen Ringbuffer stellen. Dein Hauptprogramm liest den Ringbuffer aus und bearbeitet die Daten. Beide Programmteile können unsynchonisiert nebeneinander laufen 2. Echtzeit Du kannst dir auch einen 5ms Timer mmachen. Wenn der das 1. mal abläuft, liest du die empfangenen Botschaften aus und startest ihn neu. Wenn er das 2. mal abläuft bearbeitest du die zuvor ausgelesenen Daten. Also immer Auslesen-Bearbeiten-Auslesen-Bearbeiten usw Auch hier muss man nichts synchronisieren. Es gibt noch andere Möglichkeiten, aber die finde ich irrelevant. Nimm dir mal irgend ein Beispiel und versuche nachzuvollziehen, wie die es gemacht haben. In welchem Zyklus kommen denn deine Botschaften??
Guido schrieb: > aus meiner Sicht gibt es 2 Konzepte, die erwähnenswert sind: > > 1. asynchon "multi-threaded" > Empfangs-Interrupt: Botschaften auslesen und in einen Ringbuffer > stellen. > Dein Hauptprogramm liest den Ringbuffer aus und bearbeitet die Daten. > Beide Programmteile können unsynchonisiert nebeneinander laufen > > 2. Echtzeit > Du kannst dir auch einen 5ms Timer mmachen. Wenn der das 1. mal abläuft, > liest du die empfangenen Botschaften aus und startest ihn neu. > Wenn er das 2. mal abläuft bearbeitest du die zuvor ausgelesenen > Daten. Also immer Auslesen-Bearbeiten-Auslesen-Bearbeiten usw > Auch hier muss man nichts synchronisieren. > > Es gibt noch andere Möglichkeiten, aber die finde ich irrelevant. > Nimm dir mal irgend ein Beispiel und versuche nachzuvollziehen, > wie die es gemacht haben. > > In welchem Zyklus kommen denn deine Botschaften?? Finde die erste Variante am Besten! Wie macht man sowas? Die Botschaften kommen im 10ms Takt. Danke
am grundsätzlichstem schrieb: > Finde die erste Variante am Besten! > Wie macht man sowas? Besorg dir eine Ringbuffer-Implementierung oder schreib selbst eine. Lies ggf ein Buch dazu. Dann probier deinen Ringbuffer aus -erstmal ohne CAN. Wenn es funktioniert, lies CAN-Daten im Interrupt aus und schreib sie in den Ringbuffer. Tip: Schreib den Ringbuffer so, dass du beliebige Datenstrukturen dort reinschreiben und die Implementierung so wiederverwenden kannst.
am grundsätzlichstem schrieb: > Die Botschaften kommen im 10ms Takt. Musst du auch in einem bestimmten Intervall senden?
Peter schrieb: > Musst du auch in einem bestimmten Intervall senden? Ja auch das sollte in 10ms Takt passieren. Habe jetzt etwas mit den Interrupt gespielt und es scheint zu klappen!
am grundsätzlichstem schrieb: > Ja auch das sollte in 10ms Takt passieren. Geht es um ein Datenprotokoll oder um einfache Werte (Messwerte, Zustände etc) die du vom Bus lesen willst?
Guido schrieb: > Geht es um ein Datenprotokoll oder um einfache Werte (Messwerte, > Zustände etc) die du vom Bus lesen willst? Es geht um Messwerte usw. Lg
am grundsätzlichstem schrieb: > Ja auch das sollte in 10ms Takt passieren. ... > Es geht um Messwerte usw. dann ist aus meiner Sicht die Variante mit dem 5ms Timerinterrupt passender.
Guido schrieb: >>Baudrate Can_SetBaudrate() hat keinen bezug zu Base Frames (11 bit) >>oder Extended Frames (29 Bit) > ja das stimmt auch. Aber manche Controller können nur 29 oder 11bit > senden aber beides empfangen. Ich wüßte keinen, der diese Hardwarebeschränkung hat. Nur einige APIs und Protokolle beschränken das Format. Falls du allerdings ein Beispiel hast, wäre ich interessiert. Guido schrieb: > Es gibt ja auch mehrere Wege, die zum Ziel führen... Natürlich. Daher diese Unterhaltung hier. ;-) Um den passenden Weg zu wählen, müßte man aber schon vorher ein grobes Konzept haben. Und dieses wirkt sich nach meinem Verständnis auch bereits auf die unterste Schicht aus. Guido schrieb: > Ich tendiere immer dazu, erstmal die Hardware abzubilden. Guido schrieb: > Man kann ja immer nochmal eine Schicht drüber zu legen, die noch mehr > und weiter abstrahiert. Ja klar. Dann würde ich die unterste Schicht aber spezieller an den jeweiligen CAN Controller anpassen und mit der Verallgemeinerung in der höheren Schicht beginnen. OK, da du auf MOB's referenzierts, geht dein Vorschlag auch in diese Richtung. am grundsätzlichstem schrieb: > Weiß einfach nicht wie ich das empfangen handeln soll damit ich Keine > Botschaft verliere! Per Interrupt und eine Softwarequeue, sofern du den RAM hast. Polling Betrieb in welcher Form auch immer macht schnell mal bei Bursts Probleme. Solltest Du jedoch RAM sparen wollen und daher die Nachrichten solange wie möglich im CAN Controller puffern wollen, kalkuliere das Timing mit 0-Byte Nachrichten. Das Konzept würde ich aber nur ins Auge fassen, wenn du ein MOB pro CAN ID nutzt und der Zyklus kalkulierbar ist. Wir nutzen eher Eventbasierende Kommunikation. Da kann man schnell reagieren ohne den Bus zyklisch zu belasten. Aber man muss mit der kürzestmöglichen Zeit rechnen. Thema zyklisch senden: Überlege, was du im Fehlerfall machen willst. Evtl. benötgst du low level einen Sendenabbruch, um die Sendenachricht zu erneuern.
Habe das WE über etwas rum probiert. Habe folgendes gemacht und möchte von Euch Profis die meinung hören! Also habe 2 empfangs-MOB definiert und den Filter so eingestellt das jeweils 3 Id durch kommen. Dazu habe ich mir ein globales Botschaften Array angelegt. Dazu 6 globale Bit. Wenn nun mein Empfangsinterrupt kommt sortiere ich in der ISR die daten ein und setzte mein Globales Empfangsbit. In der Main erkenne ich das und mache mit den Daten was. Im Timerinterrupt schubse ich das Senden meiner Nachrichten an. Was sagt ihr dazu? Völliger Mist? Akzeptabel? Oder? Vielen Dank Für Eure Hilfe
Ich möchte dir nicht zusehr in deine Entwicklung hineinreden. Wie Guido so schön schrieb, es gibt immer mehrere Wege. Daher nur punktuell Hinweise zu deinem Konzept. am grundsätzlichstem schrieb: > Wenn nun mein Empfangsinterrupt kommt sortiere ich in der ISR die daten > ein und setzte mein Globales Empfangsbit. Denke über das Szenario nach, dass die Nachricht erneut eintrifft, während du die alte im Hauptprogramm auswertest. am grundsätzlichstem schrieb: > Im Timerinterrupt schubse ich das Senden meiner Nachrichten an. Ich würde im Timerinterrupt nur eine Info für das Hauptprogramm setzen und dort senden. Deinen Weg würde ich nur ins Auge fassen, wenn du eine hohe Genauigkeit deiner Zykluszeit benötigst.
Steffen R. schrieb: > am grundsätzlichstem schrieb: >> Wenn nun mein Empfangsinterrupt kommt sortiere ich in der ISR die daten >> ein und setzte mein Globales Empfangsbit. > > Denke über das Szenario nach, dass die Nachricht erneut eintrifft, > während du die alte im Hauptprogramm auswertest. Deine Bedenken kann ich bei viel Daten nachvollziehen. Aber das Hauptprogramm sollte aus meiner Sicht doch nie länger als 10ms brauchen oder? Würde das Problem dann nicht auch mit einer FIFO auftreten? Was würdest du anders machen? Steffen R. schrieb: > Ich würde im Timerinterrupt nur eine Info für das Hauptprogramm setzen > und dort senden. Deinen Weg würde ich nur ins Auge fassen, wenn du eine > hohe Genauigkeit deiner Zykluszeit benötigst. Ja macht Sinn fand aber das das anschupsen deiner Nachricht relativ zackig geht! Ist dies nicht der Fall? Entschuldige das ich Dumm frage aber bin kein Profi! Was ich bis jetzt gesehen hae ist der CAN wirklich GEIL!!! Lg
am grundsätzlichstem schrieb: > Steffen R. schrieb: >> am grundsätzlichstem schrieb: >>> Wenn nun mein Empfangsinterrupt kommt sortiere ich in der ISR die daten >>> ein und setzte mein Globales Empfangsbit. >> >> Denke über das Szenario nach, dass die Nachricht erneut eintrifft, >> während du die alte im Hauptprogramm auswertest. > > Deine Bedenken kann ich bei viel Daten nachvollziehen. Aber das > Hauptprogramm sollte aus meiner Sicht doch nie länger als 10ms brauchen > oder? Das kannst nur Du wissen und auch wie häufig die jeweiligen Nachrichten eintreffen. Dein Konzept scheint darauf zu beruhen, dass die Nachrichten einen bestimmten Mindestabstand haben. In diesem Punkt möchte ich dir nicht hineinreden. > Würde das Problem dann nicht auch mit einer FIFO auftreten? Wenn die Fifo noch Platz hat, würde die Nachricht hinten angehangen, während du die erste bearbeitest. > Was würdest du anders machen? Ich möchte dich nur darauf aufmerksam machen, damit du darüber nachdenken kannst, ob du das Problem bedacht hast und welche Maßnahmen du ergreifst. Manchmal kann es ja wirklich sein, dass eine solche Analyse ergibt, das ein Problem akzeptabel ist. > Steffen R. schrieb: >> Ich würde im Timerinterrupt nur eine Info für das Hauptprogramm setzen >> und dort senden. Deinen Weg würde ich nur ins Auge fassen, wenn du eine >> hohe Genauigkeit deiner Zykluszeit benötigst. > > Ja macht Sinn fand aber das das anschupsen deiner Nachricht relativ > zackig geht! Ist dies nicht der Fall? Ja, du bist aber recht unflexibel. Vielleicht willst Du später auch zwischendurch senden oder du must auf das Problem reagieren, dass eine Nachricht verzögert gesendet wird.
Hallo, zu den Fragen: >Deine Bedenken kann ich bei viel Daten nachvollziehen. Aber das >Hauptprogramm sollte aus meiner Sicht doch nie länger als 10ms brauchen >oder? Der Interrupt kommt asynchon. Wenn du das nicht berücksichtigst, kommt dein Programm früher oder später durcheinander, weil es irgendwann, wenn dein Programm lange läuft, dazu kommen wird, dass der Interrupt gerade die Daten erneuert, während dein Hauptprogramm sie liest. Wenn du bei dem Interrupt-Konzept bleibst, musst du: - entweder einen Fifo nehmen - oder kurz die Interrupts kurz(!) sperren während dein Hauptprogramm Daten liest. Der Fifo ist m.E. zu bevorzugen. >Würde das Problem dann nicht auch mit einer FIFO auftreten? >Was würdest du anders machen? Das kommt auf die Fifo-Implementierung an. Ein ordentlicher Fifo hat einen Schreibpointer (der wird vom Interrupt angefasst) und einen Lesepointer (der wird von deinem Hauptprogramm angefasst). Der Zugriff auf beide Pointer ist atomar, sofern sie nicht als double deklariert sind. Somit wäre der Fifo Interrupt-safe. Du hattest ja geschrieben, dass du im 10ms Zyklus senden musst. Daher (und weil du unerfahren bist) habe ich dir geraten, einen 5ms Timer zu nehmen und um jew. 5ms versetzt: Auslesen Bearbeiten, Senden Auslesen Bearbeiten, Senden ... Damit hast du das Echtzeit-Thema (10ms Senderaster) und das Synchronisierungsproblem erschlagen. Wenn das dann läuft, kannst du dich ja dran machen und das ganze auf Interrupt/Fifo umstellen. @Steffen Rose: >Per Interrupt und eine Softwarequeue [...] Eine Queue ist hier m.E. nicht sinnvoll, da beim Anhängen und Lesen die Zeiger auf das vorherige und das nächste Element manipuliert werden müssen. Das ist nicht atomar und daher nicht Interrupt-safe. Aus meiner Sicht müsste er schon einen Fifo nehmen.
Guido schrieb: > Ein ordentlicher Fifo hat > einen > Schreibpointer (der wird vom Interrupt angefasst) und einen Lesepointer > (der wird von deinem Hauptprogramm angefasst). Der Zugriff auf beide > Pointer ist atomar, sofern sie nicht als double deklariert sind. > Somit wäre der Fifo Interrupt-safe. Gibt es so eine Fifo schon gekocht? Danke LG
Hallo ich nochmal;-) Sorry das ich schon wieder lästig bin! Was ist von der Option "Automatic reply" zu halten? Ist die Option Ressourcen sparend? Ich habe nicht genau verstanden wie diese Option arbeitet! Werden die Empfangenen Daten normal ausgelesen und die Antwort erfolgt dann über den selben Mob oder wird für das senden ein eigener Mob verwendet? Lg Und Danke
fifo schrieb: > http://www.mikrocontroller.net/articles/FIFO#FIFO_als_Bibliothek leider passt dieser Fifo nicht so recht auf sein Problem. Das hier ist nämlich ein Byte-Fifo. Er wird aber einen Fifo brauchen, der einen CAN-Frame + CANID + Längeninfo + RTR Flag aufnehmen kann. Er braucht einen Fifo, dem man eine Anzahl von Bytes am Stück übergeben kann. Etwa so: bool ringbufferWrite(RINGBUF_OBBJ pRingbuffer, char* pData, int writeLen); bool ringbufferRead(RINGBUF_OBJ pRingbuffer, int desiredReadLen, char* pData); pData müsste auf ein Object struct _tData { char data[8]; uint32 canId; uint msgLen; bool rtr; }tData; zeigen. Somit kann er seine empfangenen CAN-Daten inkl. der relevanten Zusatzinformationen am Stück in den Ringbuffer kopieren (im Interrupt) und wieder rausholen (Haupt-Programm). ...wäre zumindest meine Meinung.
am grundsätzlichstem schrieb: > Ich habe nicht genau verstanden wie diese Option arbeitet! Ich will dir nicht zu nahe treten, aber das steht in der Spec. Hast du diese denn nicht vorliegen?
Guido schrieb: > Ich will dir nicht zu nahe treten, aber das steht in der Spec. > Hast du diese denn nicht vorliegen? Ich habe Datenblatt hier vor mir liegen, habe daraus die Automatic reply Funktion raus gelesen aber nicht verstanden wie sie arbeitet:-\ Dachte es könnte mir jemand in klaren verständlichen Worten sagen:-) Danke!
in 19.5.2.4 Automatic Reply steht in etwa folgendes: Wenn du ein RTR empfängst, wird das dafür zuständige MOB automatisch einen CAN Frame rausschicken. RTR=1 RPLV=1 CAN-ID Maske Tx-Mode und dann sollte es gehen. Du bekommst einen Tx-Interrupt wenns funktioniert hat und kannst das MOB wieder aufziehen (RPLV=1). Falls du aber mit dem Gedanken spielst, deinen 10ms Sendetakt durch die 10ms Empfangsbotschaft Triggern zu lassen, musst du genau wissen, was du tust, weil du das Senden der von dir berechneten Daten um 10ms verzögerst.
Guido schrieb: > Falls du aber mit dem Gedanken spielst, deinen 10ms Sendetakt > durch die 10ms Empfangsbotschaft Triggern zu lassen, musst du genau > wissen, was du tust, weil du das Senden der von dir berechneten > Daten um 10ms verzögerst. Ja das war der Hintergedanke. Sorry da blicke ich nicht durch, warum verzögere ich damit die Daten? Bitte erklär mir das? Vielen herzlichen Dank!!
Du verzögerst nicht zwangsläufig (da muss ich meine Aussage korrigieren). Es wäre aber möglich, je nachdem wie du dein Programm aufbaust. Die jeweils passende und einleuchtende Erklärung kann man nur geben, wenn man diesen Aufbau kennt. Empfange im Interrupt in einen Ringbuffer. Lass dein Hauptprogramm in einer 10ms Schleife laufen und dort dann folgende Abfolge: 1. empfangene Daten aus Ringbuffer lesen (älteste Daten verwerfen) 2. Aufbereiten, prüfen was auch immer... 3. Ausgabe berechnen 4. Senden So stellst du sicher, dass du mit den aktuellsten Daten rechnest und die daraus berechneten Ergebnisse auch schnellst möglich raussendest und zwar im geforderten 10ms Raster. Ausserdem war ja die Anforderung an dich, im 10ms Raster zu senden. Das was du vor hast, sendet nur dann im 10ms Raster, wenn auch die Gegenstelle im 10ms Raster sendet. Wenn die ausfällt musst du ggf. Defaultwerte oder anderweitig synthetisierte Werte senden - keine Ahnung... Ggf musst du pro Rx-Frame auch noch einen Zeitstempel haben, um zu wissen, ob die empfangenen Daten älter als bspw. 20ms sind - dann hat die Gegenstelle ein Problem und du musst ggf. darauf reagieren?!?
am grundsätzlichstem schrieb: > Ja das war der Hintergedanke. Überlege Dir, ob du wirklich Remote Frames nutzen willst. Dass passt aus meiner Sicht nicht so ganz in dein Konzept des zyklischen Sendens. am grundsätzlichstem schrieb: > warum > verzögere ich damit die Daten? Du solltest nicht verschiedene Stellen zum Beschreiben des CAN Controllers haben. Da kann man ganz schnell Probleme bekommen, wenn man die Zugriffe nicht ordentlich verriegelt. Dein Ansatz is das Beschreiben im 10ms Interrupt. Somit kannst Du erst dort das MOB, welches auf das RTR reagiert, mit neuen Daten füllen oder, wenn nicht automatisch geantwortet werden soll, die Antwort auf den Remote Request (RTR) senden. Im Worst case empfängst du die RTR Nachricht kurz nach dem Timer Interrupt. Bis zum nächsten vergehen dann 10ms. zu der Fifo: Die von mir gefundenen allgemeinen Implementierungen bieten so viel Funktionalität, dass man schon wieder aufpassen muss, dass man Interrupt safe bleibt. Ohne dem müßte man sonst einen Lock Mechanismus einführen. Guido hat das oben bereits beschrieben. Soll heißen, ich lese mit. Auf manches hat man aber auch mal keine Antwort.
Steffen R. schrieb: > zu der Fifo: > Die von mir gefundenen allgemeinen Implementierungen bieten so viel > Funktionalität, dass man schon wieder aufpassen muss, dass man Interrupt > safe bleibt. Ohne dem müßte man sonst einen Lock Mechanismus einführen. Auch allgemeine Fifo Implementierungen folgen dem Konzept, dass der Schreiber den Lesepointer anfasst und der Leser den Lesepointer. Du hast vermutl. tatsächlich eine Listenimplementierung o.ä. gefunden. an den TO: Willst du einen 10ms RTR aufsetzen (quasi als Takt), dann andere CAN Daten einlesen und daraus Sendedaten berechnen? Also ich rate, aber erklär doch mal, was du da genau vorhast und welche Programmstruktur dir vorschwebt...
Guido schrieb: > Schreiber den Lesepointer anfasst und der Leser den Lesepointer. Das meinst du bestimmt nicht so, oder? :-)
Guido schrieb: > fifo schrieb: >> http://www.mikrocontroller.net/articles/FIFO#FIFO_als_Bibliothek > > leider passt dieser Fifo nicht so recht auf sein Problem. > Das hier ist nämlich ein Byte-Fifo. Er wird aber einen Fifo > brauchen, der einen CAN-Frame + CANID + Längeninfo + RTR Flag > aufnehmen kann. Könnte er nicht je ein fifo für Längeninfo, CAN-Frame, CAN ID in 4x8Bit und ein RTR Flag anlegen... Dabei müsste man dann bei der Längeninfo ein, bei den CAN-Frame die jeweilige Anzahl, bei der ID 4 Byte usw. abfragen...
Erwin D. schrieb: > Guido schrieb: >> Schreiber den Lesepointer anfasst und der Leser den Lesepointer. > > Das meinst du bestimmt nicht so, oder? :-) Huch ;) ..der Schreiber den Schreibpointer anfasst und der Leser den Lesepointer
fifo schrieb: > Könnte er nicht je ein fifo für Längeninfo, CAN-Frame, CAN ID in 4x8Bit > und ein RTR Flag anlegen... Dabei müsste man dann bei der Längeninfo > ein, bei den CAN-Frame die jeweilige Anzahl, bei der ID 4 Byte usw. > abfragen... Nein. Das wird inkonstent, wenn die Fifos voll sind, der Leser aber bspw. den "Längenfifo" lesen konnte, dann ein Rx-Interrupt kommt, der Längenfifo einen Platz frei hat, aber die anderen Fifos noch nicht. Das wird doch inkonsistent, ausser man fragt im Interrupt ab, ob alle 4 Fifos genug Platz haben. Das finde ich aber nicht schön. Ausserdem ist die Lösung doch denkbar einfach und robust: Er macht sich einen Fifo, in dem er die CAN-Datenstruktur komplett reinschreiben kann und fertig ist die Sache. Die von dir genannte Implementierung könnte er auch umschreiben, sodass der Fifo generisch ist und beliebige Objekte aufnehmen kann.
Mach mal ein Beispiel bei dem es zu Problemen führt. Ich denke es sollte ohne Probleme klappen
fifo schrieb: > Mach mal ein Beispiel bei dem es zu Problemen führt. Ich denke es > sollte > ohne Probleme klappen Ich hatte oben doch ein Beispiel mitgeliefert. Für meine Begriffe stellt das den kritischen Fall dar. Die Multi-Fifo-Lösung finde ich (ohne dir zu nahe treten zu wollen) nicht gut. Habe ich auch noch nirgendwo so gesehen. Zusammengehörende Informationen sollten zu einem Objekt zusammengefasst werden. Dieses Objekt sollte dann in den Fifo geschrieben werden ...meiner unbedeutenden Meinung nach.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.