Seri Protokoller
TEKNİK REHBER SERİ PROTOKOLLER CAN FD 2026

CAN FD
ISO 11898-7 — Flexible Data Rate

64 byte payload, 8 Mbit/s data bitrate, bitrate switching — CAN FD'yi Classical CAN'dan ayıran her şey ve Linux SocketCAN ile uygulama.

00 CAN FD nedir: Classical CAN sınırları ve FD farkları

Classical CAN, 1986'dan bu yana otomotiv ve endüstride güvenilir biçimde kullanılmaktadır. Ancak modern araçlarda ECU sayısı artıkça 1 Mbit/s hız ve 8 byte payload yetersiz kalmaktadır.

Classical CAN'ın iki temel kısıtı

Hız: 1 Mbit/sKlasik CAN'ın fiziksel katman sınırlaması. Uzun kablo boyutları ve terminasyon gereklilikleri nedeniyle pratikte 500 kbit/s–1 Mbit/s arasında çalışılır. Firmware OTA güncellemesi veya kamera verisi için yetersizdir.
Payload: 8 byteHer CAN frame yalnızca 8 byte veri taşır. Daha büyük veri için CAN TP (ISO 15765-2) katmanına ihtiyaç duyulur; bu da ek karmaşıklık ve gecikme demektir.

CAN FD (ISO 11898-7) farkları

CAN FD (Flexible Data Rate), Bosch tarafından 2012'de tanıtıldı ve ISO 11898-7 olarak standardize edildi. İki temel yenilik sunar:

  Classical CAN frame:
  [SOF][ID 11-bit][RTR][IDE][DLC 4-bit][DATA 0-8 byte][CRC][ACK][EOF]

  CAN FD frame:
  [SOF][ID 11/29-bit][RRS][IDE][EDL=1][BRS][ESI][DLC 4-bit]
       ↓ BRS bit → Bitrate Switch
  [DATA 0-64 byte (nominal bitrate → data bitrate)][CRC 17/21-bit][ACK][EOF]
    
EDL — Extended Data LengthBu bit set edildiğinde frame'in CAN FD olduğu anlaşılır. Classical CAN node'ları bu biti tanımaz ve error frame üretir — mixed bus dikkat ister.
BRS — Bit Rate SwitchBu bit set edildiğinde, BRS bitinden CRC sonu arasındaki veri fazı daha yüksek hızla iletilir. Arbitration fazı hala nominal bitrate'de çalışır.
ESI — Error State IndicatorGönderen node'un hata durumu (Error Active veya Error Passive) hakkında alıcıya bilgi verir.

ISO vs Non-ISO CAN FD

2012'de Bosch'un yayımladığı orijinal spec (non-ISO CAN FD) ile ISO 11898-7 arasında ince farklılıklar vardır:

ÖzellikNon-ISO CAN FD (Bosch)ISO CAN FD (11898-7)
CRC hesaplamaCRC stuff count içermezCRC'ye stuff bit sayacı eklendi
Donanım uyumuEski FD controller'lar2015+ üretim ECU'lar, MCP2517FD
SocketCAN seçeneğifd-non-iso onVarsayılan (fd on)
KullanımBazı eski geliştirme araçlarıTüm yeni projeler için önerilen
ÖNEMLİ

ISO ve non-ISO CAN FD node'ları aynı bus'ta birlikte çalışamaz. Donanım satın alırken ISO 11898-7 uyumlu (ISO CAN FD) olduğunu doğrulayın. MCP2517FD ve MCP2518FD ISO CAN FD destekler.

01 Elektriksel katman ve transceiver

CAN FD elektriksel katmanı Classical CAN ile aynı diferansiyel sinyal yapısını kullanır; ancak yüksek data bitrate için düşük gecikmeli transceiver seçimi kritik önem taşır.

Diferansiyel sinyal: CAN_H ve CAN_L

CAN bus bükümlü çift tel üzerinden diferansiyel sinyal iletir. Bu yaklaşım ortak mod gürültüsünü büyük ölçüde baskılar.

  Dominant (logic 0):   CAN_H ≈ 3.5V,  CAN_L ≈ 1.5V,  Vdiff ≈ +2.0V
  Recessive (logic 1):  CAN_H ≈ 2.5V,  CAN_L ≈ 2.5V,  Vdiff ≈  0.0V

  ┌──────────────────────────────┐
  │  CAN Controller              │
  │  TX ──→ Transceiver ──→ CAN_H│──┐
  │  RX ←── Transceiver ←── CAN_L│──┼── 120Ω terminatör
  └──────────────────────────────┘  │   (her iki ucunda)
    

Terminasyon

Bus'un her iki ucuna 120Ω terminatör takılmalıdır. Bu değer kablonun karakteristik empedansıyla eşleşir ve yansımayı önler. CAN FD'de yüksek data bitrate, terminasyon kalitesine daha duyarlıdır.

Terminasyon durumuParalel dirençEtkisi
İki uçta 120Ω + 120Ω60ΩDoğru — yansıma yok
Tek ucta 120Ω120ΩHatalı — yüksek bitrate'de frame error
Terminatör yokHatalı — tam yansıma, bus çalışmaz
Split terminasyon (60Ω+60Ω + 4.7nF)60Ω + filtreYüksek EMI ortamları için tercih edilir

CAN FD transceiver seçimi

Classical CAN transceiver'lar (TJA1050, SN65HVD230) teorik olarak CAN FD frame'lerini iletebilir; ancak propagation delay limitleri nedeniyle yüksek data bitrate'de (>2 Mbit/s) sorunlara yol açar.

TJA1057G (NXP)CAN FD uyumlu, 5 Mbit/s data bitrate destekli. Düşük propagation delay (50 ns typ). Otomotiv uygulamaları için AEC-Q100 sertifikalı.
SN65HVD235 (TI)3.3V besleme ile çalışan CAN FD transceiver. Raspberry Pi ve beaglebone gibi 3.3V sistemlerle doğrudan kullanılabilir.
TCAN1042 (TI)8 Mbit/s CAN FD destekli, gelişmiş ESD koruması. Standby/sleep modu ile düşük güç tüketimi.
MCP2562FD (Microchip)MCP2517FD/2518FD SPI-CAN controller'larıyla ideal eşleşme. 8 Mbit/s, 3.3V/5V VIO seçeneği.
KURAL

Transceiver datasheet'inde propagation delay değerini kontrol edin (TX→RX loop delay). 2 Mbit/s data bitrate için bit süresi 500 ns'dir; loop delay bu değerin %30'unu aşmamalıdır. Yüksek bitrate'de kısa kablo kullanın.

02 Bit timing detayı

CAN FD'de iki ayrı bitrate tanımlanır: arbitration fazı için nominal bitrate, veri fazı için data bitrate. Her ikisi de ayrı timing parametreleri gerektirir.

Bit timing temelleri

Her CAN bit dört bölüme ayrılır: Sync Seg, Prop Seg, Phase Seg 1 ve Phase Seg 2. Birim, Time Quantum (TQ) cinsinden ölçülür.

  ┌─────────┬──────────┬──────────┬──────────┐
  │Sync Seg │ Prop Seg │Phase Seg1│Phase Seg2│
  │ 1 TQ    │ 1-8 TQ   │ 1-8 TQ   │ 1-8 TQ   │
  └─────────┴──────────┴──────────┴──────────┘
                                  ↑ Sample Point
  TQ = 1 / (f_clk / BRP)
    
BRP — Baud Rate PrescalerCAN controller clock'unu bölerek TQ süresini ayarlar. TQ = BRP / f_clk.
TSEG1 = Prop + Phase1Sample point'ten önceki TQ sayısı. Propagation delay'i karşılayacak kadar büyük olmalıdır.
TSEG2 = Phase2Sample point'ten sonraki TQ sayısı. SJW (Synchronization Jump Width) bu değeri aşamaz.
Sample Point (SP)Bit değerinin okunduğu an. Klasik CAN için %75–80, CAN FD data fazı için %70–80 arası önerilir.

CAN FD'de dual bitrate konfigürasyonu

bash — ip link CAN FD timing
# Nominal: 500 kbit/s, Data: 2 Mbit/s
sudo ip link set can0 type can \
    bitrate 500000 \
    sample-point 0.80 \
    dbitrate 2000000 \
    dsample-point 0.75 \
    fd on

# Nominal: 500 kbit/s, Data: 4 Mbit/s (kısa kablo)
sudo ip link set can0 type can \
    bitrate 500000 \
    dbitrate 4000000 \
    fd on

# Mevcut timing değerlerini göster
ip -details link show can0

SP tutarsızlığı sorunu (SP mismatch)

CAN FD'de farklı node'ların data fazı sample point'leri birbirinden farklıysa iletişim hataları oluşur. Bu, klasik CAN'da göz yumulan ama FD'de kritik hale gelen bir sorundur.

BitrateÖnerilen nominal SPÖnerilen data SPKablo limiti
500k / 2M%80%75<30 m
500k / 4M%80%75<10 m
500k / 8M%80%70<3 m
1M / 8M%75%70<1 m
PRATİK

CAN FD analyzer araçları (PEAK PCAN-View, Vector CANalyzer) bit timing hesaplayıcısı içerir. bit-timing-calculator adlı açık kaynak araç (can-utils deposunda) SocketCAN için doğrudan kullanılabilir değerler üretir.

03 Linux SocketCAN ile CAN FD yapılandırması

Linux 3.6 ile birlikte SocketCAN, CAN FD desteği kazandı. Kernel tarafında canfd_frame struct ve CAN_RAW_FD_FRAMES socket seçeneği bu desteği kullanıcı alanına sunar.

CAN FD arayüzü açma

bash — CAN FD arayüz yapılandırması
# Kernel modüllerini yükle
sudo modprobe can
sudo modprobe can_raw
sudo modprobe can_dev

# MCP2517FD için SPI-CAN modülü (Raspberry Pi örneği)
sudo modprobe mcp251xfd

# CAN FD arayüzünü yapılandır ve aç
sudo ip link set can0 type can \
    bitrate 500000 \
    dbitrate 2000000 \
    fd on

sudo ip link set can0 up

# Durumu doğrula — "FD ON" görünmeli
ip -details link show can0
# ...
# can <FD> state ERROR-ACTIVE restart-ms 0
#   bitrate 500000 sample-point 0.800
#   tq 25 prop-seg 14 phase-seg1 15 phase-seg2 8 sjw 1
#   mcp251xfd: tseg1 2..256 tseg2 1..128 sjw 1..128 brp 1..256 brp-inc 1
#   dbitrate 2000000 dsample-point 0.750
#   dtq 25 dprop-seg 4 dphase-seg1 4 dphase-seg2 3 dsjw 1

# ISO olmayan (non-ISO) CAN FD için:
sudo ip link set can0 type can \
    bitrate 500000 dbitrate 2000000 \
    fd on fd-non-iso on

canfd_frame struct

include/uapi/linux/can.h
/* CAN FD frame yapısı — Classical can_frame ile karşılaştırma */

struct can_frame {        /* Classical CAN: 16 byte toplam */
    canid_t  can_id;      /* 4 byte: ID + flag bitleri */
    __u8     can_dlc;     /* 0-8 */
    __u8     __pad[3];
    __u8     data[8];
};  /* sizeof = 16, CAN_MTU = 16 */

struct canfd_frame {      /* CAN FD frame: 72 byte toplam */
    canid_t  can_id;      /* 4 byte: ID + flag bitleri */
    __u8     len;         /* gerçek payload boyutu: 0-64 */
    __u8     flags;       /* CANFD_BRS | CANFD_ESI */
    __u8     __res0;
    __u8     __res1;
    __u8     data[64];
};  /* sizeof = 72, CANFD_MTU = 72 */

/* flags bitleri */
#define CANFD_BRS  0x01  /* Bit Rate Switch etkin */
#define CANFD_ESI  0x02  /* Error State Indicator */
#define CANFD_FDF  0x04  /* FD Frame (bazı kernel sürümleri) */

CAN_RAW_FD_FRAMES socket seçeneği

fd_socket_setup.c
#include <linux/can.h>
#include <linux/can/raw.h>

int fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);

/* CAN FD frame desteğini etkinleştir */
int enable_fd = 1;
setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
           &enable_fd, sizeof(enable_fd));

/* Bu noktadan itibaren:
   - write() ile sizeof(struct canfd_frame) = CANFD_MTU(72) yazılırsa CAN FD
   - write() ile sizeof(struct can_frame) = CAN_MTU(16) yazılırsa Classical CAN
   Tek socket her iki türü de gönderebilir. */

04 Gönderme ve alma — C ve Python

CAN FD frame göndermek için canfd_frame struct doldurulur ve CANFD_MTU boyutunda write() çağrısı yapılır. MTU kontrolü, yanlışlıkla classical frame göndermeyi engeller.

C ile CAN FD gönderme

canfd_send.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>

int main(void) {
    int s = socket(PF_CAN, SOCK_RAW, CAN_RAW);

    /* Arayüzü bağla */
    struct ifreq ifr;
    strcpy(ifr.ifr_name, "can0");
    ioctl(s, SIOCGIFINDEX, &ifr);

    struct sockaddr_can addr = {
        .can_family  = AF_CAN,
        .can_ifindex = ifr.ifr_ifindex,
    };
    bind(s, (struct sockaddr *)&addr, sizeof(addr));

    /* CAN FD frame desteğini etkinleştir */
    int enable_fd = 1;
    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
               &enable_fd, sizeof(enable_fd));

    /* CAN FD frame hazırla: ID=0x123, 32 byte payload */
    struct canfd_frame frame;
    memset(&frame, 0, sizeof(frame));
    frame.can_id = 0x123;
    frame.len    = 32;
    frame.flags  = CANFD_BRS;   /* data fazında hız geçişi */

    for (int i = 0; i < 32; i++)
        frame.data[i] = (uint8_t)i;

    /* MTU kontrolü — her zaman CANFD_MTU(72) yazılmalı */
    ssize_t nbytes = write(s, &frame, CANFD_MTU);
    if (nbytes != CANFD_MTU) {
        perror("write");
        return 1;
    }
    printf("CAN FD frame gönderildi: ID=0x%03X len=%d\n",
           frame.can_id, frame.len);
    close(s);
    return 0;
}

C ile CAN FD alma ve MTU kontrolü

canfd_recv.c
/* Hem Classical hem CAN FD frame alabilen alıcı */
int enable_fd = 1;
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
           &enable_fd, sizeof(enable_fd));

union {
    struct can_frame    classic;
    struct canfd_frame  fd;
} buf;

while (1) {
    ssize_t nbytes = read(s, &buf, sizeof(buf));

    if (nbytes == CAN_MTU) {          /* 16 byte: Classical */
        printf("Classic: ID=0x%03X dlc=%d\n",
               buf.classic.can_id & CAN_EFF_MASK,
               buf.classic.can_dlc);
    } else if (nbytes == CANFD_MTU) {  /* 72 byte: CAN FD */
        printf("FD: ID=0x%03X len=%d flags=0x%02X\n",
               buf.fd.can_id & CAN_EFF_MASK,
               buf.fd.len,
               buf.fd.flags);
    }
}

Python ile CAN FD frame

bash — kurulum
pip install python-can
canfd_python.py
import can

# CAN FD etkin arayüze bağlan
bus = can.Bus(channel='can0', interface='socketcan',
              fd=True,
              bitrate=500_000,
              data_bitrate=2_000_000)

# CAN FD Message gönder (is_fd=True)
msg = can.Message(
    arbitration_id=0x123,
    data=bytes(range(32)),
    is_fd=True,
    bitrate_switch=True,  # BRS bit
    is_extended_id=False
)
bus.send(msg)
print(f"Gönderildi: {msg}")

# Alma (1 saniyelik timeout)
received = bus.recv(timeout=1.0)
if received:
    print(f"FD={received.is_fd} BRS={received.bitrate_switch}")
    print(f"ID=0x{received.arbitration_id:03X} len={len(received.data)}")
    print(f"Data: {received.data.hex()}")

bus.shutdown()

05 Error frame ve bus-off recovery

CAN FD, Classical CAN hata mekanizmalarını miras alır. TEC ve REC sayaçları aracılığıyla node'lar Error Active → Error Passive → Bus-Off geçişi yapar.

TEC / REC sayaçları ve durum geçişleri

  TEC/REC < 128     : Error Active   (normal çalışma, aktif error frame gönderir)
  TEC veya REC ≥ 128: Error Passive  (passive error flag gönderir)
  TEC ≥ 256         : Bus-Off        (bus'tan kopar, sessizlik)

  Bus-Off çıkışı: 128 × 11 recessive bit gözlemlenince otomatik (veya manual restart)
    

SocketCAN ile hata frame okuma

can_error_monitor.c
#include <linux/can/error.h>

/* Error frame maskesini etkinleştir */
can_err_mask_t err_mask = CAN_ERR_MASK; /* tüm hataları al */
setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
           &err_mask, sizeof(err_mask));

/* Önemli error class bitleri (can_id içinde): */
// CAN_ERR_TX_TIMEOUT   0x00000001U  TX zaman aşımı
// CAN_ERR_LOSTARB      0x00000002U  arbitrasyon kaybı
// CAN_ERR_CRTL         0x00000004U  controller hatası
// CAN_ERR_PROT         0x00000008U  protokol ihlali
// CAN_ERR_TRX          0x00000010U  transceiver hatası
// CAN_ERR_BUSOFF       0x00000040U  bus-off durumu
// CAN_ERR_BUSERROR     0x00000080U  bus hatası
// CAN_ERR_RESTARTED    0x00000100U  arayüz yeniden başladı

struct can_frame err;
read(s, &err, CAN_MTU);
if (err.can_id & CAN_ERR_FLAG) {
    if (err.can_id & CAN_ERR_BUSOFF)
        printf("Bus-Off durumu tespit edildi!\n");
    if (err.can_id & CAN_ERR_CRTL)
        printf("Controller: TEC/REC eşiği aşıldı\n");
}

Otomatik bus-off restart

bash — otomatik restart
# 100 ms sonra otomatik restart (bus-off recovery)
sudo ip link set can0 type can \
    bitrate 500000 dbitrate 2000000 fd on \
    restart-ms 100

# Manuel restart
sudo ip link set can0 type can restart

# Hata istatistiklerini izle
ip -s link show can0
# RX: errors, dropped değerlerini takip et

06 DLC genişlemesi ve payload padding

CAN FD, 0–8 arası DLC değerlerini Classical CAN ile aynı anlamda kullanır; 9–15 arası değerler ise genişletilmiş payload boyutlarına karşılık gelir.

CAN FD DLC tablosu

DLC (4-bit)Payload (byte)Not
00Boş frame
1–81–8Classical CAN ile aynı
912CAN FD genişleme başlangıcı
1016
1120
1224
1332
1448
1564Maksimum payload

Payload padding zorunluluğu

DLC 9–15 değerleri için gönderilecek veri boyutu frame'in DLC'sine karşılık gelen boyutu dolduramıyorsa padding yapılması gerekir. Örneğin 10 byte veri göndermek için DLC=10 (16 byte) seçilir ve fazladan 6 byte 0x00 ile doldurulur.

canfd_dlc.c
#include <linux/can.h>

/* DLC → gerçek byte boyutu dönüşümü */
static const uint8_t dlc_to_len[] = {
    0, 1, 2, 3, 4, 5, 6, 7, 8,
    12, 16, 20, 24, 32, 48, 64
};

/* Veri uzunluğundan uygun DLC bul (yukarı yuvarla) */
uint8_t len_to_dlc(uint8_t len) {
    if (len <= 8)  return len;
    if (len <= 12) return  9;
    if (len <= 16) return 10;
    if (len <= 20) return 11;
    if (len <= 24) return 12;
    if (len <= 32) return 13;
    if (len <= 48) return 14;
    return 15;  /* 64 */
}

/* Kullanım: 10 byte veri göndermek */
struct canfd_frame frame;
memset(&frame, 0, sizeof(frame));
frame.can_id = 0x200;
frame.len    = 16;  /* DLC=10 → 16 byte; 6 byte padding 0x00 */
frame.flags  = CANFD_BRS;
memcpy(frame.data, my_10_byte_data, 10);
/* frame.data[10..15] zaten 0x00 (memset ile temizlendi) */
write(s, &frame, CANFD_MTU);
NOT

SocketCAN'da canfd_frame.len alanı gerçek payload boyutunu tutar (DLC değil). Örneğin 10 byte veri için len = 16 ayarlanır (DLC=10'a karşılık gelen boyut). Linux kernel, frame'i bus'a yazarken doğru DLC değerini hesaplar.

07 CAN FD test araçları

can-utils paketi CAN FD için genişletilmiş destek sunar. candump ve cansend komutları FD frame'leri görüntüleyebilir ve gönderebilir.

candump ile CAN FD izleme

bash — candump
# Tüm frame'leri göster (CAN FD dahil)
candump can0

# CAN FD çıktı örneği (FD frame, BRS etkin):
# (1716890123.456789) can0  123   [32]  00 01 02 03 04 05 06 07 08 09 0A 0B
#                                        0C 0D 0E 0F 10 11 12 13 14 15 16 17
#                                        18 19 1A 1B 1C 1D 1E 1F

# Timestamp + arayüz adıyla kaydet
candump -l can0
# Dosya: candump-2026-04-12_120000.log

# Sadece belirli ID'yi izle
candump can0 123:7FF

cansend ile CAN FD gönderme

bash — cansend FD
# Classical CAN frame (8 byte)
cansend can0 123#DEADBEEF01020304

# CAN FD frame — ## ile başlar, ardından flags byte
# ##1 → BRS etkin (flags=0x01)
cansend can0 123##1DEADBEEF01020304050607080910111213141516171819

# ##0 → BRS kapalı
cansend can0 456##0AABBCCDD

canplayer ve canlogserver

bash — kayıt oynatma ve sunucu
# Kaydedilmiş log dosyasını oynat
canplayer -I candump-2026-04-12_120000.log

# Belirli bir arayüze yönlendir
canplayer -I capture.log -l can0=vcan0

# canlogserver: TCP üzerinden uzaktan loglama
canlogserver -p 28700 can0
# İstemci tarafında:
candump -a remote_host:28700

socketcand: CAN over TCP/IP

bash — socketcand
# Kurulum
sudo apt install socketcand

# can0 arayüzünü TCP 29536 üzerinden sun
socketcand -i can0 -p 29536

# Python ile uzaktan bağlantı
# bus = can.Bus('can0', interface='socketcand',
#               host='192.168.1.100', port=29536)

PEAK PCAN-USB FD

PCAN-USB FD, PEAK System'ın USB bağlantılı CAN FD adaptörüdür. Linux'ta peak_usb kernel modülü ile çalışır ve can0 arayüzü olarak görünür.

bash — PEAK PCAN-USB FD
# Modül otomatik yüklenir; kontrol et
lsmod | grep peak_usb
dmesg | grep -i pcan

# Standart ip link komutu ile yapılandır
sudo ip link set can0 type can \
    bitrate 500000 dbitrate 2000000 fd on
sudo ip link set can0 up

08 Pratik: Raspberry Pi + MCP2517FD ile CAN FD

MCP2517FD, SPI arayüzü üzerinden bağlanan ISO CAN FD controller'dır. Raspberry Pi ile birlikte düşük maliyetli CAN FD geliştirme platformu oluşturur.

Donanım bağlantısı

  Raspberry Pi 4          MCP2517FD           MCP2562FD
  ─────────────           ─────────           ─────────
  GPIO 8  (CE0) ────────→ nCS
  GPIO 11 (SCLK)────────→ SCK
  GPIO 10 (MOSI)────────→ SDI
  GPIO 9  (MISO)────────→ SDO
  GPIO 25        ────────→ nINT
                          TX  ──────────────→ TXD
                          RX  ←──────────────  RXD
                                               CAN_H ──→ bus
                                               CAN_L ──→ bus
    

Device Tree overlay ve kernel yapılandırması

/boot/firmware/config.txt (Raspberry Pi OS Bookworm)
# MCP2517FD overlay — 40 MHz SPI clock, INT pin GPIO25
dtoverlay=mcp251xfd,spi0-0,oscillator=40000000,interrupt=25

# SPI etkinleştir
dtparam=spi=on
bash — doğrulama ve başlatma
# Boot sonrası modülü kontrol et
dmesg | grep mcp251
# mcp251xfd spi0.0 can0: MCP2517FD rev0.0 (+FIFO +CRC) at 40.000 MHz

# CAN FD arayüzünü yapılandır
sudo ip link set can0 type can \
    bitrate 500000 dbitrate 2000000 fd on restart-ms 100
sudo ip link set can0 up

# Loopback testi (tek kart, kablo yok)
sudo ip link set can0 type can \
    bitrate 500000 dbitrate 2000000 fd on loopback on
sudo ip link set can0 up
candump can0 &
cansend can0 123##1DEADBEEF0102030405060708

Üretim senaryosu: Firmware OTA over CAN FD

CAN FD'nin 64 byte payload kapasitesi, Classical CAN'a göre OTA güncelleme sürelerini önemli ölçüde kısaltır. Örnek hesaplama:

ParametreClassical CANCAN FD (500k/2M)
Payload / frame8 byte64 byte
256 KB firmware süresi~52 saniye~6.5 saniye
Protokol overheadYüksek (ISO-TP katmanı)Düşük (doğrudan FD frame)
CRC güvenilirliği15-bit CRC17/21-bit CRC
ota_can_fd.py — basit OTA örneği
import can, time, struct

BLOCK_SIZE = 64           # CAN FD max payload
OTA_CMD_ID = 0x700        # OTA komut frame ID
OTA_DATA_ID = 0x701       # OTA veri frame ID

bus = can.Bus('can0', interface='socketcan', fd=True,
              bitrate=500_000, data_bitrate=2_000_000)

def send_firmware(firmware_path):
    with open(firmware_path, 'rb') as f:
        data = f.read()

    total = len(data)
    n_blocks = (total + BLOCK_SIZE - 1) // BLOCK_SIZE

    # Başlangıç komutu gönder (toplam boyut + blok sayısı)
    cmd = struct.pack('>HH', n_blocks, total)
    bus.send(can.Message(arbitration_id=OTA_CMD_ID,
                         data=cmd, is_fd=True,
                         bitrate_switch=True))
    time.sleep(0.01)

    # Blokları gönder
    for i in range(n_blocks):
        block = data[i*BLOCK_SIZE:(i+1)*BLOCK_SIZE]
        payload = struct.pack('>H', i) + block  # 2 byte seq + data
        bus.send(can.Message(arbitration_id=OTA_DATA_ID,
                             data=payload, is_fd=True,
                             bitrate_switch=True))

    print(ff"OTA tamamlandı: {total} byte, {n_blocks} blok")

send_firmware('/tmp/firmware.bin')
bus.shutdown()
BİT TIMING HESAPLAYICI

MCP2517FD için doğru TQ değerlerini hesaplamak amacıyla Microchip'in CAN FD Bit Timing Calculator aracını kullanın. 40 MHz oscillator, 500k/2M bitrate için önerilen değer: BRP=1, TSEG1=62, TSEG2=15, SJW=15 (nominal); DBRP=1, DTSEG1=14, DTSEG2=5, DSJW=4 (data).