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