clasa CAN – protocolul Controller Area Network¶
CAN este un protocol serial pe două fire, folosit pentru livrarea fiabilă, în timp real, a mesajelor între unul sau mai multe noduri conectate la o magistrală comună. CAN 2.0 a fost standardizat în ISO-11898 și este cunoscut acum și sub numele de CAN Classic.
Există, de asemenea, un protocol mai nou și compatibil cu versiunile anterioare, numit CAN FD (CAN with Flexible Data-Rate). Driverul machine.CAN nu acceptă în prezent funcțiile CAN FD; folosiți pyb.CAN pe STM32 dacă aveți nevoie de CAN FD.
Suportul CAN necesită un controler (adesea un periferic intern al microcontrolerului) și un transceiver extern care să adapteze nivelurile semnalelor pe magistrala CAN.
Disponibil pe camerele OpenMV bazate pe STM32 (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, plus variantele cu marca Arduino care includ un transceiver). Nu este încă acceptat pe OpenMV Cam RT1062 (portul mimxrt) sau OpenMV Cam AE3 (portul alif).
Interfața machine.CAN este o interfață de mesagerie CAN de bază, de nivel scăzut, care abstractizează un controler CAN sub forma unei cozi de prioritate de ieșire pentru trimiterea mesajelor, a unei cozi de intrare pentru primirea mesajelor și a unor mecanisme de raportare a erorilor.
Notă
Modulele micropython-lib can și aiocan planificate vor fi modalitatea recomandată de a folosi CAN cu MicroPython.
Constructor¶
- class machine.CAN(id: int, *args, **kwargs)¶
Construiește un obiect controler CAN cu id-ul dat:
ididentifică un anumit obiect controler CAN; depinde de placă și de port.Toate celelalte argumente sunt transmise către
CAN.init(). Trebuie furnizat cel puțin un argument (bitrate).
Versiunile viitoare ale acestei clase pot accepta aici și argumente cu cuvinte-cheie specifice portului, care configurează hardware-ul. În prezent nu sunt implementate astfel de argumente cu cuvinte-cheie.
Exemplu¶
Construiește și inițializează controlerul CAN 1 cu rata de biți de 500kbps:
from machine import CAN can = CAN(1, 500_000)
Metode¶
- init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None¶
Inițializează magistrala CAN cu parametrii dați:
bitrate este rata de biți dorită a magistralei, în biți pe secundă.
mode este una dintre valorile prezentate la Moduri, indicând modul de operare dorit. Valoarea implicită este operarea „normal” pe magistrală.
Următorii parametri sunt opționali și se referă la temporizările biților CAN. În majoritatea cazurilor puteți lăsa acești parametri la valorile implicite:
sample_point este un procentaj întreg din durata bitului de date. Specifică poziția eșantionării bitului în raport cu durata nominală totală a bitului. Driverul CAN va calcula parametrii în consecință. Acest parametru este ignorat dacă tseg1 și tseg2 sunt setate.
sjw este lățimea saltului de resincronizare în unități de cuante de timp pentru biții nominali; poate fi o valoare între 1 și 4 inclusiv pentru CAN clasic.
tseg1 definește poziția punctului de eșantionare în unități de cuante de timp pentru biții nominali; poate fi o valoare între 1 și 16 inclusiv pentru CAN clasic. Aceasta este suma fazelor
Prop_SegșiPhase_Seg1așa cum sunt definite în standardul ISO-11898. Dacă această valoare este setată, atunci tseg2 trebuie de asemenea setat, iar sample_point este ignorat.tseg2 definește poziția punctului de transmisie în unități de cuante de timp pentru biții nominali; poate fi o valoare între 1 și 8 inclusiv pentru CAN clasic. Aceasta corespunde fazei
Phase_Seg2din standardul ISO-11898. Dacă această valoare este setată, atunci tseg1 trebuie de asemenea setat.
Dacă aceste argumente sunt specificate, atunci controlerul CAN este configurat corect pentru bitrate-ul dorit și pentru numărul total specificat de cuante de timp per bit. Valorile tseg1 și tseg2 au prioritate față de argumentul sample_point dacă toate acestea sunt furnizate.
Notă
Hardware-ul fiecărui controler poate avea restricții suplimentare privind valorile valide pentru acești parametri și va genera o eroare
ValueErrordacă o anumită valoare nu este acceptată.Notă
Hardware-ul specific al controlerului poate accepta parametri opționali suplimentari cu cuvinte-cheie pentru funcții specifice hardware-ului, cum ar fi supraeșantionarea.
- set_filters(filters: list | tuple | None) None¶
Setează filtrele de recepție în controlerul CAN. filters poate fi:
Nonepentru a accepta toate mesajele primite, sau[]sau()pentru a dezactiva primirea tuturor mesajelor, sauUn iterabil cu unul sau mai multe elemente care definesc criteriile de filtrare. Fiecare element trebuie să fie un tuplu sau o listă cu trei elemente:
identifiereste un identificator CAN (int).bit_maskeste o mască de biți pentru biții din câmpul identificatorului CAN (int).flagseste un întreg cu zero sau mai mulți dintre biții definiți în Flag-uri de mesaj setați. Acesta specifică proprietățile pe care mesajul primit trebuie să le îndeplinească. Nu toate controlerele acceptă filtrarea pe toate flag-urile; se generează o eroareValueErrordacă se solicită un flag neacceptat.
Mesajele primite sunt acceptate dacă biții mascați în
bit_maskse potrivesc între identificatorul mesajului și valoareaidentifiera filtrului, iar flag-urile setate în filtru se potrivesc cu mesajul primit.Dacă bitul
CAN.FLAG_EXT_IDeste setat în flags, filtrul se potrivește numai cu ID-uri CAN extinse. Dacă bitulCAN.FLAG_EXT_IDnu este setat, filtrul se potrivește numai cu ID-uri CAN standard.Toate filtrele sunt combinate cu OR în controler. Transmiterea unei liste sau a unui tuplu gol pentru argumentul filters înseamnă că nu va fi primit niciun mesaj.
Unele controlere CAN necesită ca fiecare filtru să fie asociat cu un singur FIFO de recepție. În aceste cazuri, elementele filtrului din argument sunt alocate prin rotație (round-robin) către FIFO-urile disponibile. Acest driver nu face distincție între FIFO-uri în IRQ-ul de recepție.
Notă
Dacă apelantul transmite un iterabil cu mai multe elemente decât
CAN.FILTERS_MAX, se va genera o eroareValueError.Notă
Dacă fie
identifier, fiebit_maskse află în afara intervalului pentru tipul de ID specificat, se va genera o eroareValueErrorcu motivul „invalid id”.Exemple¶
Primește toate mesajele care sosesc:
can.set_filters(None)Primește numai mesajele cu valorile ID standard 0x301 și 0x700:
can.set_filters(((0x301, 0x7FF, 0), (0x700, 0x7FF, 0)))
Primește numai mesajele cu valori ID standard în intervalul 0x300-0x3FF și valoarea ID extins 0x50700:
can.set_filters(((0x300, 0x700, 0), (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
- FILTERS_MAX: int¶
Valoare constantă care indică numărul maxim de filtre de recepție acceptate pentru acest controler hardware.
Rețineți că unele controlere pot avea restricții hardware mai complexe privind numărul de filtre utilizate (de exemplu, numărarea independentă a filtrelor de ID standard și extins). În aceste cazuri,
CAN.set_filterspoate genera o eroareValueErrorchiar și atunci când limitaFILTERS_MAXnu este depășită.
- send(id: int, data: bytes, flags: int = 0) int | None¶
Copiază un nou mesaj CAN în coada de transmisie hardware a controlerului pentru a fi trimis pe magistrală. Coada de transmisie este o coadă de prioritate sortată după prioritatea identificatorului CAN (identificatorii numerici mai mici au prioritate mai mare).
id este o valoare întreagă de identificator CAN.
data este un obiect bytes (sau similar) care conține datele mesajului CAN sau care descrie o cerere de transmisie la distanță (Remote Transmission Request, vezi mai jos).
flags este un întreg cu zero sau mai mulți dintre biții definiți în Flag-uri de mesaj setați, specificând proprietățile mesajului CAN de ieșire (ID extins, cerere de transmisie la distanță etc.)
Dacă mesajul este pus cu succes în coadă pentru transmisia pe magistrală, funcția returnează un întreg în intervalul
0până laCAN.TX_QUEUE_LEN(exclusiv). Această valoare este indexul tamponului (buffer) de transmisie unde mesajul este pus în coadă pentru trimitere și poate fi folosită de funcțiaCAN.cancel_sendși în evenimenteleCAN.IRQ_TX.Dacă coada este plină, atunci trimiterea va eșua și se returnează
None.Trimiterea poate eșua și returna
Nonedacă valoarea id furnizată are aceeași prioritate ca un mesaj existent în coada de transmisie, iar hardware-ul controlerului CAN nu poate garanta că mesajele cu același ID vor fi trimise pe magistrală în aceeași ordine în care au fost adăugate în coadă. Pentru a pune totuși mesajul în coadă, transmiteți flag-ulCAN.FLAG_UNORDEREDîn argumentul flags. Acest flag indică faptul că este acceptabil ca mesajele cu același ID CAN să fie trimise pe magistrală în orice ordine.Dacă controlerul se află în starea de eroare „Bus Off” sau este dezactivat, apelarea acestei funcții va genera o eroare
OSError.Notă
Această implementare intenționat de nivel scăzut este concepută astfel încât apelantul să poată stabili o coadă software de mesaje de ieșire.
Important
„Coada de transmisie” CAN nu este o coadă FIFO, ci este ordonată după prioritate și, deși poate conține până la
CAN.TX_QUEUE_LENelemente, pot exista alte restricții hardware privind mesajele care pot fi puse în coadă în același timp.Cereri de transmisie la distanță (Remote Transmission Requests)¶
Dacă bitul
CAN.FLAG_RTReste setat în argumentul flags, atunci controlerul va trimite o cerere de transmisie la distanță în loc de un mesaj. În acest caz, conținutul argumentului data este ignorat. Controlerul va trimite o cerere în care câmpul de lungimeDLCeste egal cu lungimea argumentului data.Exemple¶
Încearcă să trimită un mesaj cu o sarcină utilă de trei octeți
0a0b0cși ID standard 0x200:can.send(0x200, b"\x0a\x0b\x0c", 0)Încearcă să trimită un mesaj cu o sarcină utilă goală și ID extins 0x180008. Indică faptul că controlerul poate trimite mesaje cu acest ID în orice ordine, în cazul în care alte mesaje sunt deja în coadă pentru trimitere cu același ID:
can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)Încearcă să trimită o cerere de transmisie la distanță cu lungimea de 8 octeți și ID standard 0x555:
can.send(0x555, b" " * 8, can.FLAG_RTR)
- recv(arg: list | None = None) list | None¶
Returnează un mesaj CAN care a fost primit de controler, în conformitate cu filtrele setate prin
CAN.set_filters().Această funcție acceptă un singur argument opțional; dacă este furnizat, atunci trebuie să fie o listă cu cel puțin 4 elemente, unde al doilea element este un obiect
memoryviewcare se referă la un obiectbytearraysau similar, având capacitate suficientă pentru a conține orice mesaj CAN primit (8 octeți pentru CAN Classic, 64 de octeți pentru CAN FD). Lista furnizată va fi returnată ca rezultat în caz de succes și evită alocarea de memorie în interiorul funcției.Dacă nu au fost primite mesaje de către controlerul CAN, această funcție returnează
None.Notă
CAN.set_filterstrebuie apelată înainte ca orice mesaj să poată fi primit de controler. Pentru a primi toate mesajele, apelațiset_filters(None).Dacă un mesaj a fost primit de controlerul CAN, această funcție returnează o listă cu 4 elemente:
Indexul 0 este ID-ul CAN al mesajului primit, ca întreg.
Indexul 1 este un memoryview care oferă acces la datele mesajului primit.
Dacă arg nu este furnizat, atunci acesta este un
memoryviewcare conține octeții care au fost primiți. Acestmemoryvieweste susținut de unbytearraynou alocat, suficient de mare pentru a conține orice mesaj CAN primit. Acest lucru permite ca rezultatul să fie reutilizat în siguranță ca un viitor arg, pentru a economisi alocările de memorie.Dacă arg este furnizat, atunci
memoryview-ul furnizat va fi redimensionat pentru a conține exact octeții care au fost primiți. Apelantul este responsabil să se asigure că obiectul care susținememoryview-ul poate conține un mesaj CAN de orice lungime.
Indexul 2 este un întreg cu zero sau mai mulți dintre biții definiți în Flag-uri de mesaj setați. Acesta indică metadate despre mesajul primit.
Indexul 3 este un întreg cu zero sau mai mulți dintre biții definiți în Flag-uri de eroare la recepție setați. Orice valoare diferită de zero indică probleme potențiale la primirea mesajelor CAN. Aceste flag-uri sunt resetate în interiorul controlerului de fiecare dată când această funcție returnează.
Cereri de transmisie la distanță (Remote Transmission Requests)¶
Dacă se primește o cerere de transmisie la distanță, atunci bitul
CAN.FLAG_RTRva fi setat în indexul 2, iar memoryview-ul de la indexul 1 va conține numai zerouri, cu o lungime egală cu câmpulDLCal cererii primite.Exemplu¶
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¶
Setează o funcție handler de întrerupere care să fie apelată atunci când a avut loc unul sau mai multe dintre evenimentele marcate în trigger.
handler este o funcție care va fi apelată atunci când se declanșează evenimentul de întrerupere. Handler-ul trebuie să accepte exact un argument, care este instanța
CAN.trigger configurează evenimentul (evenimentele) care pot genera o întrerupere. Valorile posibile sunt o mască formată din unul sau mai multe dintre următoarele:
Evenimentul
CAN.IRQ_RXapare după ce controlerul CAN a primit cel puțin un mesaj în FIFO-ul său RX (ceea ce înseamnă căCAN.recv()va returna cu succes).Evenimentul
CAN.IRQ_TXapare după ce controlerul CAN fie a trimis cu succes un mesaj pe magistrala CAN, fie nu a reușit să trimită un mesaj. Acest declanșator are cerințe suplimentare pentru handler, vezi Flag-uri IRQ pentru detalii.Evenimentul
CAN.IRQ_STATEapare atunci când controlerul CAN a trecut într-o stare de eroare mai gravă. ApelațiCAN.state()pentru a obține starea actualizată.
hard dacă este True, se folosește o întrerupere hard. Aceasta reduce întârzierea dintre evenimentul controlerului CAN și apelarea handler-ului. Handler-ele de întrerupere hard nu pot aloca memorie; vezi Scrierea handlerelor de întrerupere.
Returnează un obiect irq. Dacă este apelată fără argumente, atunci se returnează un obiect irq configurat anterior.
Vezi Flag-uri IRQ pentru un exemplu.
- cancel_send(index: int) bool¶
Solicită controlerului CAN să anuleze trimiterea unui mesaj pe magistrală.
Argumentul index identifică un singur tampon de transmisie. Trebuie să fie un întreg în intervalul
0până laCAN.TX_QUEUE_LEN(exclusiv). În general, aceasta va fi o valoare returnată anterior deCAN.send().Rezultatul este
Truedacă un mesaj era în așteptare pentru transmisie în acest tampon și transmisia a fost anulată.Rezultatul este
Falseîn caz contrar (fie niciun mesaj nu era în așteptare pentru transmisie în acest tampon, fie transmisia a reușit deja).Evenimentul IRQ
CAN.IRQ_TXar trebui folosit pentru a determina dacă un mesaj a fost cu siguranță trimis sau nu, dar rețineți că există condiții potențiale de cursă (race) dacă o transmisie este anulată și apoi același tampon este folosit pentru a trimite un alt mesaj (mai ales dacă IRQ-ul controlerului CAN nu este „hard”).
- state() int¶
Returnează o valoare întreagă care indică starea curentă a controlerului. Valoarea va fi una dintre valorile definite în Stări.
Stările de eroare cu severitate mai redusă se pot șterge automat dacă magistrala își revine, dar starea
CAN.STATE_BUS_OFFpoate fi recuperată numai prin apelareaCAN.restart().
- get_counters(list: list | None = None, /) list¶
Returnează valorile contoarelor de erori ale controlerului. Rezultatul este o listă cu opt valori. Dacă parametrul opțional list este specificat, atunci obiectul listă furnizat este actualizat și returnat ca rezultat, pentru a evita o alocare.
Elementele listei sunt:
valoarea TEC (Transmit Error Counter)
valoarea REC (Receive Error Counter)
Numărul de dăți în care controlerul a intrat în starea Warning din starea Active.
Numărul de dăți în care controlerul a intrat în starea Error Passive din starea Warning.
Numărul de dăți în care controlerul a intrat în starea Bus Off din starea Error Passive.
Numărul total de mesaje TX în așteptare în coada hardware.
Numărul total de mesaje RX în așteptare în coada hardware.
Numărul de dăți în care a avut loc o depășire (overrun) la recepție RX.
Notă
În funcție de controler, aceste valori pot reveni prin depășire la 0 după o anumită valoare.
Notă
Dacă un controler nu acceptă un anumit contor, va returna
Nonepentru acel element din listă.
- get_timings(list: list | None = None, /) list¶
Returnează o listă de elemente care indică temporizările configurate în prezent în controlerul CAN. Aceasta poate fi folosită pentru a verifica temporizările în scopuri de depanare. Rezultatul este o listă cu șase valori. Dacă parametrul opțional list este specificat, atunci obiectul listă furnizat este actualizat și returnat ca rezultat, pentru a evita o alocare.
Elementele listei sunt:
Rata de biți exactă folosită de controler. Poate diferi de argumentul bitrate transmis către
CAN.init()din cauza cuantizării necesare pentru a respecta constrângerile hardware.Lățimea saltului de resincronizare (SJW) în unități de cuante de timp pentru biții nominali. Are aceeași semnificație ca parametrul sjw al
CAN.init().Poziția punctului de eșantionare în unități de cuante de timp pentru biții nominali. Are aceeași semnificație ca parametrul tseg1 al
CAN.init().Poziția punctului de transmisie în unități de cuante de timp pentru biții nominali. Are aceeași semnificație ca parametrul tseg2 al
CAN.init().Informații de temporizare CAN FD.
Nonepentru controlerele care nu acceptă CAN FD sau dacă CAN FD nu este inițializat. În caz contrar, o listă imbricată de patru elemente corespunzătoare elementelor de mai sus, dar aplicabile funcției CAN FD BRS.Informații de temporizare opționale, specifice controlerului. În funcție de controler, aceasta va fi fie
Nonedacă controlerul nu raportează nimic, fie o listă cu lungime constantă ale cărei elemente sunt specifice unui anumit controler hardware.
Notă
Dacă
CAN.init()nu a fost apelată, atunci această funcție returnează totuși un rezultat, dar rezultatul depinde de interiorul controlerului și poate să nu fie exact.
- restart() None¶
Determină controlerul să iasă din starea
STATE_BUS_OFFfără a șterge nicio altă stare internă. De asemenea, șterge unele dintre contoarele de erori (întotdeauna numărul de dăți în care a fost introdusă fiecare stare de eroare, eventual TEC și REC în funcție de controler).Apelarea acestei funcții anulează, de asemenea, orice mesaje care așteaptă să fie trimise. Nu se livrează întreruperi
IRQ_TXpentru aceste mesaje.Rețineți că această funcție poate sau nu să determine controlerul să iasă din starea „Error Passive”, în funcție de faptul dacă hardware-ul controlerului anulează TEC și REC sau nu.
- deinit() None¶
Dezinițializează o instanță CAN activă anterior. Toate mesajele în așteptare (de transmisie și de recepție) sunt eliminate, iar controlerul încetează să interacționeze pe magistrală. Pentru a folosi din nou această instanță, apelați
CAN.init().Nu se apelează nicio întrerupere
IRQ_TXsauIRQ_RXca răspuns la apelarea acestei funcții.Vezi de asemenea
CAN.restart().
Constante¶
- TX_QUEUE_LEN: int¶
Numărul maxim de mesaje CAN care pot fi puse în coada hardware de mesaje de ieșire a controlerului. „Indecșii tamponului de transmisie” folosiți de
CAN.send(),CAN.cancel_send()și Flag-uri IRQ se vor afla în acest interval.
Moduri¶
Aceste valori reprezintă modurile de operare ale controlerului, așa cum sunt transmise către
CAN.init(). Nu toate controlerele pot accepta toate modurile.Schimbarea modului unui controler aflat în funcțiune necesită apelarea
CAN.deinit()și apoi apelarea din nou aCAN.init()cu noul mod.- MODE_NORMAL: int¶
Controlerul este activ ca un nod de rețea CAN standard (va confirma mesajele valide și poate transmite erori în funcție de Starea sa curentă).
- MODE_SLEEP: int¶
Controlerul CAN este în repaus într-un mod de consum redus de energie. În funcție de controler, acest mod poate permite trezirea controlerului și trecerea la
CAN.MODE_NORMALdacă se primește trafic CAN.
- MODE_LOOPBACK: int¶
Un mod de testare. Controlerul CAN este încă conectat la magistrala externă, dar va primi și propriile sale mesaje transmise și va ignora orice erori de ACK.
Stări¶
Aceste valori sunt returnate de
CAN.state()și reflectă starea de eroare a controlerului CAN:- STATE_ACTIVE: int¶
Controlerul este activ, iar contoarele de erori
TECșiRECsunt ambele sub pragul de avertizare de 96. VeziCAN.get_counters().
- STATE_WARNING: int¶
Controlerul este activ, dar cel puțin unul dintre contoarele de erori
TECșiRECeste între 96 și 127. VeziCAN.get_counters().
- STATE_PASSIVE: int¶
Controlerul se află în starea „Error Passive”, ceea ce înseamnă că nu mai transmite erori active pe magistrală, dar este altfel funcțional. Această stare este introdusă atunci când cel puțin unul dintre contoarele de erori
TECșiRECeste 128 sau mai mare, darTECeste mai mic de 255. VeziCAN.get_counters().
- STATE_BUS_OFF: int¶
Controlerul se află în starea Bus-Off, ceea ce înseamnă că contorul de erori
TECeste mai mare de 255. Controlerul CAN nu va interacționa cu magistrala în această stare și trebuie repornit prinCAN.restart()pentru a continua.
Flag-uri de mesaj¶
Aceste valori reprezintă metadate despre un mesaj CAN. Funcțiile
CAN.send(),CAN.recv()șiCAN.set_filters()fie acceptă, fie returnează o valoare întreagă alcătuită din zero sau mai multe dintre aceste flag-uri combinate prin OR la nivel de bit.- FLAG_EXT_ID: int¶
Dacă este setat, indică faptul că un identificator de mesaj este extins (29 de biți). Dacă nu este setat, indică faptul că un identificator de mesaj este standard (11 biți).
- FLAG_UNORDERED: int¶
Dacă este setat în argumentul
flagsalCAN.send(), indică faptul că este acceptabil ca mesajele cu același ID CAN să fie trimise pe magistrală în orice ordine.În caz contrar, încercarea de a pune în coadă mai multe mesaje cu același ID poate duce la eșecul
CAN.send()dacă hardware-ul controlerului nu poate impune ordinea.Acest flag nu este niciodată setat pe mesajele primite și este ignorat de
CAN.set_filters().
Flag-uri de eroare la recepție¶
Rezultatul
CAN.recv()include o valoare întreagă alcătuită din zero sau mai multe dintre aceste flag-uri combinate prin OR la nivel de bit. Dacă sunt setate, aceste flag-uri indică probleme generale potențiale la primirea mesajelor CAN.Valori IRQ¶
- IRQ_RX: int¶
Transmiteți către argumentul
triggeralirq()pentru a declanșa handler-ul de fiecare dată când controlerul CAN a primit un mesaj complet în FIFO-ul RX. În interiorul handler-ului, citiți mesajul curecv().
- IRQ_TX: int¶
Transmiteți către argumentul
triggeralirq()pentru a declanșa handler-ul de fiecare dată când controlerul CAN finalizează o încercare de transmisie (reușită sau eșuată). În interiorul handler-ului, folosiți biții suplimentari de mai jos pentru a determina care căsuță poștală (mailbox) s-a finalizat și dacă a eșuat – vezi Flag-uri IRQ.
- IRQ_STATE: int¶
Transmiteți către argumentul
triggeralirq()pentru a declanșa handler-ul de fiecare dată când controlerul trece între valorileSTATE_*(active / warning / passive / bus-off). Folosițistate()în interiorul handler-ului pentru a citi noua stare.
- IRQ_TX_FAILED: int¶
Flag de stare care poate fi setat în
irq().flags()atunci când se declanșează un evenimentIRQ_TX. Indică faptul că încercarea de transmisie a eșuat (de obicei pentru că a fost apelatăcancel_send()sau pentru că controlerul a intrat într-o stare de eroare).
- IRQ_TX_IDX_SHIFT: int¶
Poziția bitului câmpului index-căsuță-poștală-de-transmisie din valoarea
irq().flags()în timpul unui evenimentIRQ_TX. Indexul căsuței poștale este extras ca(flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.
- IRQ_TX_IDX_MASK: int¶
Masca de biți a câmpului index-căsuță-poștală-de-transmisie din valoarea
irq().flags()în timpul unui evenimentIRQ_TX. Indexul extras corespunde întregului returnat de apelulsend()corespunzător (un int în intervalul0până laTX_QUEUE_LEN).
Flag-uri IRQ¶
Apelarea CAN.irq() înregistrează un handler de întrerupere cu unul sau mai multe dintre declanșatoarele CAN.IRQ_RX, CAN.IRQ_TX și CAN.IRQ_STATE.
Funcția returnează un obiect IRQ, iar apelarea funcției flags() pe acest obiect returnează un întreg care indică ce eveniment(e) declanșator(oare) au declanșat întreruperea. Un handler de IRQ CAN ar trebui să apeleze funcția flags() în mod repetat până când aceasta returnează 0.
Atunci când funcția flags() returnează cu bitul CAN.IRQ_TX setat, handler-ul poate verifica de asemenea următorii biți de flag din rezultat pentru informații suplimentare despre evenimentul TX:
Bitul
CAN.IRQ_TX_FAILEDeste setat dacă transmisia a eșuat. De obicei, acest lucru se va întâmpla numai dacă a fost apelatăCAN.cancel_send(), deși se poate întâmpla și dacă controlerul intră într-o stare de eroare.CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFTeste o regiune mascată cu biți a valorii flags care conține indexul tamponului de transmisie care a generat evenimentul. Acesta va fi un întreg în intervalul0până laCAN.TX_QUEUE_LEN(exclusiv) și va corespunde rezultatului unui apel anterior laCAN.send().
Exemplu 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)
Important
Dacă declanșatorul CAN.IRQ_TX este setat, atunci handler-ul trebuie să apeleze flags() în mod repetat până când acesta returnează 0, așa cum se arată în acest exemplu. În caz contrar, este posibil ca întreruperile CAN să nu fie reactivate corect.