Hello, Am 02.11.21 um 16:36 schrieb Oliver Hartkopp: > Hi Matthias, > > On 02.11.21 16:03, Matthias Weißer wrote: > >> we recently had a case here where one member of a CAN bus couldn't >> receive >> frames with data content of only zeros: >> >> $ cansend can0 123#0000000000000000 >> >> After some investigation we found the root cause to be a slight >> difference >> (about 1%) in actual bitrates of the two members. The one with showed the >> RX errors had a sjw value of 1 and a lot of time quanta (40) due to >> the 40MHz >> CAN clock. >> >> This leads to a build up of phase error (as sjw is not able to >> compensate for >> enough of the bitrate difference) which at some point leads to a framing >> error due to missing a stuff bit. Playing around with the sample point >> can >> improve or worsen the behavior. >> >> We can fix this quite easily by specifying a higher sjw value. > > You can specify the sjw value with the ip command (for CAN FD there is > also a dsjw). And IIRC you can set it to the max. value for your CAN > controller if you define sjw to be 4. > > Best regards, > Oliver > > $ ip link help can > Usage: ip link set DEVICE type can > [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] | > [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1 > phase-seg2 PHASE-SEG2 [ sjw SJW ] ] This usage description is not totally correct! It is also possible, to increase "sjw" together with the bitrate, e.g.: # ip link set can0 type can bitrate 250000 sjw 2 # ip -d link show can0 | grep sjw tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 2 Here is the code for it: # cat dev.c ... /* check for sjw user settings */ if (!bt->sjw || !btc->sjw_max) { bt->sjw = 1; } else { /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ if (bt->sjw > btc->sjw_max) bt->sjw = btc->sjw_max; /* bt->sjw must not be higher than tseg2 */ if (tseg2 < bt->sjw) bt->sjw = tseg2; } Wolfgang