class CAN – Controller Area Network protokolü

CAN, ortak bir veri yoluna bağlı bir veya daha fazla düğüm arasında güvenilir gerçek zamanlı mesaj iletimi için kullanılan iki telli seri bir protokoldür. CAN 2.0, ISO-11898’de standartlaştırılmıştır ve günümüzde CAN Classic olarak da bilinir.

Ayrıca CAN FD (CAN with Flexible Data-Rate) adında, geriye dönük uyumlu daha yeni bir protokol de vardır. machine.CAN sürücüsü şu anda CAN FD özelliklerini desteklemez; CAN FD’ye ihtiyacınız varsa STM32 üzerinde pyb.CAN kullanın.

CAN desteği bir denetleyici (çoğunlukla dahili bir mikrodenetleyici çevre birimi) ve sinyalleri CAN veri yoluna seviye kaydırmak için harici bir alıcı-verici gerektirir.

STM32 OpenMV kameralarda (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, ayrıca bir alıcı-verici bağlayan Arduino markalı varyantlar) kullanılabilir. OpenMV Cam RT1062 (mimxrt portu) veya OpenMV Cam AE3 (alif portu) üzerinde henüz desteklenmemektedir.

machine.CAN arayüzü, bir CAN denetleyicisini mesaj göndermek için bir giden öncelik kuyruğu, mesaj almak için bir gelen kuyruğu ve hataları raporlama mekanizmaları olarak soyutlayan düşük seviyeli temel bir CAN mesajlaşma arayüzüdür.

Not

Planlanan can ve aiocan micropython-lib modülleri, MicroPython ile CAN kullanmanın önerilen yolu olacaktır.

Kurucu

class machine.CAN(id: int, *args, **kwargs)

Verilen id ile bir CAN denetleyici nesnesi oluşturur:

  • id belirli bir CAN denetleyici nesnesini tanımlar; karta ve porta özgüdür.

  • Diğer tüm argümanlar CAN.init() fonksiyonuna iletilir. En az bir argüman (bitrate) sağlanmalıdır.

Bu sınıfın gelecekteki sürümleri, donanımı yapılandıran porta özgü anahtar sözcük argümanlarını da burada kabul edebilir. Şu anda böyle bir anahtar sözcük argümanı uygulanmamıştır.

Örnek

CAN denetleyici 1’i 500kbps bit hızıyla oluşturun ve başlatın:

from machine import CAN
can = CAN(1, 500_000)

Metotlar

init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None

CAN veri yolunu verilen parametrelerle başlatır:

  • bitrate, saniye başına bit cinsinden istenen veri yolu bit hızıdır.

  • mode, Modlar altında gösterilen değerlerden biridir ve istenen çalışma modunu belirtir. Varsayılan, veri yolundaki “normal” çalışmadır.

Sonraki parametreler isteğe bağlıdır ve CAN bit zamanlamalarıyla ilgilidir. Çoğu durumda bu parametreleri varsayılan değerlerinde bırakabilirsiniz:

  • sample_point, veri bit süresinin tamsayı yüzdesidir. Bit örneğinin konumunu, toplam nominal bit süresine göre belirtir. CAN sürücüsü parametreleri buna göre hesaplar. tseg1 ve tseg2 ayarlanmışsa bu parametre yok sayılır.

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

  • tseg1, nominal bitler için zaman kuantumu birimleri cinsinden örnek noktasının konumunu tanımlar; klasik CAN için 1 ile 16 (dahil) arasında bir değer olabilir. Bu, ISO-11898 standardında tanımlandığı şekilde Prop_Seg ve Phase_Seg1 aşamalarının toplamıdır. Bu değer ayarlanmışsa tseg2 de ayarlanmalıdır ve sample_point yok sayılır.

  • tseg2, nominal bitler için zaman kuantumu birimleri cinsinden iletim noktasının konumunu tanımlar; klasik CAN için 1 ile 8 (dahil) arasında bir değer olabilir. Bu, ISO-11898 standardındaki Phase_Seg2 değerine karşılık gelir. Bu değer ayarlanmışsa tseg1 de ayarlanmalıdır.

Bu argümanlar belirtilirse, CAN denetleyicisi istenen bitrate ve bit başına belirtilen toplam zaman kuantumu sayısı için doğru şekilde yapılandırılır. Tümü sağlanmışsa tseg1 ve tseg2 değerleri sample_point argümanını geçersiz kılar.

Not

Belirli bir denetleyici donanımı, bu parametreler için geçerli değerler üzerinde ek kısıtlamalara sahip olabilir ve verilen bir değer desteklenmiyorsa bir ValueError yükseltir.

Not

Belirli denetleyici donanımı, aşırı örnekleme gibi donanıma özgü özellikler için ek isteğe bağlı anahtar sözcük parametreleri kabul edebilir.

set_filters(filters: list | tuple | None) None

CAN denetleyicisinde alma filtrelerini ayarlar. filters şunlar olabilir:

  • Gelen tüm mesajları kabul etmek için None veya

  • Tüm mesaj almayı devre dışı bırakmak için [] ya da () veya

  • Filtre kriterlerini tanımlayan bir veya daha fazla öğenin iterable’ı. Her öğe, üç elemanlı bir tuple veya liste olmalıdır:

    • identifier bir CAN tanımlayıcısıdır (int).

    • bit_mask CAN tanımlayıcı alanındaki bitler için bir bit maskesidir (int).

    • flags Mesaj Bayrakları içinde tanımlanan bitlerden sıfır veya daha fazlasının ayarlandığı bir tamsayıdır. Gelen mesajın eşleşmesi gereken özellikleri belirtir. Tüm denetleyiciler tüm bayraklarda filtrelemeyi desteklemez; desteklenmeyen bir bayrak istenirse bir ValueError yükseltilir.

Gelen mesajlar, bit_mask ile maskelenen bitler mesaj tanımlayıcısı ile filtre identifier değeri arasında eşleşirse ve filtrede ayarlanan bayraklar gelen mesajla eşleşirse kabul edilir.

Bayraklarda CAN.FLAG_EXT_ID biti ayarlanmışsa, filtre yalnızca Extended CAN ID’lerle eşleşir. CAN.FLAG_EXT_ID biti ayarlanmamışsa, filtre yalnızca Standard CAN ID’lerle eşleşir.

Tüm filtreler denetleyicide birbirleriyle OR işlemine tabi tutulur. Filtre argümanı için boş bir liste veya tuple geçmek, hiçbir mesajın alınmayacağı anlamına gelir.

Bazı CAN denetleyicileri her filtrenin yalnızca bir alma FIFO’su ile ilişkilendirilmesini gerektirir. Bu durumlarda, argümandaki filtre öğeleri mevcut FIFO’lara round-robin şekilde tahsis edilir. Bu sürücü, alma IRQ’sunda FIFO’lar arasında ayrım yapmaz.

Not

Çağıran, CAN.FILTERS_MAX değerinden daha fazla öğe içeren bir iterable geçerse, ValueError yükseltilir.

Not

identifier veya bit_mask belirtilen ID türü için aralık dışındaysa, “invalid id” nedeniyle bir ValueError yükseltilir.

Örnekler

Gelen tüm mesajları al:

can.set_filters(None)

Yalnızca 0x301 ve 0x700 Standard ID değerlerine sahip mesajları al:

can.set_filters(((0x301, 0x7FF, 0),
                 (0x700, 0x7FF, 0)))

0x300-0x3FF aralığındaki Standard ID değerlerine ve yalnızca 0x50700 Extended ID değerine sahip mesajları al:

can.set_filters(((0x300, 0x700, 0),
                 (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
FILTERS_MAX: int

Bu donanım denetleyicisi için desteklenen maksimum alma filtresi sayısını okuyan sabit değer.

Bazı denetleyicilerin kullanımdaki filtre sayısı üzerinde daha karmaşık donanım kısıtlamalarına sahip olabileceğini unutmayın (örneğin, Standard ve Extended ID filtrelerini bağımsız olarak sayma gibi). Bu durumlarda CAN.set_filters, FILTERS_MAX sınırı aşılmadığında bile bir ValueError yükseltebilir.

send(id: int, data: bytes, flags: int = 0) int | None

Veri yoluna gönderilmek üzere denetleyicinin donanım iletim kuyruğuna yeni bir CAN mesajı kopyalar. İletim kuyruğu, CAN tanımlayıcı önceliğine göre sıralanmış bir öncelik kuyruğudur (daha düşük sayısal tanımlayıcılar daha yüksek önceliğe sahiptir).

  • id bir tamsayı CAN tanımlayıcı değeridir.

  • data, CAN mesaj verisini içeren veya bir Remote Transmission Request’i (aşağıya bakın) tanımlayan bir bytes nesnesidir (veya benzeri).

  • flags, Mesaj Bayrakları içinde tanımlanan bitlerden sıfır veya daha fazlasının ayarlandığı bir tamsayıdır ve giden CAN mesajının özelliklerini (Extended ID, Remote Transmission Request, vb.) belirtir.

Mesaj iletim için veri yoluna başarıyla kuyruğa alınırsa, fonksiyon 0 ile CAN.TX_QUEUE_LEN (hariç) aralığında bir tamsayı döndürür. Bu değer, mesajın gönderilmek üzere kuyruğa alındığı iletim arabelleği indeksidir ve CAN.cancel_send fonksiyonu ile CAN.IRQ_TX olaylarında kullanılabilir.

Kuyruk doluysa gönderim başarısız olur ve None döndürülür.

Sağlanan id değeri iletim kuyruğundaki mevcut bir mesajla eşit önceliğe sahipse ve CAN denetleyici donanımı aynı ID’ye sahip mesajların veri yoluna kuyruğa eklendikleri sırayla gönderileceğini garanti edemiyorsa gönderim de başarısız olabilir ve None döndürebilir. Mesajı yine de kuyruğa almak için flags argümanında CAN.FLAG_UNORDERED bayrağı değerini geçin. Bu bayrak, aynı CAN ID’sine sahip mesajları veri yoluna herhangi bir sırada göndermenin uygun olduğunu belirtir.

Denetleyici “Bus Off” hata durumundaysa veya devre dışıysa, bu fonksiyonu çağırmak bir OSError yükseltir.

Not

Bu kasıtlı olarak düşük seviyeli uygulama, çağıranın giden mesajların bir yazılım kuyruğunu oluşturabilmesi için tasarlanmıştır.

Önemli

CAN “iletim kuyruğu” bir FIFO kuyruğu değildir, öncelik sıralıdır ve CAN.TX_QUEUE_LEN kadar öğe tutabilse de aynı anda kuyruğa alınabilecek mesajlar üzerinde başka donanım kısıtlamaları olabilir.

Remote Transmission Request’ler

flags argümanında CAN.FLAG_RTR biti ayarlanmışsa, denetleyici bir mesaj yerine bir Remote Transmission Request gönderir. Bu durumda data argümanının içeriği yok sayılır. Denetleyici, DLC uzunluk alanının data argümanının uzunluğuna eşit olduğu bir istek gönderir.

Örnekler

0a0b0c üç baytlık yüke ve 0x200 Standard ID’sine sahip bir mesaj göndermeyi dene:

can.send(0x200, b"\x0a\x0b\x0c", 0)

Boş bir yüke ve 0x180008 Extended ID’sine sahip bir mesaj göndermeyi dene. Aynı ID ile gönderilmek üzere başka mesajlar zaten kuyruğa alınmışsa diye, denetleyicinin bu ID’ye sahip mesajları herhangi bir sırada gönderebileceğini belirt:

can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)

8 bayt uzunluğunda ve 0x555 Standard ID’sine sahip bir Remote Transmission Request göndermeyi dene:

can.send(0x555, b" " * 8, can.FLAG_RTR)
recv(arg: list | None = None) list | None

CAN.set_filters() ile ayarlanan filtrelere göre, denetleyici tarafından alınmış bir CAN mesajı döndürür.

Bu fonksiyon tek bir isteğe bağlı argüman alır; sağlanırsa, ikinci elemanı alınmış herhangi bir CAN mesajını tutmaya yetecek kapasiteye sahip bir bytearray veya benzeri bir nesneye atıfta bulunan bir memoryview nesnesi olan, en az 4 elemanlı bir liste olmalıdır (CAN Classic için 8 bayt, CAN FD için 64 bayt). Sağlanan liste başarılı sonuç olarak döndürülür ve fonksiyon içinde bellek tahsisinden kaçınılır.

CAN denetleyicisi tarafından hiçbir mesaj alınmamışsa, bu fonksiyon None döndürür.

Not

Denetleyici tarafından herhangi bir mesaj alınabilmesi için önce CAN.set_filters çağrılmalıdır. Tüm mesajları almak için set_filters(None) çağırın.

CAN denetleyicisi tarafından bir mesaj alınmışsa, bu fonksiyon 4 elemanlı bir liste döndürür:

  • İndeks 0, alınan mesajın CAN ID’sidir; bir tamsayı olarak.

  • İndeks 1, alınan mesaj verisine erişim sağlayan bir memoryview’dir.

    • arg sağlanmamışsa, bu, alınan baytları tutan bir memoryview‘dir. Bu memoryview, alınmış herhangi bir CAN mesajını tutmaya yetecek büyüklükte yeni tahsis edilmiş bir bytearray ile desteklenir. Bu, bellek tahsislerinden tasarruf etmek için sonucun gelecekteki bir arg olarak güvenle yeniden kullanılmasına olanak tanır.

    • arg sağlanmışsa, sağlanan memoryview, tam olarak alınan baytları tutacak şekilde yeniden boyutlandırılır. memoryview‘i destekleyen nesnenin herhangi bir uzunlukta bir CAN mesajını tutabildiğinden emin olmak çağıranın sorumluluğundadır.

  • İndeks 2, Mesaj Bayrakları içinde tanımlanan bitlerden sıfır veya daha fazlasının ayarlandığı bir tamsayıdır. Alınan mesaj hakkında üst veri belirtir.

  • İndeks 3, Alma Hata Bayrakları içinde tanımlanan bitlerden sıfır veya daha fazlasının ayarlandığı bir tamsayıdır. Sıfırdan farklı herhangi bir değer, CAN mesajlarını alırken olası sorunları gösterir. Bu bayraklar, bu fonksiyon her döndüğünde denetleyici içinde sıfırlanır.

Remote Transmission Request’ler

Bir Remote Transmission Request alınırsa, İndeks 2’de CAN.FLAG_RTR biti ayarlanır ve İndeks 1’deki memoryview, alınan isteğin DLC alanına eşit bir uzunlukla tamamen sıfır içerir.

Örnek
can.set_filters(None)   # receive all
while True:
    res = can.recv()
    if res:
        can_id, data, flags, errs = res
        print("Received", hex(can_id), data.hex(), hex(flags), hex(errs))
    else:
        time.sleep_ms(1)  # not a good pattern, use the irq instead!
irq(handler: Callable[[CAN], None] | None = None, trigger: int = 0, hard: bool = False) None

trigger içinde işaretlenen olaylardan biri veya daha fazlası gerçekleştiğinde çağrılacak bir kesme handler fonksiyonu ayarlar.

  • handler, kesme olayı tetiklendiğinde çağrılacak bir fonksiyondur. Handler, CAN örneği olan tam olarak bir argüman almalıdır.

  • trigger, bir kesme üretebilen olay(lar)ı yapılandırır. Olası değerler, aşağıdakilerden bir veya daha fazlasının maskesidir:

    • CAN.IRQ_RX olayı, CAN denetleyicisi RX FIFO’suna en az bir mesaj aldıktan sonra gerçekleşir (yani CAN.recv() başarıyla dönecektir).

    • CAN.IRQ_TX olayı, CAN denetleyicisi CAN veri yoluna bir mesajı başarıyla gönderdikten veya bir mesaj gönderemedikten sonra gerçekleşir. Bu tetikleyicinin handler için ek gereksinimleri vardır, ayrıntılar için IRQ bayrakları bölümüne bakın.

    • CAN.IRQ_STATE olayı, CAN denetleyicisi daha ağır bir hata durumuna geçtiğinde gerçekleşir. Güncellenmiş durumu almak için CAN.state() çağırın.

  • hard True ise, bir donanım kesmesi kullanılır. Bu, CAN denetleyici olayı ile handler’ın çağrılması arasındaki gecikmeyi azaltır. Donanım kesme handler’ları bellek tahsis edemez; bkz. Kesme işleyicileri yazma.

Bir irq nesnesi döndürür. Argümansız çağrılırsa, daha önce yapılandırılmış bir irq nesnesi döndürülür.

Bir örnek için IRQ bayrakları bölümüne bakın.

cancel_send(index: int) bool

CAN denetleyicisinden bir mesajın veri yoluna gönderilmesini iptal etmesini ister.

index argümanı tek bir iletim arabelleğini tanımlar. 0 ile CAN.TX_QUEUE_LEN (hariç) aralığında bir tamsayı olmalıdır. Genellikle bu, daha önce CAN.send() tarafından döndürülen bir değerdir.

Bu arabellekte iletim için bekleyen bir mesaj varsa ve iletim iptal edildiyse sonuç True olur.

Aksi takdirde sonuç False olur (ya bu arabellekte iletim için bekleyen bir mesaj yoktu ya da iletim zaten başarılı oldu).

Bir mesajın kesinlikle gönderilip gönderilmediğini belirlemek için CAN.IRQ_TX IRQ olayı kullanılmalıdır, ancak bir iletim iptal edilip ardından aynı arabellek başka bir mesaj göndermek için kullanılırsa olası yarış durumları olduğunu unutmayın (özellikle CAN denetleyici IRQ’su “hard” değilse).

state() int

Denetleyicinin mevcut durumunu gösteren bir tamsayı değeri döndürür. Değer, Durumlar içinde tanımlanan değerlerden biri olur.

Daha düşük şiddetteki hata durumları, veri yolu kurtulursa otomatik olarak temizlenebilir, ancak CAN.STATE_BUS_OFF durumu yalnızca CAN.restart() çağrılarak kurtarılabilir.

get_counters(list: list | None = None, /) list

Denetleyicinin hata sayacı değerlerini döndürür. Sonuç sekiz değerden oluşan bir listedir. İsteğe bağlı list parametresi belirtilirse, bir tahsisten kaçınmak için sağlanan liste nesnesi güncellenir ve sonuç olarak döndürülür.

Liste öğeleri şunlardır:

  • TEC (Transmit Error Counter) değeri

  • REC (Receive Error Counter) değeri

  • Denetleyicinin Active durumundan Warning durumuna geçme sayısı.

  • Denetleyicinin Warning durumundan Error Passive durumuna geçme sayısı.

  • Denetleyicinin Error Passive durumundan Bus Off durumuna geçme sayısı.

  • Donanım kuyruğundaki bekleyen toplam TX mesajı sayısı.

  • Donanım kuyruğundaki bekleyen toplam RX mesajı sayısı.

  • Bir RX taşması meydana gelme sayısı.

Not

Denetleyiciye bağlı olarak, bu değerler belirli bir değerden sonra tekrar 0’a taşabilir.

Not

Bir denetleyici belirli bir sayacı desteklemiyorsa, o liste elemanı için None döndürür.

get_timings(list: list | None = None, /) list

CAN denetleyicisinde yapılandırılmış mevcut zamanlamaları gösteren bir eleman listesi döndürür. Bu, hata ayıklama amacıyla zamanlamaları doğrulamak için kullanılabilir. Sonuç altı değerden oluşan bir listedir. İsteğe bağlı list parametresi belirtilirse, bir tahsisten kaçınmak için sağlanan liste nesnesi güncellenir ve sonuç olarak döndürülür.

Liste öğeleri şunlardır:

  • Denetleyici tarafından kullanılan tam bit hızı. Donanım kısıtlamalarını karşılamak için yapılan kuantalama nedeniyle CAN.init() fonksiyonuna geçilen bitrate argümanından farklı olabilir.

  • Nominal bitler için zaman kuantumu birimleri cinsinden yeniden senkronizasyon sıçrama genişliği (SJW). CAN.init() fonksiyonunun sjw parametresiyle aynı anlama gelir.

  • Nominal bitler için zaman kuantumu birimleri cinsinden örnek noktasının konumu. CAN.init() fonksiyonunun tseg1 parametresiyle aynı anlama gelir.

  • Nominal bitler için zaman kuantumu birimleri cinsinden iletim noktasının konumu. CAN.init() fonksiyonunun tseg2 parametresiyle aynı anlama gelir.

  • CAN FD zamanlama bilgisi. CAN FD desteklemeyen denetleyiciler için veya CAN FD başlatılmamışsa None. Aksi takdirde, yukarıdaki öğelere karşılık gelen ancak CAN FD BRS özelliği için geçerli olan dört elemanlı iç içe bir liste.

  • İsteğe bağlı denetleyiciye özgü zamanlama bilgisi. Denetleyiciye bağlı olarak, denetleyici hiçbiri raporlamıyorsa None olur ya da elemanları belirli bir donanım denetleyicisine özgü olan sabit uzunlukta bir liste olur.

Not

CAN.init() çağrılmamışsa, bu fonksiyon yine de bir sonuç döndürür, ancak sonuç denetleyicinin iç yapısına bağlıdır ve doğru olmayabilir.

restart() None

Denetleyicinin, başka herhangi bir iç durumu temizlemeden STATE_BUS_OFF durumundan çıkmasına neden olur. Ayrıca bazı hata sayaçlarını temizler (her zaman her hata durumuna girilme sayısını, denetleyiciye bağlı olarak muhtemelen TEC ve REC’yi).

Bu fonksiyonu çağırmak, gönderilmek için bekleyen tüm mesajları da iptal eder. Bu mesajlar için hiçbir IRQ_TX kesmesi iletilmez.

Bu fonksiyonun, denetleyici donanımının TEC ve REC’yi sıfırlayıp sıfırlamadığına bağlı olarak, denetleyicinin “Error Passive” durumundan çıkmasına neden olabileceğini veya olmayabileceğini unutmayın.

deinit() None

Daha önce etkin olan bir CAN örneğini sonlandırır. Bekleyen tüm mesajlar (iletim ve alma) düşürülür ve denetleyici veri yolunda etkileşimi durdurur. Bu örneği tekrar kullanmak için CAN.init() çağırın.

Bu fonksiyonu çağırmaya yanıt olarak hiçbir IRQ_TX veya IRQ_RX kesmesi çağrılmaz.

Ayrıca bkz. CAN.restart().

Sabitler

TX_QUEUE_LEN: int

Denetleyicinin giden donanım mesaj kuyruğunda kuyruğa alınabilecek maksimum CAN mesajı sayısı. CAN.send(), CAN.cancel_send() ve IRQ bayrakları tarafından kullanılan “iletim arabelleği indeksleri” bu aralıkta olur.

Modlar

Bu değerler, CAN.init() fonksiyonuna geçildiği şekliyle denetleyici çalışma modlarını temsil eder. Tüm denetleyiciler tüm modları desteklemeyebilir.

Çalışan bir denetleyicinin modunu değiştirmek, CAN.deinit() çağrılmasını ve ardından yeni modla CAN.init() fonksiyonunun tekrar çağrılmasını gerektirir.

MODE_NORMAL: int

Denetleyici, standart bir CAN ağ düğümü olarak etkindir (geçerli mesajları onaylar ve mevcut Durumuna bağlı olarak hata iletebilir).

MODE_SLEEP: int

CAN denetleyicisi düşük güç modunda uyuyor. Denetleyiciye bağlı olarak, bu, CAN trafiği alınırsa denetleyicinin uyandırılmasını ve CAN.MODE_NORMAL durumuna geçmesini destekleyebilir.

MODE_LOOPBACK: int

Bir test modu. CAN denetleyicisi hâlâ harici veri yoluna bağlıdır, ancak kendi ilettiği mesajları da alır ve herhangi bir ACK hatasını yok sayar.

MODE_SILENT: int

CAN denetleyicisi mesajları alır ancak CAN veri yoluyla etkileşime girmez (ACK’lar, hatalar, vb. göndermek dahil).

MODE_SILENT_LOOPBACK: int

Hiç CAN alıcı-vericisinin bağlanmasını gerektirmeyen bir test modu. CAN denetleyicisi, CAN veri yoluyla hiç etkileşime girmeden kendi ilettiği mesajları alır. CAN TX ve RX pinleri boşta kalır.

Durumlar

Bu değerler CAN.state() tarafından döndürülür ve CAN denetleyicisinin hata durumunu yansıtır:

STATE_STOPPED: int

Denetleyici başlatılmamış.

STATE_ACTIVE: int

Denetleyici etkindir ve TEC ile REC hata sayaçlarının ikisi de 96’lık uyarı eşiğinin altındadır. Bkz. CAN.get_counters().

STATE_WARNING: int

Denetleyici etkindir ancak TEC ve REC hata sayaçlarından en az biri 96 ile 127 arasındadır. Bkz. CAN.get_counters().

STATE_PASSIVE: int

Denetleyici “Error Passive” durumundadır, yani veri yoluna artık aktif hata iletmez ama bunun dışında işlevseldir. Bu durum, TEC ve REC hata sayaçlarından en az biri 128 veya daha büyük, ancak TEC 255’ten küçük olduğunda girilir. Bkz. CAN.get_counters().

STATE_BUS_OFF: int

Denetleyici Bus-Off durumundadır, yani TEC hata sayacı 255’ten büyüktür. CAN denetleyicisi bu durumda veri yoluyla etkileşime girmez ve devam etmek için CAN.restart() ile yeniden başlatılması gerekir.

Mesaj Bayrakları

Bu değerler bir CAN mesajı hakkında üst veriyi temsil eder. CAN.send(), CAN.recv() ve CAN.set_filters() fonksiyonları, bu bayraklardan sıfır veya daha fazlasının bit düzeyinde OR’lanmasıyla oluşan bir tamsayı değerini ya kabul eder ya da döndürür.

FLAG_RTR: int

Bir mesajın remote transmission request olduğunu gösterir.

FLAG_EXT_ID: int

Ayarlanmışsa, bir mesaj tanımlayıcısının Extended (29-bit) olduğunu gösterir. Ayarlanmamışsa, bir mesaj tanımlayıcısının Standard (11-bit) olduğunu gösterir.

FLAG_UNORDERED: int

CAN.send() fonksiyonunun flags argümanında ayarlanmışsa, aynı CAN ID’sine sahip mesajların veri yoluna herhangi bir sırada gönderilmesinin uygun olduğunu gösterir.

Aksi takdirde, aynı ID ile birden fazla mesaj kuyruğa almaya çalışmak, denetleyici donanımı sıralamayı zorlayamazsa CAN.send() fonksiyonunun başarısız olmasına neden olabilir.

Bu bayrak alınan mesajlarda asla ayarlanmaz ve CAN.set_filters() tarafından yok sayılır.

Alma Hata Bayrakları

CAN.recv() fonksiyonunun sonucu, bu bayraklardan sıfır veya daha fazlasının bit düzeyinde OR’lanmasıyla oluşan bir tamsayı değeri içerir. Ayarlanmışsa, bu bayraklar CAN mesajlarını almayla ilgili olası genel sorunları gösterir.

RECV_ERR_FULL: int

Bu mesajın alındığı donanım FIFO’su doludur ve ek gelen mesajlar kaybolabilir.

RECV_ERR_OVERRUN: int

Bu mesajın alındığı donanım FIFO’su doludur ve bir veya daha fazla gelen mesaj kaybolmuştur.

IRQ değerleri

IRQ_RX: int

CAN denetleyicisi RX FIFO’suna her tam mesaj aldığında handler’ı tetiklemek için irq() fonksiyonunun trigger argümanına geçin. Handler içinde mesajı recv() ile okuyun.

IRQ_TX: int

CAN denetleyicisi her iletim girişimini (başarılı veya başarısız) tamamladığında handler’ı tetiklemek için irq() fonksiyonunun trigger argümanına geçin. Handler içinde, hangi posta kutusunun tamamlandığını ve başarısız olup olmadığını öğrenmek için aşağıdaki ek bitleri kullanın – bkz. IRQ bayrakları.

IRQ_STATE: int

Denetleyici STATE_* değerleri (active / warning / passive / bus-off) arasında her geçiş yaptığında handler’ı tetiklemek için irq() fonksiyonunun trigger argümanına geçin. Yeni durumu okumak için handler içinde state() kullanın.

IRQ_TX_FAILED: int

Bir IRQ_TX olayı tetiklendiğinde irq().flags() içinde ayarlanabilen durum bayrağı. İletim girişiminin başarısız olduğunu gösterir (genellikle cancel_send() çağrıldığı için veya denetleyici bir hata durumuna girdiği için).

IRQ_TX_IDX_SHIFT: int

Bir IRQ_TX olayı sırasında irq().flags() değeri içindeki iletim-posta-kutusu-indeksi alanının bit konumu. Posta kutusu indeksi, (flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK olarak çıkarılır.

IRQ_TX_IDX_MASK: int

Bir IRQ_TX olayı sırasında irq().flags() değeri içindeki iletim-posta-kutusu-indeksi alanının bit maskesi. Çıkarılan indeks, ilgili send() çağrısı tarafından döndürülen tamsayıyla eşleşir (0 ile TX_QUEUE_LEN aralığında bir int).

IRQ bayrakları

CAN.irq() çağrılması, CAN.IRQ_RX, CAN.IRQ_TX ve CAN.IRQ_STATE tetikleyicilerinden biri veya daha fazlasıyla bir kesme handler’ı kaydeder.

Fonksiyon bir IRQ nesnesi döndürür ve bu nesne üzerinde flags() fonksiyonunu çağırmak, kesmeyi hangi tetikleyici olay(lar)ının tetiklediğini gösteren bir tamsayı döndürür. Bir CAN IRQ handler’ı, flags() fonksiyonunu 0 döndürene kadar tekrar tekrar çağırmalıdır.

flags() fonksiyonu CAN.IRQ_TX biti ayarlanmış olarak döndüğünde, handler TX olayı hakkında ek bilgi için sonuçtaki aşağıdaki bayrak bitlerini de kontrol edebilir:

  • İletim başarısız olursa CAN.IRQ_TX_FAILED biti ayarlanır. Genellikle bu yalnızca CAN.cancel_send() çağrıldığında olur, ancak denetleyici bir hata durumuna girerse de olabilir.

  • CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFT, flags değerinin, olayı üreten iletim arabelleğinin indeksini tutan bit maskeli bir bölgesidir. Bu, 0 ile CAN.TX_QUEUE_LEN (hariç) aralığında bir tamsayı olur ve CAN.send() fonksiyonuna yapılan önceki bir çağrının sonucuyla eşleşir.

IRQ_TX Örneği

from machine import CAN

def irq_send(can):
    while flags := can.irq().flags():
        if flags & can.IRQ_TX:
            idx = (flags >> can.IRQ_TX_IDX_SHIFT) & can.IRQ_TX_IDX_MASK
            success = not (flags & can.IRQ_TX_FAILED)
            print("irq_send", idx, success)

can = CAN(1, 500_000)
can.irq(irq_send, trigger=can.IRQ_TX, hard=True)

Önemli

CAN.IRQ_TX tetikleyicisi ayarlanmışsa, bu örnekte gösterildiği gibi handler flags() fonksiyonunu 0 döndürene kadar tekrar tekrar çağırmak zorundadır. Aksi takdirde CAN kesmeleri doğru şekilde yeniden etkinleştirilemeyebilir.