Guten Morgen allerseits, ich habe folgendes Problem: Zwei Geräte tauschen über einen CAN Bus Nachrichten aus. Wenn eine Nachricht in die Mailbox geschrieben wird, dann wird in einer ISR ein Flag gesetzt, dass eine neue Nachricht vorliegt. In einer Sequenz aus If-Abfragen in meiner Main-Loop wird dieses Flag abgefragt und wenn es TRUE ist, werden die Nachrichten auf ID und Inhalt gefiltert und der weiteren Verarbeitung zugeführt. Danach wird das Flag zurückgesetzt. Wenn ich die Nachrichten einzeln versende, funktioniert das tadellos. Wenn aber zyklisch, sagen wir alle 100 ms eine Nachricht versendet wird und noch zusätzliche Nachrichten versendet werden, kommt es oft zu dem Problem, dass die zweite Nachricht die erste Nachricht im Empfänger überschreibt, bevor sie verarbeitet werden kann. Dann gibt es zwei möglichkeiten: die erste ist, dass die erste Nachricht einfach nicht erkannt wird, weil mein Programm langsamer ist, als die Mailbox die Daten empfängt. Dann erhalte ich zunächst nicht unbedingt eine Fehlermeldung, die Nachricht kommt aber nicht in der IF-Abfrage an. Die zweite Möglichkeit ist, dass ich den Error-code "SSP_ERR_CAN_DATA_UNAVAILABLE" erhalte. Das führt dann zum Abbruch der Verbindung. Der Sender wird danach seine Nachricht nicht mehr los, was wiederum zum Bus overload führt. Kurz zu meinem verwendeten System: Renesas Synergy S124 und S3A7. Ich bin mir sicher, dass die Art und Weise, wie ich die Kommunikation aufgebaut habe, sehr rudimentär ist und deshalb die Fehler auftreten. Woanders funktioniert es ja auch. Allerdings ist es so, dass ich es schwierig finde, genau zu diesem Thema brauchbare, respektive verständliche, Informationen zu erhalten, wie eine Kommunikation über CAN aufgebaut sein muss, damit dieses Problem nicht auftritt. Schließlich mache ich mir so sämtliche Vorteile des CAN busses zunichte. CAN-OPEN wäre natürlich eine Alternative, aber es muss ja auch anders, also zu Fuß, gehen. Ich bin mir sicher, dass hier der eine oder andere Experte ist, der mir auf den richtigen Weg helfen kann. Vielen Dank!
Haudrauf schrieb: > kommt es oft zu dem > Problem, dass die zweite Nachricht die erste Nachricht im Empfänger > überschreibt, bevor sie verarbeitet werden kann. Du darfst einen Puffer natürlich nicht freigeben, bevor er verarbeitet wurde. In der Regel haben CAN-Controller mehrere Puffer, d.h. Nachrichten landen automatisch im nächsten freien. Man kann aber auch eine FIFO im RAM einrichten und die Nachrichten per Interrupt oder DMA dort ablegen.
Normalereise besitzt die Hardwareeinheit deines CAN Controllers mehrere Empfangspuffer, meist 3-5. Bei Full CAN sind dann auch mal z.B. 32, diese werden dann meist als Mailboxen verwendet, d.h. in jede Empfangsbox wandert nur eine Nachricht mit einer passenden (konfigurierten) ID. Gehen wir mal davon aus, dass du dieses Feature nicht benutzt, dann würde ich so vorgehen: Nachricht empfangen, Flag des belegten Puffers setzen und in der Hauptschleife alle sagen wir mal 10ms (hängt von dem ab, was auf dem Bus los ist und wie hoch deine Baudrate ist) vorbei kommen und ALLE belegten Puffer abarbeiten und wieder freigeben.
Christian G. schrieb: > Normalereise besitzt die Hardwareeinheit deines CAN Controllers mehrere > Empfangspuffer, meist 3-5. Bei Full CAN sind dann auch mal z.B. 32, > diese werden dann meist als Mailboxen verwendet, d.h. in jede > Empfangsbox wandert nur eine Nachricht mit einer passenden > (konfigurierten) ID. Ja, bei mir sind es 32 Mailboxen. Davon benutze ich eine zum Senden, eine zum Empfangen. D.h. die Mailbox kann genau eine Nachricht speichern. Mir ist nicht bekannt, wie ich das anders konfigurieren könnte. Christian G. schrieb: > Nachricht empfangen, Flag des belegten Puffers setzen und in der > Hauptschleife alle sagen wir mal 10ms (hängt von dem ab, was auf dem Bus > los ist und wie hoch deine Baudrate ist) vorbei kommen und ALLE belegten > Puffer abarbeiten und wieder freigeben. Meine Baudrate ist auf 500kbit/s eingestellt. Wie kann ich der Mailbox denn mitteilen, dass sie nicht empfangen darf? Der Sinn folgndr Einstellung ist mir auch noch etwas schleierhaft: overwrite mode und overrun mode. Wann ist was auszuwählen?
Haudrauf schrieb: > Ja, bei mir sind es 32 Mailboxen. Davon benutze ich eine zum Senden, > eine zum Empfangen. Der S124 besitzt ja sogar einen Hardware-FIFO-Mode für 24 Botschaften. Da kann man fast nix mehr verpassen. > Mir ist nicht bekannt, wie ich das anders konfigurieren könnte. Das sollte dein Framework oder Beispielcode aber sagen.
Thomas F. schrieb: > Der S124 besitzt ja sogar einen Hardware-FIFO-Mode für 24 Botschaften Ja, den habe ich im Manual auch gesehen. Ich verstehe allerdings nicht, wie ich an das Register komme, um es zu Ändern. Thomas F. schrieb: > Das sollte dein Framework oder Beispielcode aber sagen. Genau das tut er leider nicht, ein CAN Framework gibt es nicht, nur einen driver. Ich hätte mir davon auch mehr erhofft.
Haudrauf schrieb: > Mir ist nicht bekannt, wie ich das anders konfigurieren > könnte. Das sollte im Manual Deiner CPU aber beschrieben sein. Falls Dein Framework keine entsprechenden Funktionen bereit stellt, kann man auch einfach die IO-Register direkt ansprechen.
Peter D. schrieb: > kann man auch einfach die IO-Register direkt ansprechen. Dafür muss man aber wissen, wie... Haudrauf schrieb: > Ich verstehe allerdings nicht, > wie ich an das Register komme, um es zu Ändern.
npn schrieb: > Dafür muss man aber wissen, wie... Im Example-Ordner Deiner Compilerinstallation sollten Beispiele zu finden sein. Die IO-Register und Bits heißen in der Regel genau so, wie im Datenblatt. Und mit #include<io.h> sollten sie dem Compiler bekannt sein.
Peter D. schrieb: > Deiner Compilerinstallation Meiner? Ich bin nicht der TO. Ich hab nur wiederholt, ws er schrieb...
Peter D. schrieb: > Die IO-Register und Bits heißen in der Regel genau so, wie > im Datenblatt. > Und mit #include<io.h> sollten sie dem Compiler bekannt sein. Ja, in der S124.h sind die Register tatsächlich enthalten. Leider stehe ich gerade auf dem Schlauch, wenn es darum geht, die entsprechenden bits im Register zu setzen/zurückzusetzen. Ich finde nirgends eine Erklärung, nach welchem Muster derartige Funktionsaufrufe aufgebaut sein müssen.
Nun, ich habe nochmal ein bisschen experimentiert und bin zu dem Schluss gekommen, dass das Beispiel von Renesas offensichtlich in keiner Weise praxistauglich ist. Ich habe die Routinen zur Filterung der Nachrichten jetzt direkt in die ISR eingebaut. Jetzt gehen erstmal keine Nachrichten verloren. Die Frage ist nur, wie weit man bei der Bearbeitung der Nachrichten innerhalb der ISR gehen darf, ohne deren Ausführungszeit unzulässig zu verlängern.
Du könntest die Nachrichten in der ISR auch einfach in einen FIFO schieben und dann in der Main-Loop filtern und verarbeiten.
Wäre es auch denkbar, wenn ich mit ThreadX arbeite, die Nachrichten in eine Message Queue zu schreiben und diese in einem anderen Thread zu verarbeiten? Ich habe wenig Erfahrung in der Programmierung mit mehreren Threads gleichzeitig. Der Vorteil wäre, dass ich die Größe der Warteschlange einstellen kann. Ob es unter dem Strich aber ein Vorteil ist, weiß ich nicht, da jeder Thread auch wieder einzeln durchlaufen werden muss. Allerdings kann ein kurzzeitiges höheres Nachrichtenaufkommen vielleicht kompensiert werden. Hm...
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.