class CAN – protokollet Controller Area Network

CAN är ett tvåtrådigt seriellt protokoll som används för tillförlitlig leverans av meddelanden i realtid mellan en eller flera noder anslutna till en gemensam buss. CAN 2.0 standardiserades i ISO-11898 och kallas numera även CAN Classic.

Det finns även ett nyare, bakåtkompatibelt protokoll som heter CAN FD (CAN with Flexible Data-Rate). Drivrutinen machine.CAN stöder för närvarande inte CAN FD-funktioner; använd pyb.CAN på STM32 om du behöver CAN FD.

CAN-stöd kräver en styrenhet (ofta en intern kringutrustning i mikrokontrollern) och en extern transceiver för att nivåanpassa signalerna till CAN-bussen.

Tillgängligt på STM32 OpenMV-kameror (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, samt de Arduino-märkta varianterna som har en transceiver inkopplad). Stöds ännu inte på OpenMV Cam RT1062 (mimxrt-porten) eller OpenMV Cam AE3 (alif-porten).

Gränssnittet machine.CAN är ett lågnivå-grundläggande CAN-meddelandegränssnitt som abstraherar en CAN-styrenhet som en utgående prioritetskö för att skicka meddelanden, en inkommande kö för att ta emot meddelanden, och mekanismer för att rapportera fel.

Anteckning

De planerade micropython-lib-modulerna can och aiocan kommer att vara det rekommenderade sättet att använda CAN med MicroPython.

Konstruktor

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

Skapa ett CAN-styrenhetsobjekt med det givna id:t:

  • id identifierar ett visst CAN-styrenhetsobjekt; det är kort- och portspecifikt.

  • Alla övriga argument skickas vidare till CAN.init(). Minst ett argument (bitrate) måste anges.

Framtida versioner av denna klass kan även komma att acceptera portspecifika nyckelordsargument här som konfigurerar hårdvaran. För närvarande finns inga sådana nyckelordsargument implementerade.

Exempel

Skapa och initiera CAN-styrenhet 1 med bithastigheten 500 kbps:

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

Metoder

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

Initiera CAN-bussen med de givna parametrarna:

  • bitrate är den önskade bithastigheten på bussen i bitar per sekund.

  • mode är ett av värdena som visas under Lägen och anger det önskade driftläget. Standardvärdet är ”normal” drift på bussen.

Nästa parametrar är valfria och rör CAN-bittiming. I de flesta fall kan du lämna dessa parametrar inställda på standardvärdena:

  • sample_point är en heltalsprocent av databittiden. Den anger positionen för bitprovet i förhållande till hela den nominella bittiden. CAN-drivrutinen beräknar parametrarna därefter. Denna parameter ignoreras om tseg1 och tseg2 är inställda.

  • sjw är resynkroniseringssprångbredden i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 4 inklusive för klassisk CAN.

  • tseg1 definierar provpunktens placering i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 16 inklusive för klassisk CAN. Detta är summan av faserna Prop_Seg och Phase_Seg1 enligt definitionen i standarden ISO-11898. Om detta värde anges måste även tseg2 anges och sample_point ignoreras.

  • tseg2 definierar sändpunktens placering i enheter av tidskvanta för nominella bitar; den kan vara ett värde mellan 1 och 8 inklusive för klassisk CAN. Detta motsvarar Phase_Seg2 i standarden ISO-11898. Om detta värde anges måste även tseg1 anges.

Om dessa argument anges konfigureras CAN-styrenheten korrekt för den önskade bitrate och det angivna totala antalet tidskvanta per bit. Värdena tseg1 och tseg2 åsidosätter argumentet sample_point om alla dessa anges.

Anteckning

Enskild styrenhetshårdvara kan ha ytterligare begränsningar för giltiga värden på dessa parametrar och kommer att utlösa ett ValueError om ett givet värde inte stöds.

Anteckning

Specifik styrenhetshårdvara kan acceptera ytterligare valfria nyckelordsparametrar för hårdvaruspecifika funktioner såsom översampling.

set_filters(filters: list | tuple | None) None

Ställ in mottagningsfilter i CAN-styrenheten. filters kan vara:

  • None för att acceptera alla inkommande meddelanden, eller

  • [] eller () för att inaktivera all mottagning av meddelanden, eller

  • En itererbar samling med en eller flera poster som definierar filterkriterierna. Varje post bör vara en tupel eller lista med tre element:

    • identifier är en CAN-identifierare (int).

    • bit_mask är en bitmask för bitar i CAN-identifierarfältet (int).

    • flags är ett heltal med noll eller fler av bitarna som definieras i Meddelandeflaggor satta. Detta anger egenskaper som det inkommande meddelandet måste matcha. Alla styrenheter stöder inte filtrering på alla flaggor; ett ValueError utlöses om en flagga som inte stöds begärs.

Inkommande meddelanden accepteras om bitarna som maskeras i bit_mask matchar mellan meddelandeidentifieraren och filtrets värde identifier, och flaggor satta i filtret matchar det inkommande meddelandet.

Om biten CAN.FLAG_EXT_ID är satt i flaggorna matchar filtret endast Extended CAN-ID:n. Om biten CAN.FLAG_EXT_ID inte är satt matchar filtret endast Standard CAN-ID:n.

Alla filter ELLER-kombineras i styrenheten. Att skicka en tom lista eller tupel som argumentet filters innebär att inga meddelanden kommer att tas emot.

Vissa CAN-styrenheter kräver att varje filter associeras med endast en mottagnings-FIFO. I dessa fall fördelas filterposterna i argumentet enligt round-robin till de tillgängliga FIFO:erna. Denna drivrutin skiljer inte mellan FIFO:er i mottagnings-IRQ:n.

Anteckning

Om anroparen skickar en itererbar samling med fler poster än CAN.FILTERS_MAX utlöses ValueError.

Anteckning

Om antingen identifier eller bit_mask ligger utanför intervallet för den angivna ID-typen utlöses ett ValueError med orsaken ”invalid id”.

Exempel

Ta emot alla inkommande meddelanden:

can.set_filters(None)

Ta emot endast meddelanden med Standard ID-värdena 0x301 och 0x700:

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

Ta emot meddelanden med Standard ID-värden i intervallet 0x300-0x3FF och endast Extended ID-värdet 0x50700:

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

Konstant värde som läser av det maximala antalet mottagningsfilter som stöds för denna hårdvarustyrenhet.

Observera att vissa styrenheter kan ha mer komplexa hårdvarubegränsningar för antalet filter som används (till exempel genom att räkna Standard- och Extended ID-filter separat). I dessa fall kan CAN.set_filters utlösa ett ValueError även när gränsen FILTERS_MAX inte överskrids.

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

Kopiera ett nytt CAN-meddelande till styrenhetens hårdvarusändningskö för att skickas ut på bussen. Sändningskön är en prioritetskö sorterad efter CAN-identifierarprioritet (lägre numeriska identifierare har högre prioritet).

  • id är ett CAN-identifierarvärde av heltalstyp.

  • data är ett bytes-objekt (eller liknande) som innehåller CAN-meddelandedata, eller som beskriver en Remote Transmission Request (se nedan).

  • flags är ett heltal med noll eller fler av bitarna som definieras i Meddelandeflaggor satta, och anger egenskaper för det utgående CAN-meddelandet (Extended ID, Remote Transmission Request, osv.)

Om meddelandet köas för sändning på bussen returnerar funktionen ett heltal i intervallet 0 till CAN.TX_QUEUE_LEN (exklusivt). Detta värde är det sändningsbuffertindex där meddelandet köas för sändning och kan användas av funktionen CAN.cancel_send och i CAN.IRQ_TX-händelser.

Om kön är full misslyckas sändningen och None returneras.

Sändningen kan också misslyckas och returnera None om det angivna id-värdet har samma prioritet som ett befintligt meddelande i sändningskön och CAN-styrenhetshårdvaran inte kan garantera att meddelanden med samma ID skickas ut på bussen i samma ordning som de lades till i kön. För att ändå köa meddelandet, skicka flaggan CAN.FLAG_UNORDERED i argumentet flags. Denna flagga anger att det är OK att skicka meddelanden med samma CAN-ID ut på bussen i valfri ordning.

Om styrenheten befinner sig i feltillståndet ”Bus Off” eller är inaktiverad kommer ett anrop av denna funktion att utlösa ett OSError.

Anteckning

Denna avsiktligt lågnivåimplementering är utformad så att anroparen kan upprätta en mjukvarukö av utgående meddelanden.

Viktigt

CAN-”sändningskön” är inte en FIFO-kö, den är prioritetsordnad, och även om den kan rymma upp till CAN.TX_QUEUE_LEN poster kan det finnas andra hårdvarubegränsningar för meddelanden som kan köas samtidigt.

Remote Transmission Requests

Om biten CAN.FLAG_RTR är satt i argumentet flags skickar styrenheten en Remote Transmission Request istället för ett meddelande. I detta fall ignoreras innehållet i argumentet data. Styrenheten skickar en begäran där längdfältet DLC är lika med längden på argumentet data.

Exempel

Försök att skicka ett meddelande med en nyttolast på tre byte 0a0b0c och Standard ID 0x200:

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

Försök att skicka ett meddelande med en tom nyttolast och Extended ID 0x180008. Ange att styrenheten kan skicka meddelanden med detta ID i valfri ordning, ifall andra meddelanden redan är köade för sändning med samma ID:

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

Försök att skicka en Remote Transmission Request med längden 8 byte och Standard ID 0x555:

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

Returnera ett CAN-meddelande som har tagits emot av styrenheten, enligt filter inställda med CAN.set_filters().

Denna funktion tar ett enda valfritt argument; om det anges måste det vara en lista med minst 4 element där det andra elementet är ett memoryview-objekt som refererar till ett bytearray eller liknande objekt med tillräcklig kapacitet för att rymma vilket mottaget CAN-meddelande som helst (8 byte för CAN Classic, 64 byte för CAN FD). Den angivna listan returneras som ett lyckat resultat och undviker minnesallokering inuti funktionen.

Om inga meddelanden har tagits emot av CAN-styrenheten returnerar denna funktion None.

Anteckning

CAN.set_filters måste anropas innan några meddelanden kan tas emot av styrenheten. För att ta emot alla meddelanden, anropa set_filters(None).

Om ett meddelande har tagits emot av CAN-styrenheten returnerar denna funktion en lista med 4 element:

  • Index 0 är CAN-ID:t för det mottagna meddelandet, som ett heltal.

  • Index 1 är ett memoryview som ger åtkomst till det mottagna meddelandedatat.

    • Om arg inte anges är detta ett memoryview som innehåller de byte som togs emot. Detta memoryview backas upp av ett nyallokerat bytearray som är tillräckligt stort för att rymma vilket mottaget CAN-meddelande som helst. Detta gör att resultatet kan återanvändas säkert som ett framtida arg, för att spara minnesallokeringar.

    • Om arg anges kommer det tillhandahållna memoryview att storleksändras så att det rymmer exakt de byte som togs emot. Anroparen ansvarar för att se till att det underliggande objektet för memoryview kan rymma ett CAN-meddelande av valfri längd.

  • Index 2 är ett heltal med noll eller fler av bitarna som definieras i Meddelandeflaggor satta. Det anger metadata om det mottagna meddelandet.

  • Index 3 är ett heltal med noll eller fler av bitarna som definieras i Mottagningsfelflaggor satta. Alla värden som inte är noll indikerar potentiella problem vid mottagning av CAN-meddelanden. Dessa flaggor nollställs inuti styrenheten varje gång denna funktion returnerar.

Remote Transmission Requests

Om en Remote Transmission Request tas emot kommer biten CAN.FLAG_RTR att vara satt i Index 2 och memoryview vid Index 1 kommer att innehålla enbart nollor, med en längd lika med fältet DLC i den mottagna begäran.

Exempel
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

Ställer in en avbrottsfunktion handler som ska anropas när en eller flera av de händelser som flaggats i trigger har inträffat.

  • handler är en funktion som ska anropas när avbrottshändelsen utlöses. Funktionen måste ta exakt ett argument, vilket är CAN-instansen.

  • trigger konfigurerar de händelser som kan generera ett avbrott. Möjliga värden är en mask med en eller flera av följande:

    • Händelsen CAN.IRQ_RX inträffar efter att CAN-styrenheten har tagit emot minst ett meddelande till sin RX-FIFO (vilket innebär att CAN.recv() returnerar utan fel).

    • Händelsen CAN.IRQ_TX inträffar efter att CAN-styrenheten antingen har lyckats skicka ett meddelande ut på CAN-bussen eller misslyckats med att skicka ett meddelande. Denna trigger har ytterligare krav på funktionen, se IRQ-flaggor för detaljer.

    • Händelsen CAN.IRQ_STATE inträffar när CAN-styrenheten har övergått till ett allvarligare feltillstånd. Anropa CAN.state() för att få det uppdaterade tillståndet.

  • hard om True används ett hårt avbrott. Detta minskar fördröjningen mellan CAN-styrenhetshändelsen och att funktionen anropas. Hårda avbrottsfunktioner får inte allokera minne; se Skriva avbrottshanterare.

Returnerar ett irq-objekt. Om den anropas utan argument returneras ett tidigare konfigurerat irq-objekt.

Se IRQ-flaggor för ett exempel.

cancel_send(index: int) bool

Begär att CAN-styrenheten avbryter sändningen av ett meddelande ut på bussen.

Argumentet index identifierar en enskild sändningsbuffert. Det bör vara ett heltal i intervallet 0 till CAN.TX_QUEUE_LEN (exklusivt). Vanligtvis är detta ett värde som tidigare returnerats av CAN.send().

Resultatet är True om ett meddelande väntade på sändning i denna buffert och sändningen avbröts.

Resultatet är False annars (antingen väntade inget meddelande på sändning i denna buffert, eller så lyckades sändningen redan).

IRQ-händelsen CAN.IRQ_TX bör användas för att avgöra om ett meddelande definitivt skickades eller inte, men observera att det finns potentiella kapplöpningstillstånd om en sändning avbryts och samma buffert sedan används för att skicka ett annat meddelande (särskilt om CAN-styrenhetens IRQ inte är ”hård”).

state() int

Returnerar ett heltalsvärde som anger styrenhetens aktuella tillstånd. Värdet kommer att vara ett av värdena som definieras i Tillstånd.

Feltillstånd med lägre allvarlighetsgrad kan rensas automatiskt om bussen återhämtar sig, men tillståndet CAN.STATE_BUS_OFF kan endast återställas genom att anropa CAN.restart().

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

Returnerar styrenhetens felräknarvärden. Resultatet är en lista med åtta värden. Om den valfria parametern list anges uppdateras det angivna listobjektet och returneras som resultat, för att undvika en allokering.

Listposterna är:

  • Värdet TEC (Transmit Error Counter)

  • Värdet REC (Receive Error Counter)

  • Antal gånger styrenheten gick in i Warning-tillståndet från Active-tillståndet.

  • Antal gånger styrenheten gick in i Error Passive-tillståndet från Warning-tillståndet.

  • Antal gånger styrenheten gick in i Bus Off-tillståndet från Error Passive-tillståndet.

  • Totalt antal väntande TX-meddelanden i hårdvarukön.

  • Totalt antal väntande RX-meddelanden i hårdvarukön.

  • Antal gånger ett RX-överflöde inträffade.

Anteckning

Beroende på styrenheten kan dessa värden svämma över tillbaka till 0 efter ett visst värde.

Anteckning

Om en styrenhet inte stöder en viss räknare returnerar den None för det listelementet.

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

Returnerar en lista med element som anger de aktuella timinginställningarna i CAN-styrenheten. Detta kan användas för att verifiera timing i felsökningssyfte. Resultatet är en lista med sex värden. Om den valfria parametern list anges uppdateras det angivna listobjektet och returneras som resultat, för att undvika en allokering.

Listposterna är:

  • Exakt bithastighet som styrenheten använder. Kan avvika från argumentet bitrate som skickades till CAN.init() på grund av kvantisering för att uppfylla hårdvarubegränsningar.

  • Resynkroniseringssprångbredd (SJW) i enheter av tidskvanta för nominella bitar. Har samma betydelse som parametern sjw i CAN.init().

  • Provpunktens placering i enheter av tidskvanta för nominella bitar. Har samma betydelse som parametern tseg1 i CAN.init().

  • Sändpunktens placering i enheter av tidskvanta för nominella bitar. Har samma betydelse som parametern tseg2 i CAN.init().

  • Timinginformation för CAN FD. None för styrenheter som inte stöder CAN FD, eller om CAN FD inte är initierat. Annars en nästlad lista med fyra element som motsvarar posterna ovan men gäller CAN FD BRS-funktionen.

  • Valfri styrenhetsspecifik timinginformation. Beroende på styrenheten är detta antingen None om styrenheten inte rapporterar någon, eller så är det en lista med konstant längd vars element är specifika för en viss hårdvarustyrenhet.

Anteckning

Om CAN.init() inte har anropats returnerar denna funktion fortfarande ett resultat, men resultatet beror på styrenhetens interna tillstånd och kanske inte är korrekt.

restart() None

Får styrenheten att lämna STATE_BUS_OFF utan att rensa något annat internt tillstånd. Rensar även en del av felräknarna (alltid antalet gånger varje feltillstånd har inträtts, möjligen TEC och REC beroende på styrenheten.)

Anrop av denna funktion avbryter även alla meddelanden som väntar på att skickas. Inga IRQ_TX-avbrott levereras för dessa meddelanden.

Observera att denna funktion kan komma att få styrenheten att lämna tillståndet ”Error Passive”, beroende på om styrenhetshårdvaran nollställer TEC och REC eller inte.

deinit() None

Avinitierar en tidigare aktiv CAN-instans. Alla väntande meddelanden (sändning och mottagning) släpps och styrenheten slutar interagera på bussen. För att använda denna instans igen, anropa CAN.init().

Inga IRQ_TX- eller IRQ_RX-avbrott anropas som svar på anrop av denna funktion.

Se även CAN.restart().

Konstanter

TX_QUEUE_LEN: int

Maximalt antal CAN-meddelanden som kan köas i styrenhetens utgående hårdvarumeddelandekö. ”Sändningsbuffertindexen” som används av CAN.send(), CAN.cancel_send() och IRQ-flaggor kommer att ligga i detta intervall.

Lägen

Dessa värden representerar styrenhetens driftlägen, som skickas till CAN.init(). Alla styrenheter stöder kanske inte alla lägen.

Att ändra läget på en igångvarande styrenhet kräver att man anropar CAN.deinit() och sedan anropar CAN.init() igen med det nya läget.

MODE_NORMAL: int

Styrenheten är aktiv som en standard CAN-nätverksnod (kommer att bekräfta giltiga meddelanden och kan sända fel beroende på dess aktuella tillstånd).

MODE_SLEEP: int

CAN-styrenheten är i viloläge i ett lågeffektsläge. Beroende på styrenheten kan detta stödja väckning av styrenheten och övergång till CAN.MODE_NORMAL om CAN-trafik tas emot.

MODE_LOOPBACK: int

Ett testläge. CAN-styrenheten är fortfarande ansluten till den externa bussen, men kommer även att ta emot sina egna sända meddelanden och ignorera eventuella ACK-fel.

MODE_SILENT: int

CAN-styrenheten tar emot meddelanden men interagerar inte med CAN-bussen (inklusive att skicka ACK:er, fel, osv.)

MODE_SILENT_LOOPBACK: int

Ett testläge som inte alls kräver att en CAN-transceiver är ansluten. CAN-styrenheten tar emot sina egna sända meddelanden utan att alls interagera med CAN-bussen. CAN TX- och RX-stiften förblir inaktiva.

Tillstånd

Dessa värden returneras av CAN.state() och återspeglar CAN-styrenhetens feltillstånd:

STATE_STOPPED: int

Styrenheten har inte initierats.

STATE_ACTIVE: int

Styrenheten är aktiv och felräknarna TEC och REC ligger båda under varningströskeln 96. Se CAN.get_counters().

STATE_WARNING: int

Styrenheten är aktiv men minst en av felräknarna TEC och REC ligger mellan 96 och 127. Se CAN.get_counters().

STATE_PASSIVE: int

Styrenheten är i tillståndet ”Error Passive”, vilket innebär att den inte längre sänder aktiva fel till bussen, men den är i övrigt funktionsduglig. Detta tillstånd inträder när minst en av felräknarna TEC och REC är 128 eller större, men TEC är mindre än 255. Se CAN.get_counters().

STATE_BUS_OFF: int

Styrenheten är i Bus-Off-tillståndet, vilket innebär att felräknaren TEC är större än 255. CAN-styrenheten interagerar inte med bussen i detta tillstånd och behöver startas om via CAN.restart() för att fortsätta.

Meddelandeflaggor

Dessa värden representerar metadata om ett CAN-meddelande. Funktionerna CAN.send(), CAN.recv() och CAN.set_filters() accepterar eller returnerar ett heltalsvärde bestående av noll eller fler av dessa flaggor bitvis ELLER-kombinerade.

FLAG_RTR: int

Anger att ett meddelande är en remote transmission request.

FLAG_EXT_ID: int

Om satt anger den att en meddelandeidentifierare är Extended (29-bitars). Om inte satt anger den att en meddelandeidentifierare är Standard (11-bitars).

FLAG_UNORDERED: int

Om satt i argumentet flags till CAN.send() anger den att det är OK om meddelanden med samma CAN-ID skickas i valfri ordning ut på bussen.

Annars kan försök att köa flera meddelanden med samma ID resultera i att CAN.send() misslyckas om styrenhetshårdvaran inte kan upprätthålla ordning.

Denna flagga sätts aldrig på mottagna meddelanden och ignoreras av CAN.set_filters().

Mottagningsfelflaggor

Resultatet av CAN.recv() innehåller ett heltalsvärde bestående av noll eller fler av dessa flaggor bitvis ELLER-kombinerade. Om satta anger dessa flaggor potentiella allmänna problem med mottagning av CAN-meddelanden.

RECV_ERR_FULL: int

Hårdvaru-FIFO:n där detta meddelande togs emot är full, och ytterligare inkommande meddelanden kan gå förlorade.

RECV_ERR_OVERRUN: int

Hårdvaru-FIFO:n där detta meddelande togs emot är full, och ett eller flera inkommande meddelanden har gått förlorade.

IRQ-värden

IRQ_RX: int

Skicka till argumentet trigger i irq() för att utlösa funktionen varje gång CAN-styrenheten har tagit emot ett komplett meddelande till RX-FIFO:n. Läs meddelandet inuti funktionen med recv().

IRQ_TX: int

Skicka till argumentet trigger i irq() för att utlösa funktionen varje gång CAN-styrenheten avslutar ett sändningsförsök (lyckat eller misslyckat). Använd inuti funktionen de ytterligare bitarna nedan för att ta reda på vilken brevlåda som slutfördes och om den misslyckades – se IRQ-flaggor.

IRQ_STATE: int

Skicka till argumentet trigger i irq() för att utlösa funktionen varje gång styrenheten övergår mellan värdena STATE_* (active / warning / passive / bus-off). Använd state() inuti funktionen för att läsa det nya tillståndet.

IRQ_TX_FAILED: int

Statusflagga som kan sättas i irq().flags() när en IRQ_TX-händelse utlöses. Anger att sändningsförsöket misslyckades (vanligtvis för att cancel_send() anropades, eller för att styrenheten gick in i ett feltillstånd).

IRQ_TX_IDX_SHIFT: int

Bitposition för fältet sändnings-brevlådeindex inom värdet irq().flags() under en IRQ_TX-händelse. Brevlådeindexet extraheras som (flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.

IRQ_TX_IDX_MASK: int

Bitmask för fältet sändnings-brevlådeindex inom värdet irq().flags() under en IRQ_TX-händelse. Det extraherade indexet matchar heltalet som returnerades av motsvarande send()-anrop (ett int i intervallet 0 till TX_QUEUE_LEN).

IRQ-flaggor

Anrop av CAN.irq() registrerar en avbrottsfunktion med en eller flera av triggrarna CAN.IRQ_RX, CAN.IRQ_TX och CAN.IRQ_STATE.

Funktionen returnerar ett IRQ-objekt, och att anropa funktionen flags() på detta objekt returnerar ett heltal som anger vilken eller vilka triggerhändelser som utlöste avbrottet. En CAN IRQ-funktion bör anropa funktionen flags() upprepade gånger tills den returnerar 0.

När funktionen flags() returnerar med biten CAN.IRQ_TX satt kan funktionen även kontrollera följande flaggbitar i resultatet för ytterligare information om TX-händelsen:

  • Biten CAN.IRQ_TX_FAILED är satt om sändningen misslyckades. Vanligtvis händer detta endast om CAN.cancel_send() anropades, även om det också kan hända om styrenheten går in i ett feltillstånd.

  • CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFT är ett bitmaskat område av flaggvärdet som innehåller indexet för den sändningsbuffert som genererade händelsen. Detta kommer att vara ett heltal i intervallet 0 till CAN.TX_QUEUE_LEN (exklusivt), och kommer att matcha resultatet av ett tidigare anrop till CAN.send().

IRQ_TX-exempel

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)

Viktigt

Om triggern CAN.IRQ_TX är satt måste funktionen anropa flags() upprepade gånger tills den returnerar 0, som visas i detta exempel. Annars kanske CAN-avbrott inte återaktiveras korrekt.