Forum: Mikrocontroller und Digitale Elektronik Atmega162, SJA1000, Zeitverzögerung\Verschlucken von Nachrichten


von Meiner (Gast)


Lesenswert?

Hi,

ich hab momentan folgendes Problem: Ich habe grade eine Platine vor mir 
liegen, bei der acht SJA1000 Can-Controller über einen Atmega162 (16 
Mhz) betrieben werden. Zur Programmierung wird die Can-Lib von 
"kreatives-chaos". Das Board ist nicht von mir und wurde wohl schon für 
einige Projekte erfolgreich eingesetzt.

Momentan soll das Board dazu genutzt werden, einfach einen Can-Bus zu 
spiegeln, sprich CAN1 -> CAN2 (100k Baud). Das Problem liegt darin, dass 
bei der zu erwartenden Sequenz von 5-6 Messages (aufgezeichet per Canoe) 
manche Nachrichten mit extremer Zeitverzögerung (oder auch mal gar 
nicht) gespiegelt werden. Mit Canoe kann außerdem beobachtet werden, 
dass die Bus-Auslastung auf CAN2 deutlich kleiner ist als auf CAN1. 
Filtere ich hier nach und nach Nachrichten raus, normalisieren sich die 
Buslasten.

Das Verhalten lässt sich auch über Canoe mit nur einer Nachricht 
erzwingen, indem die Zykluszeit auf geringe Werte (z.B. 10-20ms) gesetzt 
wird.

Der Programmcode besteht dank CAN-Lib eigentlich nur aus der 
Intialisierung der Baudrate, sowie der Abfrage in einer 'while' 
Schleife, ob eine Nachricht auf CAN1 empfangen wurde. Wenn ja, wird die 
Nachricht auf CAN2 gesendet.

Ich komme an dieser Stelle nun nicht so recht weiter. Worin könnte hier 
das Problem liegen? Ist der µC bzw. der Controller irgendwie überlastet? 
Schafft der solche Zykluszeiten nicht? Falls jemand mir helfen kann, 
wäre ich sehr dankbar.

von Peter D. (peda)


Lesenswert?

Meiner schrieb:
> Zur Programmierung wird die Can-Lib von
> "kreatives-chaos".

Du erwartest hoffentlich nicht, daß jemand sich die Lib erst selber 
suchen muß.

Meiner schrieb:
> Worin könnte hier
> das Problem liegen?

Ohne kompletten Source, nicht zu sagen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Meiner schrieb:
> Das Problem liegt darin, dass bei der zu erwartenden Sequenz von 5-6
> Messages (aufgezeichet per Canoe) manche Nachrichten mit extremer
> Zeitverzögerung (oder auch mal gar nicht) gespiegelt werden.
Ich tippe auf Software...

> Ist der µC bzw. der Controller irgendwie überlastet?
Kann sein.

> Schafft der solche Zykluszeiten nicht?
Wenn er ungünstig programmiert ist....

> sowie der Abfrage in einer 'while' Schleife, ob eine Nachricht auf CAN1
> empfangen wurde. Wenn ja, wird die Nachricht auf CAN2 gesendet.
Du solltest die Nachrichten in einem Fifo/Ringpuffer puffern. Was, wenn 
der CAN2 mal einen Fehler hat und das 3. von 16 Telegrammen /wiederholt 
wiederholen/ muss?

von Meiner (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Meiner schrieb:
>> Zur Programmierung wird die Can-Lib von
>> "kreatives-chaos".
>
> Du erwartest hoffentlich nicht, daß jemand sich die Lib erst selber
> suchen muß.
>
> Meiner schrieb:
>> Worin könnte hier
>> das Problem liegen?
>
> Ohne kompletten Source, nicht zu sagen.

Hier der Link: 
http://www.kreatives-chaos.com/artikel/universelle-can-bibliothek . 
Hatte ich vergessen, weil ich bei meiner Recherche hier im Forum auch 
schon öfter drüber gestolpert bin. Hatte angenommen, dass die evtl. 
bekannt ist.


Der Programmcode sieht so aus:
1
#define UCU_CAN CAN1
2
#define HDSG_CAN CAN2
3
4
int main(void) {
5
  can_t sReceivedMessageOnUcuCAN;
6
  can_t sReceivedMessageOnHdsgCAN;
7
  io_init();
8
  cs_init(BITRATE_100_KBPS, UCU_CAN);
9
  cs_init(BITRATE_100_KBPS, HDSG_CAN);
10
  _delay_ms(0); /* no delay after system start*/
11
    
12
  while (1) {
13
    /*------------------------------------------------------------------
14
     *Mirror UCU-CAN on HDSG-CAN
15
     *----------------------------------------------------------------*/
16
    if (cs_get_message(&sReceivedMessageOnUcuCAN, UCU_CAN)) {
17
      if (cs_send_message(&sReceivedMessageOnUcuCAN, HDSG_CAN)) {
18
        // LED an oder sonstiges
19
      }
20
    }
21
  }
22
}

Lothar Miller schrieb:
> Meiner schrieb:
>> Das Problem liegt darin, dass bei der zu erwartenden Sequenz von 5-6
>> Messages (aufgezeichet per Canoe) manche Nachrichten mit extremer
>> Zeitverzögerung (oder auch mal gar nicht) gespiegelt werden.
> Ich tippe auf Software...
>
>> Ist der µC bzw. der Controller irgendwie überlastet?
> Kann sein.
>
>> Schafft der solche Zykluszeiten nicht?
> Wenn er ungünstig programmiert ist....
>
>> sowie der Abfrage in einer 'while' Schleife, ob eine Nachricht auf CAN1
>> empfangen wurde. Wenn ja, wird die Nachricht auf CAN2 gesendet.
> Du solltest die Nachrichten in einem Fifo/Ringpuffer puffern. Was, wenn
> der CAN2 mal einen Fehler hat und das 3. von 16 Telegrammen /wiederholt
> wiederholen/ muss?

Das wird intern (in einem kleinem Wrapper um die CAN-LIB) bereit getan. 
Ein Auszug:
1
/*=============================================================================
2
 * transmit-buffer-array : one buffer for each channel
3
 *============================================================================*/
4
struct Buffer {
5
  can_t data[BUFFER_SIZE]; /*array of can messages*/
6
  uint8_t read; /* link to the oldest message*/
7
  uint8_t write; /* link to an empty field*/
8
} buffer_array[NUMBER_OF_CHANNELS];

und gesendet wird über
1
uint8_t cs_send_message(const can_t *msg, can_controller_id_t controller_id) {
2
    chip_select(controller_id);
3
    if (!can_check_free_buffer()) // TX buffer full
4
    {
5
      if (msg == NULL)
6
        return TRUE; // nothing to send
7
      if (BufferIn(msg, controller_id))
8
        return TRUE; // buffer not full
9
      else
10
        return FALSE;
11
    } else // TX buffer not full
12
    {
13
      can_t *msg_to_send = NULL;
14
15
      if (BufferOut(&msg_to_send, controller_id)) // buffer not empty
16
      {
17
        can_send_message(msg_to_send); // send oldest buffered message
18
        if (msg != NULL)
19
          BufferIn(msg, controller_id); // store new message for later
20
      } else // buffer empty
21
      if (msg != NULL)
22
        can_send_message(msg); // send new message
23
24
      return TRUE;
25
    }
26
}

"BufferIn" schreibt neue Nachrichten in den Buffer, "BufferOut" liefert 
die Älteste und die "chip_select" Funktion schaltet die entsprechenden 
Can-Controller.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Meiner schrieb:
> "BufferIn" schreibt neue Nachrichten in den Buffer
Du schienst da irgendwie die Rückgabewerte gar nicht zu verwenden oder 
auszuwerten:
1
    if (!can_check_free_buffer()) // TX buffer full
2
    {
3
        return TRUE; // nothing to send
4
        :
5
        :
6
        return FALSE;
7
    } else // TX buffer not full

> Der Programmcode besteht dank CAN-Lib eigentlich nur aus der
> Intialisierung der Baudrate, sowie der Abfrage in einer 'while'
> Schleife, ob eine Nachricht auf CAN1 empfangen wurde.
Und der config.h, in der wesentliche Einstellungen vorgenommen werden...

> manche Nachrichten mit extremer Zeitverzögerung (oder auch mal gar
> nicht) gespiegelt werden.
Hast du den Thread dort auch gelesen? Da taucht immer wieder so ein 
Problem mit "verlorenen" Nachrichten auf, z.B. auch am 20. Juli 2011

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.