Forum: Mikrocontroller und Digitale Elektronik UC3C Problem mit 2. CAN-Kanal


von Dionysos 3. (dionysos328)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche gerade, beide CAN-Kanäle eines UC3C parallel in Betrieb zu 
nehmen.

Ich habe jeden Kanal einzeln betrieben können.
Nun versuche ich aber beide Kanäle parallel zu initialisieren und 
zunächst nur mit Kanal zwei zu Empfangen und zu Senden.

Auf eine Empfangene Nachricht soll das Programm mit einer gesendeten 
Nachricht antworten.

Das Problem ist jetzt, dass nur genau 16 Nachrichten von dem Programm 
gesendet werden, danach reagiert es nicht mehr.

Es kommt aber zu keinem ACK-Fehler, d.h. empfangen werden die weiteren 
Nachrichten vermutlich, nur verarbeitet werden Sie nicht

Hat jemand eine Idee, die mir auf die Sprünge helfen kann?

Grüße,
dionysos

von Dionysos 3. (dionysos328)


Angehängte Dateien:

Lesenswert?

ich stehe immernoch auf dem Schlauch.

Scheinen hier aber nicht viele Leute zu sein, die sich mit AVR32 
auskennen?!

Mittlerweile kann ich auf zwei Kanälen Senden um Empfangen, aber jeweils 
nur 16 Nachrichten.

Ich vermute, dass irgendein Speicher wieder freigegeben werden muss um 
weitere Nachrichten senden zu können.

von Dionysos 3. (dionysos328)


Lesenswert?

ich meine, das Problem liegt in meiner falschen Verwendung der Funktion 
"can_out_callback_channel" bzw. daran, dass ich nur den Fall des 
Empfangens abdecke.

In einem anderen Beispiel sieht die Funktion nämlich so aus:


void can_out_callback_channel0(U8 handle, U8 event)
{
  // Reception of Wakeup frame
  if (handle == NO_MOB)
  {
    // Disable Wake-Up Mode
    CANIF_disable_wakeup(CAN_CHANNEL_EXAMPLE);
    // Clear Interrupt Flag
    CANIF_clr_interrupt_status(CAN_CHANNEL_EXAMPLE);
    gpio_clr_gpio_pin(LED0_GPIO);
  }
  else
  {
    // Reception of Data frame
    appli_rx_msg.can_msg->data.u64 = 
can_get_mob_data(CAN_CHANNEL_EXAMPLE,handle).u64;
    appli_rx_msg.can_msg->id = 
can_get_mob_id(CAN_CHANNEL_EXAMPLE,handle);
    appli_rx_msg.dlc = can_get_mob_dlc(CAN_CHANNEL_EXAMPLE,handle);
    appli_rx_msg.status = event;
    can_mob_free(CAN_CHANNEL_EXAMPLE,handle);
    nb_message_received_on_channel0 = 1;
    gpio_clr_gpio_pin(LED1_GPIO);
  }
}

Allerdings ist dieses Beispiel für den Empfang einer Wakeup-Message.

Ich bräuchte eine Unterscheidung des callbacks, ob ich nun enden oder 
Empfangen will.
Aber wie kann ich diese Unterscheidung realisieren?

von Dionysos 3. (dionysos328)


Angehängte Dateien:

Lesenswert?

Ich habe mittlerweile unterschiedliche callback-Funktionen für beide
Kanäle jeweils für das Senden und Empfangen eingerichtet.

Der jeweile Kanal hängt sich aber dennoch nach dem Absetzen von 16
Nachrichten reproduzierbar ab.

Der andere Kanal funktioniert weiterhin solange, bis auch er 16
Nachrichten abgesetzt hat.

Hat niemand eine Idee, wo ich den Fehler suchen könnte?

von Dionysos 3. (dionysos328)


Lesenswert?

keiner?

von Dionysos 3. (dionysos328)


Lesenswert?

ich hab jetzt nochmal mein Programm mit zwei Kanälen mit einer früheren 
Version verglichen, bei der ich nur einen Kanal verwendet habe.

die Hauptschleife beinhaltet in der frühen Version folgendes:

 while(true)

 {
   if ((nb_message_received_on_channel1 == 1))
    {

      send_ch1();
      print_dbg("Nachricht da\r\n");
      //send_ch1();
      can_example_prepare_data(1);
      nb_message_received_on_channel1= 0;

    }

}


In dieser Form kann ich unbegrenzt Nachrichten empfangen und 
beantworten.
Tausche ich jedoch die Position, an der "send_ch1()" aufgerufen wird, 
bleibt er nach 16 Nachrichten hängen.

von CAN-User (Gast)


Lesenswert?

Hallo,

ich habe jetzt nicht versucht deine Code-Schnipsel im einzelnen 
nachzuvollziehen. Aber einige Anmerkungen, Ideen oder Denkanstöße habe 
ich dennoch:
- Hast du inzwischen eine Interrupt-Handler registriert?

- Hast du nachdem du eine Nachricht verarbeitet hast, das Message-Objekt 
mit
   can_mob_free( CAN_Interface, handle )
wieder freigegeben?

- Hast du einmal versucht die Anzahl der Msg-Objekte zu verändern?

Das waren jetzt einfach mal so ein paar Schüsse aus der Hüfte. 
Vielleicht hats ja geholfen.

Gruß

von Dionysos 3. (dionysos328)


Lesenswert?

Hi,

danke für deine Gedankenanstöße.

Also ich verwende noch die Interrupt-Routine aus dem ASF-Beispiel.
(In dem Beispiel funktioniert die anscheinend).

Die MOB's werden in can_out_callbacks freigegeben.

An der Anzahl der MOB's habe ich noch nicht gedreht.

Dafür habe ich mir das "CAN Software Stack Example 2" nochmal angesehen.

Ich habe das Mainroutine dahingehend verändert, dass auf eine Nachricht 
gewartet wird und falls eine eintrifft, diese mit einer anderen 
Nachricht "beantwortet" wird. (Die Statemachine muss gefüttert werden, 
da sie im Originalprogramm vorhanden war)

Das sieht nun also so aus:

while(1)
  {
    if (nb_message_received_on_channel0 == 1)
    {
      state_machine = 120;
      can_example_prepare_data(0);
      print_dbg("Nachricht da\r\n");
      nb_message_received_on_channel0 = 0;
      state_machine = 220;
      can_example_prepare_data(1);
    }


  }


In diesem Zustand funktioniert das Programm, ich kann unbegrenzt 
Nachrichten empfangen.

Der Knaller ist aber:

Kommentiere ich die Debug-Ausgabe AUS, bleibt das Programm Nach 16 
gesendeten Nachrichten hängen!

Wird die Debug-Ausgabe getätigt, läuft das Programm.

von CAN-User (Gast)


Lesenswert?

Das könnte doch sicher etwas mit den Interrupts zu tun haben, da die 
serielle Schnittstelle ( USART ) sicher auch interruptgesteuert 
implementiert ist.
Versuche doch einmal, die CAN-Interrupts nach dem Verarbeiten der Pakete 
explizit neu zu aktivieren per can_enable_interrupt()...

Ich denke, du solltest dir die Interruptverarbeitung nocheinmal genau 
anschauen.

Gruß

von Dionysos 3. (dionysos328)


Lesenswert?

danke für den Tipp, aber ein einfaches can_enable_interrupt() behebt das 
Problem leider nicht.

Ich schaue mir die Interrupts trotzdem nochmal genauer an.

von Dionysos 3. (dionysos328)


Lesenswert?

Ich konnte das Problem eingrenzen:

Zum Senden und zum Empfangen werden Message Objekte allokiert.
Diese müssen wieder freigegeben werden.

Das geschiet mit den Funktionen

can_mob_alloc und can_mob_free

Ich habe mir dazu jedes Mal debug-Nachrichten ausgeben lassen.

Wenn das Programm funktioniert, wird ein MOB allokiert, die Nachricht 
empfangen, die Inhalte in Variablen abgelegt, das MOB freigegeben.
Dann wird ein neues MOB allokiert, zum senden der CAN-Nachricht 
verwendet und freigegeben.

In einer Konstellation, in der sich das Porgramm aufhängt, werden zwei 
MOBs allokiert, aber nur eins davon freigegeben.
Irgendwann können dann keine neuen mehr alokiert werden.

Jetzt ist die Frage, was hat die Stelle, an der in der main() debug 
Ausgaben gemacht werden damit zutun, dass nicht beide MOBs freigegeben 
werden können?!

Edit: anscheinend wird mein Empfangs-Callback nicht ausgeführt, in dem 
das MOB freigegeben werden soll.

: Bearbeitet durch User
von Dionysos 3. (dionysos328)


Lesenswert?

auch wenn das hier ein Selbstgespräch ist, halte ich mal den 
Zwischenstand fest:

Das Problem liegt darin, dass die send-callbacks nicht aufgerufen 
werden, um MOBs freizugeben.


Das klappt allerdings nur in der if-Verzweigung meiner main-Schleife 
nicht.
In dieser Verzweigung wird abgefragt, ob einer der beiden Kanäle eine 
Nachricht empfangen hat.

while(4>2)

 {
   if ((nb_message_received_on_channel0 == 1))
   {

     ...


   }
   else if ((nb_message_received_on_channel1 == 1))
   {

     ...

   }


 }

wird meine Send-Funktion vor der if-Verzweigung aufgerufen, wird auch 
der Send-callback einwandfrei abgearbeitet.

Worann kann das nun wieder liegen?

von Sinuslive (Gast)


Lesenswert?

Hallo dionysos 328,
habe das selbe Problem und habe auch rausgefunden, dass beim Empfangen 
die Call-Back Methode nicht aufgerufen wird.
Senden und Empfangen geht aber. Leider kann ich nicht auf die Daten der 
empfangenen Botschaft reagieren, da wie gesagt die Call-Back Methode 
nicht aufgerufen wird.

Hast du schon rausgefunden, an was das liegt?
Würde mich über deine Hilfe freuen.

Beste Grüße,
Sinuslive

von Dionysos 3. (dionysos328)


Lesenswert?

Hi Sinuslive,

ja ich konnte das Problem in der Zwischenzeit lösen.

Ich hatte auch rausgefunden, dass die Callbacks nach dem Senden nicht 
aufgerufen werden, und deshalb die erzeugten Messageobjekte nicht 
freigegeben werden.

Und das lag an der Struktur, wie ich meine Hauptverzweigung aufgebaut 
hatte.

Wenn eine Nachricht auf einem Kanal empfangen wurde, wurde der 
Empfangs-Callback ausgelöst, die Nachricht abgeholt und dann eine 
Variable gesetzt "Nachricht da Kanal X".

In der Main-Schleife wurde dann in einer Verzweigung in einen Zweig 
gesprungen, in der die "Nachricht Empfangen"-Variable zurückgesetzt 
wurde.
Anschließen wurde die "Send"-Funktion aufgerufen und daraufhin eine 
Variable gesetzt: "Nachricht gesendet Kanal X".

In einem weiteren Zweig wurde auf diese Variable reagiert und der Kanal 
wieder für das Empfangen vorbereitet("prepare_data_to_receive").

Das Problem dabei ist das setzen der Variable "Nachricht gesendet Kanal 
X".
Dies geschah zwar rein logisch an der richtigen Stelle, allerdings war 
der Zeitpunkt, an dem das Rücksetzten geschah nicht immer gleich.

Je nach dem, durch welchen Interrupt das Programm unterbrochen wurde 
(Stichwort print_dbg).
Die sichere Variante ist daher, das setzten der Variable „gesendet“ mit 
den den Send-Callback zu integrieren, weil dort nichts den Ablauf 
unterbricht.

Jetzt werden Send Callbacks immer zuende ausgeführt.

Hoffe das hat geholfen, Grüße,
dionysos

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.