class CAN – denetleyici alan ağı (CAN) iletişim veri yolu

CAN, hem klasik CAN (bxCAN, OpenMV Cam M4 ve M7 üzerinde kullanılır) hem de CAN FD (FDCAN, OpenMV Cam H7, H7 Plus ve Pure Thermal üzerinde kullanılır) denetleyicileri için destek sağlar. Fiziksel düzeyde CAN veri yolu, RX ve TX olmak üzere iki hattan oluşur. Bir OpenMV Cam’i bir CAN veri yoluna bağlamak için, MCU’dan gelen CAN mantık sinyallerini veri yolundaki doğru gerilim seviyelerine dönüştürmek üzere bir CAN alıcı-verici (transceiver) kullanmanız gerekir.

Geri döngü (alıcı-vericisiz) modunda klasik CAN:

from pyb import CAN

can = CAN(1, CAN.LOOPBACK)

# Accept messages with id 123, 124, 125 or 126.
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))

can.send("message!", 123)   # send a message with id 123
can.recv(0)                 # receive a message on FIFO 0

İsteğe bağlı tüm özellikleri etkinleştirilmiş CAN FD (FD çerçeve, bit hızı geçişi, genişletilmiş çerçeve ID’leri; 500 kbit/s arbitrasyon fazı, 1 Mbit/s veri fazı):

from pyb import CAN

can = CAN(
    1,
    CAN.NORMAL,
    baudrate=500_000,
    brs_baudrate=1_000_000,
    sample_point=80,
)

# Accept any id in the range 0xFFF0 .. 0xFFFF.
can.setfilter(0, CAN.RANGE, 0, (0xFFF0, 0xFFFF))

can.send(b"a" * 64, 0xFFFF, fdf=True, brs=True, extframe=True)
can.recv(0)

Aksi belirtilmedikçe, aşağıdaki CAN modülü işlevleri ve argümanları hem klasik hem de FD CAN denetleyicileri için kullanılabilir.

Yapıcılar

class pyb.CAN(bus: int | str, *args, **kwargs)

Verilen bus (bir tam sayı çevre birimi indeksi; örneğin CAN1 için 1, CAN2 için 2) üzerinde bir CAN nesnesi oluşturur. Ek parametre verilmezse nesne oluşturulur ancak başlatılmaz (varsa önceki veri yolu ayarlarını korur); ek argümanlar verilirse veri yolu başlatılır. Kullanılabilir parametreler için CAN.init() bölümüne bakın.

CAN(2), pyb.CAN‘i sunan her OpenMV Cam’de (M4 / M7 / H7 / H7 Plus / Pure Thermal) aynı başlık pinlerine bağlıdır:

Sinyal

Başlık pini

Notlar

RX

P3

TX

P2

CAN çevre birimi yalnızca mantık seviyesi sinyaller sağlar; gerçek bir CAN veri yolunu sürmek için harici bir CAN alıcı-verici (transceiver) gereklidir.

pyb.CAN, OpenMV Cam N6’da kullanılamaz.

Metotlar

init(mode: int, prescaler: int = 100, *, sjw: int = 1, bs1: int = 6, bs2: int = 8, auto_restart: bool = False, baudrate: int = 0, sample_point: int = 75, num_filter_banks: int = 14, brs_sjw: int = 1, brs_bs1: int = 8, brs_bs2: int = 3, brs_baudrate: int = 0, brs_sample_point: int = 75) None

CAN veri yolunu verilen parametrelerle başlatır:

  • mode şunlardan biridir: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK

  • prescaler, nominal bit zamanı kuantasını üretmek için CAN giriş saatinin bölündüğü değerdir. Ön bölücü, klasik CAN için 1 ile 1024 (dahil) arasında, CAN FD için ise 1 ile 512 (dahil) arasında bir değer olabilir.

  • sjw, nominal bitler için zaman kuantası birimi cinsinden yeniden senkronizasyon sıçrama genişliğidir; klasik CAN için 1 ile 4 (dahil) arasında, CAN FD için ise 1 ile 128 (dahil) arasında bir değer olabilir.

  • bs1, nominal bitler için zaman kuantası birimi cinsinden örnekleme noktasının konumunu tanımlar; klasik CAN için 1 ile 16 (dahil) arasında, CAN FD için ise 2 ile 256 (dahil) arasında bir değer olabilir.

  • bs2, nominal bitler için zaman kuantası birimi cinsinden iletim noktasının konumunu tanımlar; klasik CAN için 1 ile 8 (dahil) arasında, CAN FD için ise 2 ile 128 (dahil) arasında bir değer olabilir.

  • auto_restart, denetleyicinin bus-off durumuna girdikten sonra iletişimi otomatik olarak yeniden başlatmaya çalışıp çalışmayacağını ayarlar; bu devre dışı bırakılırsa bus-off durumundan çıkmak için restart() kullanılabilir

  • baudrate, 0’dan farklı bir baud hızı verilirse, bu işlev hem baudrate‘i (%.1 dahilinde) hem de istenen sample_point‘i (en yakın %1’e) karşılayan CAN nominal bit zamanını otomatik olarak hesaplamaya çalışır (prescaler, bs1 ve bs2‘yi geçersiz kılarak). CAN zamanlaması üzerinde daha hassas denetim için prescaler, bs1 ve bs2 parametrelerini doğrudan ayarlayın.

  • sample_point, bit örneğinin tüm nominal bit zamanına göre konumunu, nominal bit zamanının tam sayı yüzdesi olarak belirtir. Varsayılan sample_point %75’tir. baudrate ayarlanmadıkça bu parametre yoksayılır.

  • num_filter_banks, klasik CAN için, CAN(1)’e atanacak bank sayısıdır; 28’in geri kalanı CAN(2)’ye atanır.

Kalan parametreler yalnızca CAN FD desteğine sahip kartlarda bulunur ve isteğe bağlı CAN FD Bit Hızı Geçişi (BRS) özelliğini yapılandırır:

  • brs_prescaler, veri bit zamanı kuantasını üretmek için CAN FD giriş saatinin bölündüğü değerdir. Ön bölücü, 1 ile 32 (dahil) arasında bir değer olabilir.

  • brs_sjw, veri bitleri için zaman kuantası birimi cinsinden yeniden senkronizasyon sıçrama genişliğidir; 1 ile 16 (dahil) arasında bir değer olabilir

  • brs_bs1, veri bitleri için zaman kuantası birimi cinsinden örnekleme noktasının konumunu tanımlar; 1 ile 32 (dahil) arasında bir değer olabilir

  • brs_bs2, veri bitleri için zaman kuantası birimi cinsinden iletim noktasının konumunu tanımlar; 1 ile 16 (dahil) arasında bir değer olabilir

  • brs_baudrate, 0’dan farklı bir baud hızı verilirse, bu işlev hem brs_baudrate‘i (%.1 dahilinde) hem de istenen brs_sample_point‘i (en yakın %1’e) karşılayan CAN veri bit zamanını otomatik olarak hesaplamaya çalışır (brs_prescaler, brs_bs1 ve brs_bs2‘yi geçersiz kılarak). BRS zamanlaması üzerinde daha hassas denetim için brs_prescaler, brs_bs1 ve brs_bs2 parametrelerini doğrudan ayarlayın.

  • brs_sample_point, bit örneğinin tüm nominal bit zamanına göre konumunu, nominal bit zamanının tam sayı yüzdesi olarak belirtir. Varsayılan brs_sample_point %75’tir. brs_baudrate ayarlanmadıkça bu parametre yoksayılır.

Zaman kuantası tq, CAN veri yolu için temel zaman birimidir. tq, CAN ön bölücü değerinin PCLK1’e (dahili çevre birimi veri yolu 1’in frekansı) bölünmesidir; PCLK1’i belirlemek için pyb.freq() bölümüne bakın.

Tek bir bit, her zaman 1 tq olan senkronizasyon segmentinden oluşur. Ardından bit segmenti 1, sonra bit segmenti 2 gelir. Örnekleme noktası, bit segmenti 1 bittikten sonradır. İletim noktası, bit segmenti 2 bittikten sonradır. Baud hızı 1/bittime olacaktır; burada bittime, 1 + BS1 + BS2 değerinin zaman kuantası tq ile çarpımıdır.

Örneğin, OpenMV Cam H7’de (PCLK1 = 100 MHz), %75 örnekleme noktalı 250 kbps CAN, prescaler=25, sjw=1, bs1=11, bs2=4 olarak yapılandırılabilir: tq = 25 / 100 MHz = 250 ns, bittime = (1 + 11 + 4) × 250 ns = 4 µs, örnekleme noktası = (1 + 11) / 16 = 75% ve baud hızı 1 / 4 µs = 250 kHz‘dir.

Daha fazla ayrıntı için OpenMV Cam’in MCU’su için STM32 referans kılavuzunun bxCAN / FDCAN bölümüne bakın.

deinit() None

CAN veri yolunu kapatır.

restart() None

CAN denetleyicisinin yapılandırmasını sıfırlamadan yazılımsal olarak yeniden başlatılmasını zorlar.

Denetleyici bus-off durumuna girerse, artık veri yolu etkinliğine katılmaz. Denetleyici otomatik olarak yeniden başlatılacak şekilde yapılandırılmamışsa (bkz. init()), bu metot bir yeniden başlatmayı tetiklemek için kullanılabilir; denetleyici bus-off durumundan çıkıp error active durumuna geçmek için CAN protokolünü izler.

state() int

Denetleyicinin durumunu döndürür. Dönüş değeri şunlardan biri olabilir:

  • CAN.STOPPED – denetleyici tamamen kapalı ve sıfırlanmış durumda;

  • CAN.ERROR_ACTIVE – denetleyici açık ve Error Active durumunda (hem TEC hem de REC 96’dan küçük);

  • CAN.ERROR_WARNING – denetleyici açık ve Error Warning durumunda (TEC veya REC’ten en az biri 96 veya daha büyük);

  • CAN.ERROR_PASSIVE – denetleyici açık ve Error Passive durumunda (TEC veya REC’ten en az biri 128 veya daha büyük);

  • CAN.BUS_OFF – denetleyici açık ancak veri yolu etkinliğine katılmıyor (TEC, 255’in ötesine taştı).

info(list: list | None = None) list

Denetleyicinin hata durumları ile TX ve RX arabellekleri hakkında bilgi alır. list sağlanırsa, en az 8 girdiye sahip bir liste nesnesi olmalıdır; bu nesne bilgilerle doldurulur. Aksi takdirde yeni bir liste oluşturulup doldurulur. Her iki durumda da metodun dönüş değeri doldurulmuş listedir.

Listedeki değerler şunlardır:

  • TEC değeri

  • REC değeri

  • denetleyicinin Error Warning durumuna girme sayısı (65535’ten sonra 0’a döner)

  • denetleyicinin Error Passive durumuna girme sayısı (65535’ten sonra 0’a döner)

  • denetleyicinin Bus Off durumuna girme sayısı (65535’ten sonra 0’a döner)

  • bekleyen TX mesajı sayısı

  • fifo 0’da bekleyen RX mesajı sayısı

  • fifo 1’de bekleyen RX mesajı sayısı

setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None

Bir filtre bankını yapılandırır:

  • bank, yapılandırılacak klasik CAN denetleyicisi filtre bankı veya CAN FD filtre indeksidir.

  • mode, filtrenin çalışacağı moddur; aşağıdaki tablolara bakın.

  • fifo, bu filtre tarafından kabul edilirse bir mesajın depolanacağı fifo’dur (0 veya 1).

  • params, filtreyi tanımlayan bir değerler dizisidir. Dizinin içeriği mode argümanına bağlıdır.

Klasik CAN denetleyicileri (OpenMV Cam M4 / M7) için params dizisinin içeriği:

mode

params içeriği

CAN.LIST16

Kabul edilecek dört adet 16 bitlik ID.

CAN.LIST32

Kabul edilecek iki adet 32 bitlik ID.

CAN.MASK16

İki adet 16 bitlik id/maske çifti, örneğin (1, 3, 4, 4). İlk çift (1, 3), bit 0 = 1 ve bit 1 = 0 olan tüm ID’leri kabul eder; ikinci çift (4, 4), bit 2 = 1 olan tüm ID’leri kabul eder.

CAN.MASK32

Bir adet 32 bitlik id/maske çifti (aksi halde CAN.MASK16 ile aynı).

CAN FD denetleyicileri (OpenMV Cam H7 / H7 Plus / Pure Thermal) için params dizisinin içeriği:

mode

params içeriği

CAN.RANGE

Kabul edilen ID’lerin bir aralığını oluşturan iki ID.

CAN.DUAL

Kabul edilecek iki ID (örneğin (1, 2)).

CAN.MASK

Bir adet (id, mask) çifti (örneğin (0x111, 0x7FF)).

  • rtr Klasik CAN denetleyicileri için, bir filtrenin uzaktan iletim isteği (remote transmission request) mesajını kabul edip etmeyeceğini belirten bir boolean dizisidir. Bu argüman verilmezse tüm girdiler için varsayılan olarak False kabul edilir. Uzunluk mode‘a bağlıdır:

    mode

    len(rtr)

    Notlar

    CAN.LIST16

    4

    CAN.LIST32

    2

    CAN.MASK16

    2

    CAN.MASK32

    1

    CAN FD için bu argüman yoksayılır.

  • extframe True ise çerçeve genişletilmiş bir tanımlayıcıya (29 bit) sahip olur, aksi takdirde standart bir tanımlayıcı (11 bit) kullanılır.

clearfilter(bank: int, extframe: bool = False) None

Bir filtre bankını temizler ve devre dışı bırakır:

  • bank, temizlenecek klasik CAN denetleyicisi filtre bankı veya CAN FD filtre indeksidir.

  • extframe CAN FD denetleyicileri için, True ise genişletilmiş bir filtreyi (extframe=True ile yapılandırılmış) temizler, aksi takdirde standart bir tanımlayıcıyı (extframe=False ile yapılandırılmış) temizler.

any(fifo: int) bool

FIFO’da bekleyen herhangi bir mesaj varsa True, aksi takdirde False döndürür.

recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list

Veri yolundan veri alır:

  • fifo, üzerinden alım yapılacak FIFO olan bir tam sayıdır

  • list, dönüş değeri olarak kullanılacak isteğe bağlı bir liste nesnesidir

  • timeout, alımı beklemek için milisaniye cinsinden zaman aşımıdır.

Dönüş değeri: Beş değer içeren bir liste.

  • Mesajın id’si.

  • Mesaj ID’sinin standart mı yoksa genişletilmiş mi olduğunu belirten bir boolean.

  • Mesajın bir RTR mesajı olup olmadığını belirten bir boolean.

  • FMI (Filtre Eşleşme İndeksi) değeri.

  • Veriyi içeren bir dizi.

list, None ise yeni bir liste ile birlikte veriyi içerecek yeni bir bytes nesnesi (listedeki beşinci eleman olarak) tahsis edilir.

list, None değilse, en az beş elemana sahip bir liste nesnesi olmalıdır. Beşinci eleman, bir bytearray veya ‘B’ ya da ‘b’ türünde bir array’den oluşturulan bir memoryview nesnesi olmalıdır ve bu array’in en az 8 bayt için yeterli yere sahip olması gerekir. Liste nesnesi yukarıdaki ilk dört dönüş değeriyle doldurulur ve memoryview nesnesi yerinde verinin boyutuna göre yeniden boyutlandırılıp o veriyle doldurulur. Aynı liste ve memoryview nesneleri bu metodun sonraki çağrılarında yeniden kullanılabilir; bu da heap kullanmadan veri almanın bir yolunu sağlar. Örneğin:

buf = bytearray(8)
lst = [0, 0, 0, 0, memoryview(buf)]
# No heap memory is allocated in the following call
can.recv(0, lst)
send(data: int | bytes | bytearray, id: int, *, timeout: int = 0, rtr: bool = False, extframe: bool = False, fdf: bool = False, brs: bool = False) None

Veri yolunda bir mesaj gönderir:

  • data, gönderilecek veridir (gönderilecek bir tam sayı veya bir arabellek nesnesi).

  • id, gönderilecek mesajın id’sidir.

  • timeout, gönderimi beklemek için milisaniye cinsinden zaman aşımıdır.

  • rtr, mesajın bir uzaktan iletim isteği (remote transmission request) olarak gönderilip gönderilmeyeceğini belirten bir boolean’dır. rtr True ise, çerçevenin DLC alanını doldurmak için yalnızca data‘nın uzunluğu kullanılır; data‘daki gerçek baytlar kullanılmaz.

  • extframe True ise çerçeve genişletilmiş bir tanımlayıcıya (29 bit) sahip olur, aksi takdirde standart bir tanımlayıcı (11 bit) kullanılır.

  • fdf CAN FD denetleyicileri için, True olarak ayarlanırsa çerçeve, 64 bayta kadar veri yükünü destekleyen bir FD çerçeve biçimine sahip olur.

  • brs CAN FD denetleyicileri için, True olarak ayarlanırsa, veri fazının farklı bir bit hızında iletildiği bit hızı geçişi modu etkinleştirilir. Veri bit zamanlaması yapılandırma parametreleri için CAN.init() bölümüne bakın.

timeout 0 ise, mesaj üç donanım arabelleğinden birine yerleştirilir ve metot hemen döner. Üç arabelleğin tümü kullanımdaysa bir istisna fırlatılır. timeout 0 değilse, metot mesaj iletilene kadar bekler. Mesaj belirtilen süre içinde iletilemezse bir istisna fırlatılır.

Dönüş değeri: None.

rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None

Boş bir FIFO’ya bir mesaj kabul edildiğinde çağrılacak bir işlevi kaydeder:

  • fifo, alıcı FIFO’dur.

  • fun, FIFO boş olmadığında çağrılacak işlevdir.

Geri çağırma (callback) işlevi iki argüman alır: ilki CAN nesnesinin kendisidir; ikincisi geri çağırmanın nedenini belirten bir tam sayıdır:

Neden

Anlamı

0

Boş bir FIFO’ya bir mesaj kabul edildi.

1

FIFO dolu.

2

Dolu bir FIFO nedeniyle bir mesaj kaybedildi.

rxcallback örnek kullanımı:

def cb0(bus, reason):
  print('cb0')
  if reason == 0:
      print('pending')
  if reason == 1:
      print('full')
  if reason == 2:
      print('overflow')

can = CAN(1, CAN.LOOPBACK)
can.rxcallback(0, cb0)

Sabitler

Veri yolu modu sabitleri (init()‘in mode argümanı):

NORMAL: int

Denetleyici veri yolunda normal şekilde katılır – kendi çerçevelerini iletir ve geçerli alınan çerçeveleri onaylar.

LOOPBACK: int

Dahili geri döngü modu: denetleyici pinlerden ayrılır ve iletilen çerçeveleri doğrudan alım yoluna geri yönlendirir. Alıcı-verici olmadan otomatik testler için kullanışlıdır.

SILENT: int

Yalnızca dinleme modu: denetleyici çerçeveleri alır ancak veri yolunu asla sürmez (ACK yok, iletim yok). Veri yolunu dinlemek (sniffing) için kullanışlıdır.

SILENT_LOOPBACK: int

SILENT ve LOOPBACK modlarını birleştirir: pin etkinliği yok ve onay yok, TX’in RX’e dahili geri döngüsü ile birlikte.

Denetleyici durumu sabitleri (state() tarafından döndürülür):

STOPPED: int

Denetleyici tamamen kapalı ve sıfırlanmış durumda.

ERROR_ACTIVE: int

Denetleyici açık ve Error Active durumunda (hem TEC hem de REC 96’dan küçük).

ERROR_WARNING: int

Denetleyici açık ve Error Warning durumunda (TEC veya REC’ten en az biri 96 veya daha büyük).

ERROR_PASSIVE: int

Denetleyici açık ve Error Passive durumunda (TEC veya REC’ten en az biri 128 veya daha büyük).

BUS_OFF: int

Denetleyici açık ancak veri yolu etkinliğine katılmıyor (TEC, 255’in ötesine taştı).

Klasik CAN filtre modları (OpenMV Cam M4 / M7’de setfilter()‘ın mode argümanı):

LIST16: int

Filtre params dizisi, kabul edilecek dört adet 16 bitlik ID tutar.

LIST32: int

Filtre params dizisi, kabul edilecek iki adet 32 bitlik ID tutar.

MASK16: int

Filtre params dizisi, iki adet 16 bitlik (id, mask) çifti tutar.

MASK32: int

Filtre params dizisi, bir adet 32 bitlik (id, mask) çifti tutar.

CAN FD filtre modları (OpenMV Cam H7 / H7 Plus / Pure Thermal’de setfilter()‘ın mode argümanı):

RANGE: int

Filtre params dizisi, kabul edilen ID’lerin bir aralığını oluşturan iki ID tutar.

DUAL: int

Filtre params dizisi, kabul edilecek iki özel ID tutar.

MASK: int

Filtre params dizisi, bir adet (id, mask) çifti tutar.