classe CAN – protocollo Controller Area Network¶
CAN è un protocollo seriale a due fili utilizzato per la consegna affidabile di messaggi in tempo reale tra uno o più nodi connessi a un bus comune. CAN 2.0 è stato standardizzato nella ISO-11898 ed è ora noto anche come CAN Classic.
Esiste anche un protocollo più recente e retrocompatibile chiamato CAN FD (CAN with Flexible Data-Rate). Il driver machine.CAN attualmente non supporta le funzionalità CAN FD; usa pyb.CAN su STM32 se hai bisogno di CAN FD.
Il supporto CAN richiede un controller (spesso una periferica interna del microcontrollore) e un transceiver esterno per adattare il livello dei segnali sul bus CAN.
Disponibile sulle OpenMV Cam STM32 (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, oltre alle varianti a marchio Arduino che integrano un transceiver). Non ancora supportato sulla OpenMV Cam RT1062 (porta mimxrt) o sulla OpenMV Cam AE3 (porta alif).
L’interfaccia machine.CAN è un’interfaccia di messaggistica CAN di base e a basso livello che astrae un controller CAN come una coda di priorità in uscita per l’invio dei messaggi, una coda in ingresso per la ricezione dei messaggi e meccanismi per la segnalazione degli errori.
Nota
I moduli micropython-lib pianificati can e aiocan saranno il modo consigliato per usare il CAN con MicroPython.
Costruttore¶
- class machine.CAN(id: int, *args, **kwargs)¶
Costruisce un oggetto controller CAN con l’id indicato:
ididentifica un particolare oggetto controller CAN; è specifico della scheda e della porta.Tutti gli altri argomenti vengono passati a
CAN.init(). Deve essere fornito almeno un argomento (bitrate).
Le versioni future di questa classe potrebbero anche accettare qui argomenti keyword specifici della porta che configurano l’hardware. Attualmente non è implementato alcun argomento keyword di questo tipo.
Esempio¶
Costruisce e inizializza il controller CAN 1 con bitrate 500kbps:
from machine import CAN can = CAN(1, 500_000)
Metodi¶
- init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None¶
Inizializza il bus CAN con i parametri indicati:
bitrate è la velocità in bit del bus desiderata, espressa in bit al secondo.
mode è uno dei valori mostrati in Modalità e indica la modalità di funzionamento desiderata. Il valore predefinito è il funzionamento «normal» sul bus.
I parametri successivi sono opzionali e riguardano le temporizzazioni dei bit CAN. Nella maggior parte dei casi puoi lasciare questi parametri impostati sui valori predefiniti:
sample_point è una percentuale intera del tempo del bit di dati. Specifica la posizione del campionamento del bit rispetto all’intero tempo nominale del bit. Il driver CAN calcolerà i parametri di conseguenza. Questo parametro viene ignorato se tseg1 e tseg2 sono impostati.
sjw è l’ampiezza del salto di risincronizzazione in unità di quanti di tempo per i bit nominali; può assumere un valore compreso tra 1 e 4 inclusi per il CAN classico.
tseg1 definisce la posizione del campionamento in unità di quanti di tempo per i bit nominali; può assumere un valore compreso tra 1 e 16 inclusi per il CAN classico. È la somma delle fasi
Prop_SegePhase_Seg1come definite nello standard ISO-11898. Se questo valore è impostato, allora deve essere impostato anche tseg2 e sample_point viene ignorato.tseg2 definisce la posizione del punto di trasmissione in unità di quanti di tempo per i bit nominali; può assumere un valore compreso tra 1 e 8 inclusi per il CAN classico. Corrisponde a
Phase_Seg2nello standard ISO-11898. Se questo valore è impostato, allora deve essere impostato anche tseg1.
Se questi argomenti vengono specificati, il controller CAN viene configurato correttamente per il bitrate desiderato e per il numero totale di quanti di tempo per bit specificato. I valori tseg1 e tseg2 prevalgono sull’argomento sample_point se vengono forniti tutti questi valori.
Nota
I singoli hardware dei controller possono avere ulteriori restrizioni sui valori validi per questi parametri e solleveranno un
ValueErrorse un determinato valore non è supportato.Nota
Hardware specifici di controller possono accettare ulteriori parametri keyword opzionali per funzionalità specifiche dell’hardware, come l’oversampling.
- set_filters(filters: list | tuple | None) None¶
Imposta i filtri di ricezione nel controller CAN. filters può essere:
Noneper accettare tutti i messaggi in ingresso, oppure[]o()per disabilitare la ricezione di tutti i messaggi, oppureUn iterabile di uno o più elementi che definiscono i criteri di filtro. Ogni elemento deve essere una tupla o una lista con tre elementi:
identifierè un identificatore CAN (int).bit_maskè una maschera di bit per i bit nel campo dell’identificatore CAN (int).flagsè un intero con zero o più dei bit definiti in Flag dei messaggi impostati. Specifica le proprietà che il messaggio in ingresso deve soddisfare. Non tutti i controller supportano il filtraggio su tutti i flag; viene sollevato unValueErrorse viene richiesto un flag non supportato.
I messaggi in ingresso vengono accettati se i bit mascherati in
bit_maskcorrispondono tra l’identificatore del messaggio e il valoreidentifierdel filtro, e se i flag impostati nel filtro corrispondono al messaggio in ingresso.Se il bit
CAN.FLAG_EXT_IDè impostato nei flag, il filtro corrisponde solo agli ID CAN estesi. Se il bitCAN.FLAG_EXT_IDnon è impostato, il filtro corrisponde solo agli ID CAN standard.Tutti i filtri vengono combinati in OR nel controller. Passare una lista o una tupla vuota come argomento dei filtri significa che non verrà ricevuto alcun messaggio.
Alcuni controller CAN richiedono che ogni filtro sia associato a una sola FIFO di ricezione. In questi casi, gli elementi del filtro nell’argomento vengono assegnati in modo round-robin alle FIFO disponibili. Questo driver non distingue tra le FIFO nell’IRQ di ricezione.
Nota
Se il chiamante passa un iterabile con più elementi di
CAN.FILTERS_MAX, verrà sollevato unValueError.Nota
Se
identifierobit_maskè fuori intervallo per il tipo di ID specificato, verrà sollevato unValueErrorcon motivo «invalid id».Esempi¶
Ricevere tutti i messaggi in ingresso:
can.set_filters(None)Ricevere solo i messaggi con valori Standard ID 0x301 e 0x700:
can.set_filters(((0x301, 0x7FF, 0), (0x700, 0x7FF, 0)))
Ricevere solo i messaggi con valori Standard ID nell’intervallo 0x300-0x3FF e con valore Extended ID 0x50700:
can.set_filters(((0x300, 0x700, 0), (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
- FILTERS_MAX: int¶
Valore costante che legge il numero massimo di filtri di ricezione supportati da questo controller hardware.
Nota che alcuni controller possono avere restrizioni hardware più complesse sul numero di filtri in uso (ad esempio, contando in modo indipendente i filtri per ID standard ed esteso). In questi casi
CAN.set_filterspuò sollevare unValueErroranche quando il limiteFILTERS_MAXnon è superato.
- send(id: int, data: bytes, flags: int = 0) int | None¶
Copia un nuovo messaggio CAN nella coda di trasmissione hardware del controller per essere inviato sul bus. La coda di trasmissione è una coda di priorità ordinata in base alla priorità dell’identificatore CAN (gli identificatori numericamente inferiori hanno priorità più alta).
id è un valore intero di identificatore CAN.
data è un oggetto bytes (o simile) contenente i dati del messaggio CAN, oppure che descrive una Remote Transmission Request (vedi sotto).
flags è un intero con zero o più dei bit definiti in Flag dei messaggi impostati, che specifica le proprietà del messaggio CAN in uscita (ID esteso, Remote Transmission Request, ecc.)
Se il messaggio viene accodato con successo per la trasmissione sul bus, la funzione restituisce un intero nell’intervallo da
0aCAN.TX_QUEUE_LEN(escluso). Questo valore è l’indice del buffer di trasmissione in cui il messaggio è accodato per l’invio e può essere utilizzato dalla funzioneCAN.cancel_sende negli eventiCAN.IRQ_TX.Se la coda è piena, l’invio fallirà e verrà restituito
None.L’invio può anche fallire e restituire
Nonese il valore id fornito ha la stessa priorità di un messaggio esistente nella coda di trasmissione e l’hardware del controller CAN non può garantire che i messaggi con lo stesso ID vengano inviati sul bus nello stesso ordine in cui sono stati aggiunti alla coda. Per accodare comunque il messaggio, passa il flagCAN.FLAG_UNORDEREDnell’argomento flags. Questo flag indica che è accettabile inviare sul bus i messaggi con lo stesso ID CAN in qualsiasi ordine.Se il controller si trova nello stato di errore «Bus Off» o è disabilitato, allora la chiamata a questa funzione solleverà un
OSError.Nota
Questa implementazione volutamente a basso livello è progettata in modo che il chiamante possa stabilire una coda software di messaggi in uscita.
Importante
La «coda di trasmissione» CAN non è una coda FIFO, è ordinata per priorità e, sebbene possa contenere fino a
CAN.TX_QUEUE_LENelementi, possono esistere altre restrizioni hardware sui messaggi che possono essere accodati contemporaneamente.Remote Transmission Request¶
Se il bit
CAN.FLAG_RTRè impostato nell’argomento flags, allora il controller invierà una Remote Transmission Request invece di un messaggio. In questo caso il contenuto dell’argomento data viene ignorato. Il controller invierà una richiesta in cui il campo di lunghezzaDLCè uguale alla lunghezza dell’argomento data.Esempi¶
Tentare di inviare un messaggio con un payload di tre byte
0a0b0ce Standard ID 0x200:can.send(0x200, b"\x0a\x0b\x0c", 0)Tentare di inviare un messaggio con un payload vuoto ed Extended ID 0x180008. Indicare che il controller può inviare messaggi con questo ID in qualsiasi ordine, nel caso in cui altri messaggi con lo stesso ID siano già in coda per l’invio:
can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)Tentare di inviare una Remote Transmission Request con lunghezza 8 byte e Standard ID 0x555:
can.send(0x555, b" " * 8, can.FLAG_RTR)
- recv(arg: list | None = None) list | None¶
Restituisce un messaggio CAN ricevuto dal controller, in base ai filtri impostati con
CAN.set_filters().Questa funzione accetta un singolo argomento opzionale; se fornito, deve essere una lista di almeno 4 elementi in cui il secondo elemento è un oggetto
memoryviewche fa riferimento a un oggettobytearrayo simile con capacità sufficiente a contenere qualsiasi messaggio CAN ricevuto (8 byte per CAN Classic, 64 byte per CAN FD). La lista fornita verrà restituita come risultato in caso di successo, evitando l’allocazione di memoria all’interno della funzione.Se il controller CAN non ha ricevuto alcun messaggio, questa funzione restituisce
None.Nota
CAN.set_filtersdeve essere chiamata prima che il controller possa ricevere qualsiasi messaggio. Per ricevere tutti i messaggi, chiamaset_filters(None).Se un messaggio è stato ricevuto dal controller CAN, questa funzione restituisce una lista con 4 elementi:
L’indice 0 è l’ID CAN del messaggio ricevuto, come intero.
L’indice 1 è una memoryview che fornisce l’accesso ai dati del messaggio ricevuto.
Se arg non viene fornito, allora questa è una
memoryviewche contiene i byte ricevuti. Questamemoryviewè supportata da unbytearrayappena allocato, abbastanza grande da contenere qualsiasi messaggio CAN ricevuto. Questo consente di riutilizzare in sicurezza il risultato come futuro arg, per risparmiare allocazioni di memoria.Se arg viene fornito, allora la
memoryviewfornita verrà ridimensionata per contenere esattamente i byte ricevuti. Il chiamante è responsabile di assicurarsi che l’oggetto di supporto dellamemoryviewpossa contenere un messaggio CAN di qualsiasi lunghezza.
L’indice 2 è un intero con zero o più dei bit definiti in Flag dei messaggi impostati. Indica i metadati relativi al messaggio ricevuto.
L’indice 3 è un intero con zero o più dei bit definiti in Flag di errore di ricezione impostati. Qualsiasi valore diverso da zero indica potenziali problemi durante la ricezione dei messaggi CAN. Questi flag vengono azzerati all’interno del controller ogni volta che questa funzione restituisce un valore.
Remote Transmission Request¶
Se viene ricevuta una Remote Transmission Request, allora il bit
CAN.FLAG_RTRsarà impostato nell’Indice 2 e la memoryview all’Indice 1 conterrà tutti zeri, con una lunghezza pari al campoDLCdella richiesta ricevuta.Esempio¶
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¶
Imposta una funzione handler di interrupt da chiamare quando si è verificato uno o più degli eventi segnalati in trigger.
handler è una funzione da chiamare quando l’evento di interrupt viene attivato. L’handler deve accettare esattamente un argomento, che è l’istanza
CAN.trigger configura gli eventi che possono generare un interrupt. I valori possibili sono una maschera di uno o più dei seguenti:
L’evento
CAN.IRQ_RXsi verifica dopo che il controller CAN ha ricevuto almeno un messaggio nella sua FIFO RX (il che significa cheCAN.recv()restituirà un valore con successo).L’evento
CAN.IRQ_TXsi verifica dopo che il controller CAN ha inviato con successo un messaggio sul bus CAN oppure non è riuscito a inviare un messaggio. Questo trigger ha requisiti aggiuntivi per l’handler, vedi Flag IRQ per i dettagli.L’evento
CAN.IRQ_STATEsi verifica quando il controller CAN è passato a uno stato di errore più grave. ChiamaCAN.state()per ottenere lo stato aggiornato.
hard se True, viene utilizzato un hard interrupt. Questo riduce il ritardo tra l’evento del controller CAN e la chiamata dell’handler. Gli handler di hard interrupt non possono allocare memoria; vedi Scrittura dei gestori di interrupt.
Restituisce un oggetto irq. Se chiamata senza argomenti, viene restituito un oggetto irq configurato in precedenza.
Vedi Flag IRQ per un esempio.
- cancel_send(index: int) bool¶
Richiede al controller CAN di annullare l’invio di un messaggio sul bus.
L’argomento index identifica un singolo buffer di trasmissione. Deve essere un intero nell’intervallo da
0aCAN.TX_QUEUE_LEN(escluso). Generalmente sarà un valore restituito in precedenza daCAN.send().Il risultato è
Truese un messaggio era in attesa di trasmissione in questo buffer e la trasmissione è stata annullata.Il risultato è
Falsein caso contrario (o nessun messaggio era in attesa di trasmissione in questo buffer, oppure la trasmissione è già riuscita).L’evento IRQ
CAN.IRQ_TXdovrebbe essere utilizzato per determinare se un messaggio è stato sicuramente inviato o meno, ma nota che esistono potenziali race condition se una trasmissione viene annullata e poi lo stesso buffer viene utilizzato per inviare un altro messaggio (specialmente se l’IRQ del controller CAN non è di tipo «hard»).
- state() int¶
Restituisce un valore intero che indica lo stato attuale del controller. Il valore sarà uno dei valori definiti in Stati.
Gli stati di errore di minore gravità possono azzerarsi automaticamente se il bus si ripristina, ma lo stato
CAN.STATE_BUS_OFFpuò essere ripristinato solo chiamandoCAN.restart().
- get_counters(list: list | None = None, /) list¶
Restituisce i valori dei contatori di errore del controller. Il risultato è una lista di otto valori. Se viene specificato il parametro opzionale list, allora l’oggetto lista fornito viene aggiornato e restituito come risultato, per evitare un’allocazione.
Gli elementi della lista sono:
Valore TEC (Transmit Error Counter)
Valore REC (Receive Error Counter)
Numero di volte in cui il controller è entrato nello stato Warning dallo stato Active.
Numero di volte in cui il controller è entrato nello stato Error Passive dallo stato Warning.
Numero di volte in cui il controller è entrato nello stato Bus Off dallo stato Error Passive.
Numero totale di messaggi TX in sospeso nella coda hardware.
Numero totale di messaggi RX in sospeso nella coda hardware.
Numero di volte in cui si è verificato un overrun RX.
Nota
A seconda del controller, questi valori possono andare in overflow tornando a 0 dopo un certo valore.
Nota
Se un controller non supporta un particolare contatore, restituirà
Noneper quell’elemento della lista.
- get_timings(list: list | None = None, /) list¶
Restituisce una lista di elementi che indicano le temporizzazioni attualmente configurate nel controller CAN. Può essere utilizzata per verificare le temporizzazioni a scopo di debug. Il risultato è una lista di sei valori. Se viene specificato il parametro opzionale list, allora l’oggetto lista fornito viene aggiornato e restituito come risultato, per evitare un’allocazione.
Gli elementi della lista sono:
Bitrate esatto utilizzato dal controller. Può differire dall’argomento bitrate passato a
CAN.init()a causa della quantizzazione necessaria per soddisfare i vincoli hardware.Ampiezza del salto di risincronizzazione (SJW) in unità di quanti di tempo per i bit nominali. Ha lo stesso significato del parametro sjw di
CAN.init().Posizione del campionamento in unità di quanti di tempo per i bit nominali. Ha lo stesso significato del parametro tseg1 di
CAN.init().Posizione del punto di trasmissione in unità di quanti di tempo per i bit nominali. Ha lo stesso significato del parametro tseg2 di
CAN.init().Informazioni di temporizzazione CAN FD.
Noneper i controller che non supportano CAN FD, oppure se il CAN FD non è inizializzato. Altrimenti, una lista annidata di quattro elementi corrispondenti alle voci precedenti ma applicabili alla funzionalità BRS del CAN FD.Informazioni di temporizzazione opzionali specifiche del controller. A seconda del controller, sarà
Nonese il controller non ne fornisce alcuna, oppure sarà una lista di lunghezza costante i cui elementi sono specifici di un particolare controller hardware.
Nota
Se
CAN.init()non è stata chiamata, questa funzione restituisce comunque un risultato, ma il risultato dipende dagli aspetti interni del controller e potrebbe non essere accurato.
- restart() None¶
Fa uscire il controller dallo stato
STATE_BUS_OFFsenza azzerare alcun altro stato interno. Azzera inoltre alcuni dei contatori di errore (sempre il numero di volte in cui è stato raggiunto ciascuno stato di errore, eventualmente TEC e REC a seconda del controller).La chiamata a questa funzione annulla anche tutti i messaggi in attesa di essere inviati. Per questi messaggi non vengono generati interrupt
IRQ_TX.Nota che questa funzione può o meno far uscire il controller dallo stato «Error Passive», a seconda che l’hardware del controller azzeri o meno TEC e REC.
- deinit() None¶
De-inizializza un’istanza CAN precedentemente attiva. Tutti i messaggi in sospeso (in trasmissione e in ricezione) vengono scartati e il controller smette di interagire sul bus. Per utilizzare nuovamente questa istanza, chiama
CAN.init().In risposta alla chiamata di questa funzione non viene chiamato alcun interrupt
IRQ_TXoIRQ_RX.Vedi anche
CAN.restart().
Costanti¶
- TX_QUEUE_LEN: int¶
Numero massimo di messaggi CAN che possono essere accodati nella coda hardware dei messaggi in uscita del controller. Gli «indici del buffer di trasmissione» utilizzati da
CAN.send(),CAN.cancel_send()e Flag IRQ saranno in questo intervallo.
Modalità¶
Questi valori rappresentano le modalità di funzionamento del controller, come passate a
CAN.init(). Non tutti i controller possono supportare tutte le modalità.La modifica della modalità di un controller in funzione richiede di chiamare
CAN.deinit()e poi di chiamare nuovamenteCAN.init()con la nuova modalità.- MODE_NORMAL: int¶
Il controller è attivo come nodo di rete CAN standard (riconoscerà i messaggi validi e potrà trasmettere errori a seconda del suo Stato attuale).
- MODE_SLEEP: int¶
Il controller CAN è in stato di riposo in una modalità a basso consumo. A seconda del controller, ciò può supportare il risveglio del controller e la transizione a
CAN.MODE_NORMALse viene ricevuto traffico CAN.
- MODE_LOOPBACK: int¶
Una modalità di test. Il controller CAN è ancora connesso al bus esterno, ma riceverà anche i propri messaggi trasmessi e ignorerà eventuali errori di ACK.
Stati¶
Questi valori vengono restituiti da
CAN.state()e riflettono lo stato di errore del controller CAN:- STATE_ACTIVE: int¶
Il controller è attivo e i contatori di errore
TECeRECsono entrambi al di sotto della soglia di warning di 96. VediCAN.get_counters().
- STATE_WARNING: int¶
Il controller è attivo ma almeno uno dei contatori di errore
TECeRECè compreso tra 96 e 127. VediCAN.get_counters().
- STATE_PASSIVE: int¶
Il controller è nello stato «Error Passive», il che significa che non trasmette più errori attivi sul bus, ma per il resto è funzionante. Si entra in questo stato quando almeno uno dei contatori di errore
TECeRECè pari o superiore a 128, maTECè inferiore a 255. VediCAN.get_counters().
- STATE_BUS_OFF: int¶
Il controller è nello stato Bus-Off, il che significa che il contatore di errore
TECè maggiore di 255. In questo stato il controller CAN non interagirà con il bus e deve essere riavviato tramiteCAN.restart()per continuare.
Flag dei messaggi¶
Questi valori rappresentano i metadati relativi a un messaggio CAN. Le funzioni
CAN.send(),CAN.recv()eCAN.set_filters()accettano o restituiscono un valore intero composto da zero o più di questi flag combinati tra loro in OR bit a bit.- FLAG_EXT_ID: int¶
Se impostato, indica che un identificatore di messaggio è Esteso (29 bit). Se non impostato, indica che un identificatore di messaggio è Standard (11 bit).
- FLAG_UNORDERED: int¶
Se impostato nell’argomento
flagsdiCAN.send(), indica che è accettabile che i messaggi con lo stesso ID CAN vengano inviati sul bus in qualsiasi ordine.In caso contrario, tentare di accodare più messaggi con lo stesso ID può causare il fallimento di
CAN.send()se l’hardware del controller non è in grado di garantire l’ordinamento.Questo flag non viene mai impostato sui messaggi ricevuti e viene ignorato da
CAN.set_filters().
Flag di errore di ricezione¶
Il risultato di
CAN.recv()include un valore intero composto da zero o più di questi flag combinati tra loro in OR bit a bit. Se impostati, questi flag indicano potenziali problemi generali nella ricezione dei messaggi CAN.Valori IRQ¶
- IRQ_RX: int¶
Passa all’argomento
triggerdiirq()per attivare l’handler ogni volta che il controller CAN ha ricevuto un messaggio completo nella FIFO RX. All’interno dell’handler, leggi il messaggio conrecv().
- IRQ_TX: int¶
Passa all’argomento
triggerdiirq()per attivare l’handler ogni volta che il controller CAN termina un tentativo di trasmissione (con successo o con fallimento). All’interno dell’handler, usa i bit aggiuntivi qui sotto per recuperare quale mailbox è stata completata e se è fallita – vedi Flag IRQ.
- IRQ_STATE: int¶
Passa all’argomento
triggerdiirq()per attivare l’handler ogni volta che il controller passa tra i valoriSTATE_*(active / warning / passive / bus-off). Usastate()all’interno dell’handler per leggere il nuovo stato.
- IRQ_TX_FAILED: int¶
Flag di stato che può essere impostato in
irq().flags()quando si verifica un eventoIRQ_TX. Indica che il tentativo di trasmissione è fallito (tipicamente perché è stato chiamatocancel_send(), oppure perché il controller è entrato in uno stato di errore).
- IRQ_TX_IDX_SHIFT: int¶
Posizione del bit del campo indice-mailbox-di-trasmissione all’interno del valore
irq().flags()durante un eventoIRQ_TX. L’indice della mailbox viene estratto come(flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.
- IRQ_TX_IDX_MASK: int¶
Maschera di bit del campo indice-mailbox-di-trasmissione all’interno del valore
irq().flags()durante un eventoIRQ_TX. L’indice estratto corrisponde all’intero restituito dalla corrispondente chiamatasend()(un int nell’intervallo da0aTX_QUEUE_LEN).
Flag IRQ¶
La chiamata a CAN.irq() registra un handler di interrupt con uno o più dei trigger CAN.IRQ_RX, CAN.IRQ_TX e CAN.IRQ_STATE.
La funzione restituisce un oggetto IRQ e la chiamata alla funzione flags() su questo oggetto restituisce un intero che indica quale evento o eventi di trigger hanno attivato l’interrupt. Un handler di IRQ CAN dovrebbe chiamare la funzione flags() ripetutamente finché non restituisce 0.
Quando la funzione flags() restituisce un valore con il bit CAN.IRQ_TX impostato, l’handler può anche controllare i seguenti bit di flag nel risultato per ottenere informazioni aggiuntive sull’evento TX:
Il bit
CAN.IRQ_TX_FAILEDè impostato se la trasmissione è fallita. Di solito ciò accade solo se è stata chiamataCAN.cancel_send(), sebbene possa accadere anche se il controller entra in uno stato di errore.CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFTè una regione mascherata in bit del valore dei flag che contiene l’indice del buffer di trasmissione che ha generato l’evento. Sarà un intero nell’intervallo da0aCAN.TX_QUEUE_LEN(escluso) e corrisponderà al risultato di una precedente chiamata aCAN.send().
Esempio di 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)
Importante
Se il trigger CAN.IRQ_TX è impostato, allora l’handler deve chiamare flags() ripetutamente finché non restituisce 0, come mostrato in questo esempio. Altrimenti, gli interrupt CAN potrebbero non essere riabilitati correttamente.