třída CAN – protokol Controller Area Network

CAN je dvouvodičový sériový protokol používaný pro spolehlivé doručování zpráv v reálném čase mezi jedním nebo více uzly připojenými ke společné sběrnici. CAN 2.0 byl standardizován v ISO-11898 a dnes je znám také jako CAN Classic.

Existuje také novější, zpětně kompatibilní protokol s názvem CAN FD (CAN with Flexible Data-Rate). Ovladač machine.CAN v současnosti funkce CAN FD nepodporuje; pokud potřebujete CAN FD, použijte na STM32 třídu pyb.CAN.

Podpora CAN vyžaduje řadič (často interní periferii mikrokontroléru) a externí transceiver, který posune úroveň signálů na sběrnici CAN.

Dostupné na STM32 kamerách OpenMV (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, plus varianty se značkou Arduino, které zapojují transceiver). Zatím nepodporováno na OpenMV Cam RT1062 (port mimxrt) ani na OpenMV Cam AE3 (port alif).

Rozhraní machine.CAN je nízkoúrovňové základní rozhraní pro zasílání zpráv CAN, které abstrahuje řadič CAN jako odchozí prioritní frontu pro odesílání zpráv, příchozí frontu pro příjem zpráv a mechanismy pro hlášení chyb.

Poznámka

Plánované moduly micropython-lib can a aiocan budou doporučeným způsobem použití CAN s MicroPythonem.

Konstruktor

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

Vytvoří objekt řadiče CAN s daným id:

  • id identifikuje konkrétní objekt řadiče CAN; je specifické pro desku a port.

  • Všechny ostatní argumenty se předávají do CAN.init(). Musí být zadán alespoň jeden argument (bitrate).

Budoucí verze této třídy zde mohou přijímat také klíčová slova specifická pro port, která konfigurují hardware. V současnosti nejsou žádná taková klíčová slova implementována.

Příklad

Vytvoření a inicializace řadiče CAN 1 s přenosovou rychlostí 500 kb/s:

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

Metody

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

Inicializuje sběrnici CAN se zadanými parametry:

  • bitrate je požadovaná přenosová rychlost sběrnice v bitech za sekundu.

  • mode je jedna z hodnot uvedených v Režimy a určuje požadovaný režim provozu. Výchozí je „normální“ provoz na sběrnici.

Další parametry jsou volitelné a souvisejí s časováním bitů CAN. Ve většině případů můžete tyto parametry ponechat na výchozích hodnotách:

  • sample_point je celočíselné procento doby datového bitu. Určuje pozici vzorkování bitu vzhledem k celé nominální době bitu. Ovladač CAN podle toho vypočítá parametry. Tento parametr je ignorován, pokud jsou nastaveny tseg1 a tseg2.

  • sjw je šířka resynchronizačního skoku v jednotkách časových kvant pro nominální bity; pro klasický CAN to může být hodnota v rozsahu od 1 do 4 včetně.

  • tseg1 definuje umístění vzorkovacího bodu v jednotkách časových kvant pro nominální bity; pro klasický CAN to může být hodnota v rozsahu od 1 do 16 včetně. Jedná se o součet fází Prop_Seg a Phase_Seg1 definovaných v normě ISO-11898. Pokud je tato hodnota nastavena, musí být nastaven také tseg2 a sample_point je ignorován.

  • tseg2 definuje umístění bodu vysílání v jednotkách časových kvant pro nominální bity; pro klasický CAN to může být hodnota v rozsahu od 1 do 8 včetně. Odpovídá Phase_Seg2 v normě ISO-11898. Pokud je tato hodnota nastavena, musí být nastaven také tseg1.

Pokud jsou tyto argumenty zadány, je řadič CAN správně nakonfigurován pro požadovaný bitrate a zadaný celkový počet časových kvant na bit. Hodnoty tseg1 a tseg2 mají přednost před argumentem sample_point, pokud jsou všechny zadány.

Poznámka

Konkrétní hardware řadiče může mít dodatečná omezení platných hodnot těchto parametrů a vyvolá ValueError, pokud daná hodnota není podporována.

Poznámka

Konkrétní hardware řadiče může přijímat dodatečné volitelné klíčové parametry pro funkce specifické pro hardware, jako je nadvzorkování.

set_filters(filters: list | tuple | None) None

Nastaví přijímací filtry v řadiči CAN. filters může být:

  • None pro přijetí všech příchozích zpráv, nebo

  • [] nebo () pro zakázání příjmu všech zpráv, nebo

  • iterovatelný objekt s jednou nebo více položkami definujícími kritéria filtru. Každá položka by měla být n-tice nebo seznam se třemi prvky:

    • identifier je identifikátor CAN (int).

    • bit_mask je bitová maska pro bity v poli identifikátoru CAN (int).

    • flags je celé číslo s nula nebo více bity definovanými v Příznaky zpráv. Určuje vlastnosti, kterým musí příchozí zpráva odpovídat. Ne všechny řadiče podporují filtrování podle všech příznaků; pokud je požadován nepodporovaný příznak, je vyvolán ValueError.

Příchozí zprávy jsou přijaty, pokud bity maskované v bit_mask souhlasí mezi identifikátorem zprávy a hodnotou identifier filtru a příznaky nastavené ve filtru odpovídají příchozí zprávě.

Pokud je v příznacích nastaven bit CAN.FLAG_EXT_ID, filtr odpovídá pouze rozšířeným CAN ID. Pokud bit CAN.FLAG_EXT_ID nastaven není, filtr odpovídá pouze standardním CAN ID.

Všechny filtry jsou v řadiči spojeny operací OR. Předání prázdného seznamu nebo n-tice jako argumentu filtrů znamená, že nebudou přijaty žádné zprávy.

Některé řadiče CAN vyžadují, aby byl každý filtr přidružen pouze k jedné přijímací FIFO. V těchto případech jsou položky filtrů v argumentu přidělovány dostupným FIFO metodou round-robin. Tento ovladač v přijímacím IRQ mezi jednotlivými FIFO nerozlišuje.

Poznámka

Pokud volající předá iterovatelný objekt s více položkami, než je CAN.FILTERS_MAX, bude vyvolán ValueError.

Poznámka

Pokud je identifier nebo bit_mask mimo rozsah pro zadaný typ ID, bude vyvolán ValueError s důvodem „invalid id“.

Příklady

Příjem všech příchozích zpráv:

can.set_filters(None)

Příjem pouze zpráv se standardními hodnotami ID 0x301 a 0x700:

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

Příjem pouze zpráv se standardními hodnotami ID v rozsahu 0x300-0x3FF a rozšířenou hodnotou ID 0x50700:

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

Konstantní hodnota, která vrací maximální počet podporovaných přijímacích filtrů pro tento hardwarový řadič.

Mějte na paměti, že některé řadiče mohou mít složitější hardwarová omezení počtu používaných filtrů (například nezávislé počítání filtrů standardních a rozšířených ID). V těchto případech může CAN.set_filters vyvolat ValueError i tehdy, když není překročen limit FILTERS_MAX.

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

Zkopíruje novou zprávu CAN do hardwarové vysílací fronty řadiče, aby byla odeslána na sběrnici. Vysílací fronta je prioritní fronta seřazená podle priority identifikátoru CAN (nižší číselné identifikátory mají vyšší prioritu).

  • id je celočíselná hodnota identifikátoru CAN.

  • data je objekt typu bytes (nebo podobný) obsahující data zprávy CAN, nebo popisující Remote Transmission Request (viz níže).

  • flags je celé číslo s nula nebo více bity definovanými v Příznaky zpráv, určující vlastnosti odchozí zprávy CAN (rozšířené ID, Remote Transmission Request atd.)

Pokud je zpráva úspěšně zařazena do fronty k odeslání na sběrnici, funkce vrátí celé číslo v rozsahu 0CAN.TX_QUEUE_LEN (nezahrnuje horní hranici). Tato hodnota je index vysílacího bufferu, kde je zpráva zařazena k odeslání, a lze ji použít funkcí CAN.cancel_send a v událostech CAN.IRQ_TX.

Pokud je fronta plná, odeslání selže a je vráceno None.

Odeslání může také selhat a vrátit None, pokud má zadaná hodnota id stejnou prioritu jako existující zpráva ve vysílací frontě a hardware řadiče CAN nemůže zaručit, že zprávy se stejným ID budou odeslány na sběrnici ve stejném pořadí, v jakém byly přidány do fronty. Chcete-li zprávu přesto zařadit do fronty, předejte v argumentu flags příznak CAN.FLAG_UNORDERED. Tento příznak označuje, že je v pořádku odesílat zprávy se stejným CAN ID na sběrnici v libovolném pořadí.

Pokud je řadič v chybovém stavu „Bus Off“ nebo je zakázán, volání této funkce vyvolá OSError.

Poznámka

Tato záměrně nízkoúrovňová implementace je navržena tak, aby volající mohl vytvořit softwarovou frontu odchozích zpráv.

Důležité

„Vysílací fronta“ CAN není FIFO fronta, je seřazena podle priority, a přestože může pojmout až CAN.TX_QUEUE_LEN položek, mohou existovat další hardwarová omezení zpráv, které lze zařadit do fronty současně.

Remote Transmission Requests

Pokud je v argumentu flags nastaven bit CAN.FLAG_RTR, řadič odešle místo zprávy Remote Transmission Request. V tomto případě je obsah argumentu data ignorován. Řadič odešle požadavek, kde se délkové pole DLC rovná délce argumentu data.

Příklady

Pokus o odeslání zprávy s tříbajtovým obsahem 0a0b0c a standardním ID 0x200:

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

Pokus o odeslání zprávy s prázdným obsahem a rozšířeným ID 0x180008. Indikujte, že řadič může odesílat zprávy s tímto ID v libovolném pořadí, pro případ že jsou již ve frontě k odeslání jiné zprávy se stejným ID:

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

Pokus o odeslání Remote Transmission Request s délkou 8 bajtů a standardním ID 0x555:

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

Vrátí zprávu CAN, kterou řadič přijal, podle filtrů nastavených funkcí CAN.set_filters().

Tato funkce přijímá jediný volitelný argument; pokud je zadán, musí být seznamem s alespoň 4 prvky, kde druhý prvek je objekt memoryview odkazující na objekt bytearray nebo podobný s dostatečnou kapacitou pro uložení libovolné přijaté zprávy CAN (8 bajtů pro CAN Classic, 64 bajtů pro CAN FD). Zadaný seznam bude vrácen jako úspěšný výsledek a zabrání alokaci paměti uvnitř funkce.

Pokud řadič CAN nepřijal žádné zprávy, tato funkce vrátí None.

Poznámka

Než řadič může přijmout jakékoli zprávy, musí být zavolána funkce CAN.set_filters. Chcete-li přijímat všechny zprávy, zavolejte set_filters(None).

Pokud řadič CAN přijal zprávu, tato funkce vrátí seznam se 4 prvky:

  • Index 0 je CAN ID přijaté zprávy jako celé číslo.

  • Index 1 je memoryview poskytující přístup k datům přijaté zprávy.

    • Pokud arg není zadán, jedná se o memoryview obsahující přijaté bajty. Toto memoryview je podloženo nově alokovaným bytearray dostatečně velkým pro uložení libovolné přijaté zprávy CAN. To umožňuje bezpečné opětovné použití výsledku jako budoucího arg a šetří alokace paměti.

    • Pokud je arg zadán, bude zadané memoryview změněno tak, aby obsahovalo přesně přijaté bajty. Volající je zodpovědný za zajištění toho, aby podkladový objekt pro memoryview mohl pojmout zprávu CAN libovolné délky.

  • Index 2 je celé číslo s nula nebo více bity definovanými v Příznaky zpráv. Označuje metadata přijaté zprávy.

  • Index 3 je celé číslo s nula nebo více bity definovanými v Příznaky chyb příjmu. Jakákoli nenulová hodnota indikuje potenciální problémy při příjmu zpráv CAN. Tyto příznaky jsou v řadiči resetovány při každém návratu této funkce.

Remote Transmission Requests

Pokud je přijat Remote Transmission Request, bude na indexu 2 nastaven bit CAN.FLAG_RTR a memoryview na indexu 1 bude obsahovat samé nuly, s délkou rovnou poli DLC přijatého požadavku.

Příklad
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

Nastaví funkci obslužné rutiny přerušení handler, která se zavolá, když nastane jedna nebo více událostí označených v trigger.

  • handler je funkce, která se zavolá při spuštění události přerušení. Obslužná rutina musí přijímat přesně jeden argument, kterým je instance CAN.

  • trigger konfiguruje událost(i), které mohou generovat přerušení. Možné hodnoty jsou maska jedné nebo více z následujících:

    • Událost CAN.IRQ_RX nastane poté, co řadič CAN přijal alespoň jednu zprávu do své RX FIFO (což znamená, že CAN.recv() se vrátí úspěšně).

    • Událost CAN.IRQ_TX nastane poté, co řadič CAN buď úspěšně odeslal zprávu na sběrnici CAN, nebo odeslání zprávy selhalo. Tento trigger má pro obslužnou rutinu další požadavky, podrobnosti viz Příznaky IRQ.

    • Událost CAN.IRQ_STATE nastane, když řadič CAN přejde do závažnějšího chybového stavu. Aktualizovaný stav získáte voláním CAN.state().

  • hard pokud je True, použije se tvrdé přerušení. To snižuje zpoždění mezi událostí řadiče CAN a voláním obslužné rutiny. Obslužné rutiny tvrdých přerušení nesmějí alokovat paměť; viz Psaní obslužných rutin přerušení.

Vrací objekt irq. Pokud je voláno bez argumentů, vrátí se dříve nakonfigurovaný objekt irq.

Příklad viz Příznaky IRQ.

cancel_send(index: int) bool

Požádá řadič CAN o zrušení odesílání zprávy na sběrnici.

Argument index identifikuje jeden vysílací buffer. Měl by to být celé číslo v rozsahu 0CAN.TX_QUEUE_LEN (nezahrnuje horní hranici). Obvykle to bude hodnota dříve vrácená funkcí CAN.send().

Výsledek je True, pokud v tomto bufferu čekala zpráva k odeslání a odeslání bylo zrušeno.

V opačném případě je výsledek False (buď v tomto bufferu nečekala žádná zpráva k odeslání, nebo odeslání již proběhlo úspěšně).

Pro zjištění, zda byla zpráva s jistotou odeslána či nikoli, by se měla použít událost IRQ CAN.IRQ_TX, ale mějte na paměti, že existují potenciální souběhy, pokud je odeslání zrušeno a poté je stejný buffer použit k odeslání jiné zprávy (zejména pokud IRQ řadiče CAN není „tvrdé“).

state() int

Vrací celočíselnou hodnotu indikující aktuální stav řadiče. Hodnota bude jednou z hodnot definovaných v Stavy.

Chybové stavy nižší závažnosti se mohou automaticky vymazat, pokud se sběrnice zotaví, ale ze stavu CAN.STATE_BUS_OFF lze obnovit pouze voláním CAN.restart().

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

Vrací hodnoty čítačů chyb řadiče. Výsledek je seznam osmi hodnot. Pokud je zadán volitelný parametr list, je zadaný objekt seznamu aktualizován a vrácen jako výsledek, aby se zabránilo alokaci.

Položky seznamu jsou:

  • hodnota TEC (Transmit Error Counter)

  • hodnota REC (Receive Error Counter)

  • Počet případů, kdy řadič přešel ze stavu Active do stavu Warning.

  • Počet případů, kdy řadič přešel ze stavu Warning do stavu Error Passive.

  • Počet případů, kdy řadič přešel ze stavu Error Passive do stavu Bus Off.

  • Celkový počet čekajících TX zpráv v hardwarové frontě.

  • Celkový počet čekajících RX zpráv v hardwarové frontě.

  • Počet případů, kdy došlo k přetečení RX.

Poznámka

V závislosti na řadiči mohou tyto hodnoty po dosažení určité hodnoty přetéct zpět na 0.

Poznámka

Pokud řadič nepodporuje určitý čítač, vrátí pro tento prvek seznamu None.

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

Vrací seznam prvků indikujících aktuální časování nakonfigurovaná v řadiči CAN. Lze jej použít k ověření časování pro účely ladění. Výsledek je seznam šesti hodnot. Pokud je zadán volitelný parametr list, je zadaný objekt seznamu aktualizován a vrácen jako výsledek, aby se zabránilo alokaci.

Položky seznamu jsou:

  • Přesná přenosová rychlost použitá řadičem. Může se lišit od argumentu bitrate předaného do CAN.init() kvůli kvantizaci za účelem splnění hardwarových omezení.

  • Šířka resynchronizačního skoku (SJW) v jednotkách časových kvant pro nominální bity. Má stejný význam jako parametr sjw funkce CAN.init().

  • Umístění vzorkovacího bodu v jednotkách časových kvant pro nominální bity. Má stejný význam jako parametr tseg1 funkce CAN.init().

  • Umístění bodu vysílání v jednotkách časových kvant pro nominální bity. Má stejný význam jako parametr tseg2 funkce CAN.init().

  • Informace o časování CAN FD. None pro řadiče, které nepodporují CAN FD, nebo pokud CAN FD není inicializován. Jinak vnořený seznam čtyř prvků odpovídajících výše uvedeným položkám, ale platných pro funkci BRS CAN FD.

  • Volitelné informace o časování specifické pro řadič. V závislosti na řadiči to bude buď None, pokud řadič žádné nehlásí, nebo to bude seznam konstantní délky, jehož prvky jsou specifické pro konkrétní hardwarový řadič.

Poznámka

Pokud nebyla zavolána CAN.init(), tato funkce přesto vrátí výsledek, ale výsledek závisí na vnitřních záležitostech řadiče a nemusí být přesný.

restart() None

Způsobí, že řadič opustí stav STATE_BUS_OFF, aniž by vymazal jakýkoli jiný vnitřní stav. Vymaže také některé čítače chyb (vždy počet přechodů do jednotlivých chybových stavů, případně TEC a REC v závislosti na řadiči).

Volání této funkce také zruší všechny zprávy čekající na odeslání. Pro tyto zprávy nejsou doručena žádná přerušení IRQ_TX.

Mějte na paměti, že tato funkce může, ale nemusí způsobit, že řadič opustí stav „Error Passive“, podle toho, zda hardware řadiče vynuluje TEC a REC, nebo ne.

deinit() None

Deinicializuje dříve aktivní instanci CAN. Všechny čekající zprávy (vysílané i přijímané) jsou zahozeny a řadič přestane interagovat na sběrnici. Chcete-li tuto instanci znovu použít, zavolejte CAN.init().

V reakci na volání této funkce nejsou volána žádná přerušení IRQ_TX ani IRQ_RX.

Viz také CAN.restart().

Konstanty

TX_QUEUE_LEN: int

Maximální počet zpráv CAN, které lze zařadit do odchozí hardwarové fronty zpráv řadiče. „Indexy vysílacího bufferu“ používané CAN.send(), CAN.cancel_send() a Příznaky IRQ budou v tomto rozsahu.

Režimy

Tyto hodnoty představují provozní režimy řadiče, předávané do CAN.init(). Ne všechny řadiče mohou podporovat všechny režimy.

Změna režimu běžícího řadiče vyžaduje volání CAN.deinit() a poté opětovné volání CAN.init() s novým režimem.

MODE_NORMAL: int

Řadič je aktivní jako standardní uzel sítě CAN (potvrzuje platné zprávy a může vysílat chyby v závislosti na svém aktuálním Stavu).

MODE_SLEEP: int

Řadič CAN spí v úsporném režimu. V závislosti na řadiči to může podporovat probuzení řadiče a přechod do CAN.MODE_NORMAL, pokud je přijat provoz CAN.

MODE_LOOPBACK: int

Testovací režim. Řadič CAN je stále připojen k externí sběrnici, ale bude také přijímat své vlastní odeslané zprávy a ignorovat veškeré chyby ACK.

MODE_SILENT: int

Řadič CAN přijímá zprávy, ale neinteraguje se sběrnicí CAN (včetně odesílání ACK, chyb atd.)

MODE_SILENT_LOOPBACK: int

Testovací režim, který nevyžaduje vůbec žádné připojení transceiveru CAN. Řadič CAN přijímá své vlastní odeslané zprávy, aniž by jakkoli interagoval se sběrnicí CAN. Piny TX a RX řadiče CAN zůstávají nečinné.

Stavy

Tyto hodnoty vrací CAN.state() a odrážejí chybový stav řadiče CAN:

STATE_STOPPED: int

Řadič nebyl inicializován.

STATE_ACTIVE: int

Řadič je aktivní a oba čítače chyb TEC a REC jsou pod varovným prahem 96. Viz CAN.get_counters().

STATE_WARNING: int

Řadič je aktivní, ale alespoň jeden z čítačů chyb TEC a REC je mezi 96 a 127. Viz CAN.get_counters().

STATE_PASSIVE: int

Řadič je ve stavu „Error Passive“, což znamená, že již nevysílá aktivní chyby na sběrnici, ale jinak je funkční. Do tohoto stavu se přechází, když je alespoň jeden z čítačů chyb TEC a REC roven 128 nebo větší, ale TEC je menší než 255. Viz CAN.get_counters().

STATE_BUS_OFF: int

Řadič je ve stavu Bus-Off, což znamená, že čítač chyb TEC je větší než 255. Řadič CAN v tomto stavu nebude interagovat se sběrnicí a pro pokračování je třeba jej restartovat pomocí CAN.restart().

Příznaky zpráv

Tyto hodnoty představují metadata zprávy CAN. Funkce CAN.send(), CAN.recv() a CAN.set_filters() buď přijímají, nebo vracejí celočíselnou hodnotu složenou z nula nebo více těchto příznaků spojených bitovým OR.

FLAG_RTR: int

Indikuje, že zpráva je remote transmission request.

FLAG_EXT_ID: int

Pokud je nastaven, indikuje, že identifikátor zprávy je rozšířený (29bitový). Pokud nastaven není, indikuje, že identifikátor zprávy je standardní (11bitový).

FLAG_UNORDERED: int

Pokud je nastaven v argumentu flags funkce CAN.send(), indikuje, že je v pořádku, jsou-li zprávy se stejným CAN ID odeslány na sběrnici v libovolném pořadí.

Jinak může pokus o zařazení více zpráv se stejným ID do fronty způsobit selhání CAN.send(), pokud hardware řadiče nemůže vynutit pořadí.

Tento příznak není nikdy nastaven na přijatých zprávách a je ignorován funkcí CAN.set_filters().

Příznaky chyb příjmu

Výsledek CAN.recv() zahrnuje celočíselnou hodnotu složenou z nula nebo více těchto příznaků spojených bitovým OR. Pokud jsou nastaveny, tyto příznaky indikují potenciální obecné problémy s příjmem zpráv CAN.

RECV_ERR_FULL: int

Hardwarová FIFO, do které byla tato zpráva přijata, je plná a další příchozí zprávy mohou být ztraceny.

RECV_ERR_OVERRUN: int

Hardwarová FIFO, do které byla tato zpráva přijata, je plná a jedna nebo více příchozích zpráv byla ztracena.

Hodnoty IRQ

IRQ_RX: int

Předejte do argumentu trigger funkce irq(), aby se obslužná rutina spustila pokaždé, když řadič CAN přijme kompletní zprávu do RX FIFO. Uvnitř obslužné rutiny přečtěte zprávu pomocí recv().

IRQ_TX: int

Předejte do argumentu trigger funkce irq(), aby se obslužná rutina spustila pokaždé, když řadič CAN dokončí pokus o vysílání (úspěch nebo selhání). Uvnitř obslužné rutiny použijte níže uvedené dodatečné bity ke zjištění, která mailbox byla dokončena a zda selhala – viz Příznaky IRQ.

IRQ_STATE: int

Předejte do argumentu trigger funkce irq(), aby se obslužná rutina spustila pokaždé, když řadič přejde mezi hodnotami STATE_* (active / warning / passive / bus-off). Pro přečtení nového stavu použijte uvnitř obslužné rutiny state().

IRQ_TX_FAILED: int

Stavový příznak, který může být nastaven v irq().flags(), když nastane událost IRQ_TX. Indikuje, že pokus o vysílání selhal (typicky proto, že bylo zavoláno cancel_send(), nebo řadič přešel do chybového stavu).

IRQ_TX_IDX_SHIFT: int

Bitová pozice pole indexu vysílací mailboxu v hodnotě irq().flags() během události IRQ_TX. Index mailboxu se extrahuje jako (flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.

IRQ_TX_IDX_MASK: int

Bitová maska pole indexu vysílací mailboxu v hodnotě irq().flags() během události IRQ_TX. Extrahovaný index odpovídá celému číslu vrácenému odpovídajícím voláním send() (int v rozsahu 0TX_QUEUE_LEN).

Příznaky IRQ

Volání CAN.irq() registruje obslužnou rutinu přerušení s jedním nebo více triggery CAN.IRQ_RX, CAN.IRQ_TX a CAN.IRQ_STATE.

Funkce vrací objekt IRQ a volání funkce flags() na tomto objektu vrací celé číslo indikující, která událost (události) triggeru spustila přerušení. Obslužná rutina IRQ CAN by měla volat funkci flags() opakovaně, dokud nevrátí 0.

Když se funkce flags() vrátí s nastaveným bitem CAN.IRQ_TX, může obslužná rutina ve výsledku zkontrolovat také následující bity příznaků pro dodatečné informace o události TX:

  • Bit CAN.IRQ_TX_FAILED je nastaven, pokud vysílání selhalo. Obvykle k tomu dojde pouze tehdy, pokud bylo zavoláno CAN.cancel_send(), ačkoli k tomu může dojít také tehdy, pokud řadič přejde do chybového stavu.

  • CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFT je bitově maskovaná oblast hodnoty příznaků, která obsahuje index vysílacího bufferu, jenž událost vygeneroval. Bude to celé číslo v rozsahu 0CAN.TX_QUEUE_LEN (nezahrnuje horní hranici) a bude odpovídat výsledku předchozího volání CAN.send().

Příklad IRQ_TX

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)

Důležité

Pokud je nastaven trigger CAN.IRQ_TX, obslužná rutina musí volat flags() opakovaně, dokud nevrátí 0, jak je ukázáno v tomto příkladu. Jinak nemusí být přerušení CAN správně znovu povolena.