Ich glaube, dass einfach Bus-Kabel ziehen an sich von einem
CAN-Controller noch nicht als Fehler empfunden wird. Das Problem kommt,
wenn der Controller ein Meldung sendet und - weil das Kabel gezogen ist
- niemand am Bus antwortet.
Vorschlag: miss die Zeit, zu der Meldungen zum Senden abgelegt werden
(z.B. in einer Tabelle mit 15 Eintraegen, einem pro MOb) und, in Deiner
Warteschleife, schau nach ob eine MOb "zu lange" schon eine gesendet
werdende Meldung hat. Wenn ja, dann hast Du Deinen Fehler, und Du kannst
diese Meldung loeschen.
"Zu lange" laesst sich aus der Bitrate und Reserven fuer Behandlung im
Sender und Empfaenger abschaetzen. Ich verwende zu diesem Zweck das
obere Bit des CAN Timers (CANTIMH), mein Timer laeuft mit 10 kBps (Bus
Takt = 100kBps). Hier ist die Prozedur CanCheckWait, die ich in meiner
Warteschleife periodisch aufrufe (wenn nichts zu tun ist, alle 10 msec -
jedes Mal wird eine neue MOb geprueft)- meine Tabelle ist in
can_status.cs_stamp (uint8_t):
1 | // Check next MOB for send-hang
|
2 | // ----------------------------
|
3 | // Consider an MOB as hanging if xmit is not terminated after > 75 msec
|
4 | //
|
5 | // Return the MOB ordinal if the MOB hangs
|
6 | // Return -1 if the MOB is OK
|
7 |
|
8 | int8_t CanCheckWait ()
|
9 | {
|
10 | uint8_t x_mob ; // ordinal of MOB to check
|
11 | int8_t x_wait ;
|
12 |
|
13 | static uint8_t next_mob = 0 ; // next MOB to check
|
14 |
|
15 | // Determine which MOB to check
|
16 | // - the variable next_mob does a circular walk-trough { 0 .. 14 }
|
17 | // - do nothing if the MOB is not transmitting
|
18 |
|
19 | if ( next_mob > 14 ) next_mob = 0 ; // circular overflow modulo 14
|
20 | x_mob = next_mob++ ;
|
21 | CANPAGE = x_mob << 4 ;
|
22 | if ( ( CANCDMOB & _BV(CONMOB0) ) == 0 ) return -1 ; // OK if not sending
|
23 |
|
24 | // Check the time spent since the launch of the transmission:
|
25 | // - cs_stamp is the value of CANTIMH at transmission launch,
|
26 | // - the high byte of the CAN-timer (CANTIMH) has increments of
|
27 | // 25.6 msec (at 10kHz = 0.1 msec increments of CANTIML),
|
28 | // - sampling jitter = 25.6 msec due to only considering CANTIMH.
|
29 | //
|
30 | // x_wait > 3 ... frame hold detection at 76.8 ... 102.4 mseconds
|
31 |
|
32 | x_wait = CANTIMH - can_status.cs_stamp[x_mob] ;
|
33 | if ( x_wait < 0 ) x_wait += 256 ; // handle counter wrap-around
|
34 | if ( x_wait > 3 ) return x_mob ;
|
35 | return -1 ;
|
36 | }
|