Forum: Mikrocontroller und Digitale Elektronik CAN Bus: Nachrichten werden nicht verarbeitet


von Haudrauf (Gast)


Lesenswert?

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!

von Peter D. (peda)


Lesenswert?

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.

von Christian G. (christiang)


Lesenswert?

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.

von Haudrauf (Gast)


Lesenswert?

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?

von Thomas F. (igel)


Lesenswert?

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.

von Haudrauf (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von npn (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von npn (Gast)


Lesenswert?

Peter D. schrieb:
> Deiner Compilerinstallation

Meiner? Ich bin nicht der TO. Ich hab nur wiederholt, ws er schrieb...

von Haudrauf (Gast)


Lesenswert?

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.

von Haudrauf (Gast)


Lesenswert?

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.

von Samuel C. (neoexacun)


Lesenswert?

Du könntest die Nachrichten in der ISR auch einfach in einen FIFO 
schieben und dann in der Main-Loop filtern und verarbeiten.

von Haudrauf (Gast)


Lesenswert?

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