mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Haudrauf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian G. (christiang)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Haudrauf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Thomas F. (igel)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Haudrauf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: npn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: npn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> Deiner Compilerinstallation

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

Autor: Haudrauf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Haudrauf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Samuel C. (neoexacun)
Datum:

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

Autor: Haudrauf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.