classe CAN – protocole Controller Area Network¶
CAN est un protocole série à deux fils utilisé pour la transmission fiable de messages en temps réel entre un ou plusieurs nœuds connectés à un bus commun. CAN 2.0 a été normalisé dans la norme ISO-11898 et est désormais également connu sous le nom de CAN Classic.
Il existe également un protocole plus récent et rétrocompatible nommé CAN FD (CAN with Flexible Data-Rate). Le pilote machine.CAN ne prend actuellement pas en charge les fonctionnalités CAN FD ; utilisez pyb.CAN sur STM32 si vous avez besoin de CAN FD.
La prise en charge de CAN nécessite un contrôleur (souvent un périphérique interne du microcontrôleur) et un émetteur-récepteur externe pour adapter le niveau des signaux sur le bus CAN.
Disponible sur les OpenMV cams STM32 (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, ainsi que les variantes de marque Arduino qui câblent un émetteur-récepteur). Pas encore pris en charge sur l’OpenMV Cam RT1062 (port mimxrt) ni sur l’OpenMV Cam AE3 (port alif).
L’interface machine.CAN est une interface de messagerie CAN de bas niveau et basique qui présente un contrôleur CAN sous la forme d’une file d’attente de priorité sortante pour l’envoi des messages, d’une file d’attente entrante pour la réception des messages, et de mécanismes de signalement des erreurs.
Note
Les modules micropython-lib can et aiocan prévus seront la méthode recommandée pour utiliser CAN avec MicroPython.
Constructeur¶
- class machine.CAN(id: int, *args, **kwargs)¶
Construit un objet contrôleur CAN avec l’identifiant donné :
ididentifie un objet contrôleur CAN particulier ; il est spécifique à la carte et au port.Tous les autres arguments sont passés à
CAN.init(). Au moins un argument (bitrate) doit être fourni.
Les versions futures de cette classe pourront également accepter ici des arguments nommés spécifiques au port qui configurent le matériel. Actuellement, aucun argument nommé de ce type n’est implémenté.
Exemple¶
Construire et initialiser le contrôleur CAN 1 avec un débit de 500 kbit/s
from machine import CAN can = CAN(1, 500_000)
Méthodes¶
- init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None¶
Initialise le bus CAN avec les paramètres donnés :
bitrate est le débit binaire souhaité du bus en bits par seconde.
mode est l’une des valeurs indiquées sous Modes, désignant le mode de fonctionnement souhaité. La valeur par défaut est le fonctionnement « normal » sur le bus.
Les paramètres suivants sont facultatifs et concernent les temporisations des bits CAN. Dans la plupart des cas, vous pouvez laisser ces paramètres aux valeurs par défaut :
sample_point est un pourcentage entier du temps d’un bit de données. Il spécifie la position de l’échantillonnage du bit par rapport au temps nominal total du bit. Le pilote CAN calculera les paramètres en conséquence. Ce paramètre est ignoré si tseg1 et tseg2 sont définis.
sjw est la largeur de saut de resynchronisation en unités de quanta de temps pour les bits nominaux ; il peut prendre une valeur comprise entre 1 et 4 inclus pour le CAN classique.
tseg1 définit l’emplacement du point d’échantillonnage en unités de quanta de temps pour les bits nominaux ; il peut prendre une valeur comprise entre 1 et 16 inclus pour le CAN classique. Il s’agit de la somme des phases
Prop_SegetPhase_Seg1telles que définies dans la norme ISO-11898. Si cette valeur est définie, alors tseg2 doit également l’être et sample_point est ignoré.tseg2 définit l’emplacement du point de transmission en unités de quanta de temps pour les bits nominaux ; il peut prendre une valeur comprise entre 1 et 8 inclus pour le CAN classique. Cela correspond à
Phase_Seg2dans la norme ISO-11898. Si cette valeur est définie, alors tseg1 doit également l’être.
Si ces arguments sont spécifiés, le contrôleur CAN est configuré correctement pour le bitrate souhaité et le nombre total de quanta de temps par bit spécifié. Les valeurs tseg1 et tseg2 prévalent sur l’argument sample_point si tous ces éléments sont fournis.
Note
Le matériel de certains contrôleurs peut imposer des restrictions supplémentaires sur les valeurs valides de ces paramètres, et lèvera une
ValueErrorsi une valeur donnée n’est pas prise en charge.Note
Le matériel de certains contrôleurs spécifiques peut accepter des arguments nommés facultatifs supplémentaires pour des fonctionnalités propres au matériel, telles que le suréchantillonnage.
- set_filters(filters: list | tuple | None) None¶
Définit les filtres de réception dans le contrôleur CAN. filters peut être :
Nonepour accepter tous les messages entrants, ou[]ou()pour désactiver toute réception de messages, ouun itérable d’un ou plusieurs éléments définissant les critères de filtrage. Chaque élément doit être un tuple ou une liste de trois éléments :
identifierest un identifiant CAN (int).bit_maskest un masque de bits pour les bits du champ d’identifiant CAN (int).flagsest un entier comportant zéro ou plusieurs des bits définis dans Drapeaux de message. Cela spécifie les propriétés auxquelles le message entrant doit correspondre. Tous les contrôleurs ne prennent pas en charge le filtrage sur tous les drapeaux ; uneValueErrorest levée si un drapeau non pris en charge est demandé.
Les messages entrants sont acceptés si les bits masqués dans
bit_maskcorrespondent entre l’identifiant du message et la valeuridentifierdu filtre, et si les drapeaux définis dans le filtre correspondent au message entrant.Si le bit
CAN.FLAG_EXT_IDest défini dans les drapeaux, le filtre ne correspond qu’aux ID CAN étendus. Si le bitCAN.FLAG_EXT_IDn’est pas défini, le filtre ne correspond qu’aux ID CAN standard.Tous les filtres sont combinés par OU dans le contrôleur. Passer une liste ou un tuple vide pour l’argument filters signifie qu’aucun message ne sera reçu.
Certains contrôleurs CAN exigent que chaque filtre soit associé à une seule FIFO de réception. Dans ces cas, les éléments de filtre de l’argument sont répartis à tour de rôle (round-robin) entre les FIFO disponibles. Ce pilote ne fait pas de distinction entre les FIFO dans l’IRQ de réception.
Note
Si l’appelant passe un itérable comportant plus d’éléments que
CAN.FILTERS_MAX, uneValueErrorsera levée.Note
Si soit l”
identifiersoit lebit_maskest hors plage pour le type d’ID spécifié, uneValueErroravec le motif « invalid id » sera levée.Exemples¶
Recevoir tous les messages entrants
can.set_filters(None)Recevoir uniquement les messages avec les valeurs d’ID standard 0x301 et 0x700
can.set_filters(((0x301, 0x7FF, 0), (0x700, 0x7FF, 0)))
Recevoir les messages avec des valeurs d’ID standard dans la plage 0x300-0x3FF, et uniquement la valeur d’ID étendu 0x50700
can.set_filters(((0x300, 0x700, 0), (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
- FILTERS_MAX: int¶
Constante dont la valeur renseigne le nombre maximal de filtres de réception pris en charge par ce contrôleur matériel.
Notez que certains contrôleurs peuvent imposer des restrictions matérielles plus complexes sur le nombre de filtres utilisés (par exemple, en comptant indépendamment les filtres d’ID standard et étendu). Dans ces cas,
CAN.set_filterspeut lever uneValueErrormême lorsque la limiteFILTERS_MAXn’est pas dépassée.
- send(id: int, data: bytes, flags: int = 0) int | None¶
Copie un nouveau message CAN dans la file d’attente de transmission matérielle du contrôleur pour l’envoyer sur le bus. La file d’attente de transmission est une file de priorité triée selon la priorité de l’identifiant CAN (les identifiants numériquement plus bas ont une priorité plus élevée).
id est une valeur entière d’identifiant CAN.
data est un objet bytes (ou similaire) contenant les données du message CAN, ou décrivant une requête de transmission distante (Remote Transmission Request, voir ci-dessous).
flags est un entier comportant zéro ou plusieurs des bits définis dans Drapeaux de message, spécifiant les propriétés du message CAN sortant (ID étendu, requête de transmission distante, etc.).
Si le message est mis en file d’attente avec succès pour transmission sur le bus, la fonction renvoie un entier dans la plage
0àCAN.TX_QUEUE_LEN(exclu). Cette valeur est l’index du tampon de transmission où le message est mis en file d’attente pour envoi, et peut être utilisée par la fonctionCAN.cancel_sendet dans les événementsCAN.IRQ_TX.Si la file d’attente est pleine, l’envoi échouera et
Nonesera renvoyé.L’envoi peut également échouer et renvoyer
Nonesi la valeur id fournie a une priorité égale à celle d’un message existant dans la file d’attente de transmission et que le matériel du contrôleur CAN ne peut pas garantir que les messages ayant le même ID seront envoyés sur le bus dans le même ordre que celui où ils ont été ajoutés à la file. Pour mettre le message en file d’attente malgré tout, passez le drapeauCAN.FLAG_UNORDEREDdans l’argument flags. Ce drapeau indique qu’il est acceptable d’envoyer sur le bus des messages ayant le même ID CAN dans n’importe quel ordre.Si le contrôleur est dans l’état d’erreur « Bus Off » ou désactivé, l’appel de cette fonction lèvera une
OSError.Note
Cette implémentation volontairement de bas niveau est conçue pour que l’appelant puisse établir une file d’attente logicielle de messages sortants.
Important
La « file d’attente de transmission » CAN n’est pas une file FIFO, elle est ordonnée par priorité, et bien qu’elle puisse contenir jusqu’à
CAN.TX_QUEUE_LENéléments, il peut exister d’autres restrictions matérielles sur les messages pouvant être mis en file d’attente simultanément.Requêtes de transmission distante¶
Si le bit
CAN.FLAG_RTRest défini dans l’argument flags, le contrôleur enverra une requête de transmission distante au lieu d’un message. Dans ce cas, le contenu de l’argument data est ignoré. Le contrôleur enverra une requête dont le champ de longueurDLCest égal à la longueur de l’argument data.Exemples¶
Tenter d’envoyer un message avec une charge utile de trois octets
0a0b0cet un ID standard 0x200can.send(0x200, b"\x0a\x0b\x0c", 0)Tenter d’envoyer un message avec une charge utile vide et un ID étendu 0x180008. Indiquer que le contrôleur peut envoyer des messages avec cet ID dans n’importe quel ordre, au cas où d’autres messages seraient déjà en file d’attente pour envoi avec le même ID
can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)Tenter d’envoyer une requête de transmission distante d’une longueur de 8 octets et avec un ID standard 0x555
can.send(0x555, b" " * 8, can.FLAG_RTR)
- recv(arg: list | None = None) list | None¶
Renvoie un message CAN qui a été reçu par le contrôleur, conformément aux filtres définis par
CAN.set_filters().Cette fonction prend un seul argument facultatif ; s’il est fourni, ce doit être une liste d’au moins 4 éléments où le deuxième élément est un objet
memoryviewfaisant référence à unbytearrayou un objet similaire dont la capacité est suffisante pour contenir n’importe quel message CAN reçu (8 octets pour le CAN Classic, 64 octets pour le CAN FD). La liste fournie sera renvoyée en tant que résultat valide, et évite l’allocation de mémoire à l’intérieur de la fonction.Si aucun message n’a été reçu par le contrôleur CAN, cette fonction renvoie
None.Note
CAN.set_filtersdoit être appelée avant qu’aucun message ne puisse être reçu par le contrôleur. Pour recevoir tous les messages, appelezset_filters(None).Si un message a été reçu par le contrôleur CAN, cette fonction renvoie une liste de 4 éléments :
L’index 0 est l’ID CAN du message reçu, sous forme d’entier.
L’index 1 est un memoryview qui donne accès aux données du message reçu.
Si arg n’est pas fourni, il s’agit d’un
memoryviewcontenant les octets qui ont été reçus. Cememoryviewest adossé à unbytearraynouvellement alloué, suffisamment grand pour contenir n’importe quel message CAN reçu. Cela permet de réutiliser le résultat en toute sécurité comme un futur arg, afin d’économiser des allocations de mémoire.Si arg est fourni, le
memoryviewfourni sera redimensionné pour contenir exactement les octets qui ont été reçus. Il incombe à l’appelant de s’assurer que l’objet adossé aumemoryviewpeut contenir un message CAN de n’importe quelle longueur.
L’index 2 est un entier comportant zéro ou plusieurs des bits définis dans Drapeaux de message. Il indique des métadonnées sur le message reçu.
L’index 3 est un entier comportant zéro ou plusieurs des bits définis dans Drapeaux d’erreur de réception. Toute valeur non nulle indique des problèmes potentiels lors de la réception de messages CAN. Ces drapeaux sont réinitialisés à l’intérieur du contrôleur à chaque retour de cette fonction.
Requêtes de transmission distante¶
Si une requête de transmission distante est reçue, le bit
CAN.FLAG_RTRsera défini à l’index 2 et le memoryview à l’index 1 contiendra uniquement des zéros, avec une longueur égale au champDLCde la requête reçue.Exemple¶
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¶
Définit une fonction de traitement d’interruption handler à appeler lorsqu’un ou plusieurs des événements signalés dans trigger se sont produits.
handler est une fonction à appeler lorsque l’événement d’interruption se déclenche. Le gestionnaire doit prendre exactement un argument, qui est l’instance
CAN.trigger configure le ou les événements pouvant générer une interruption. Les valeurs possibles sont un masque d’un ou plusieurs des éléments suivants :
L’événement
CAN.IRQ_RXse produit après que le contrôleur CAN a reçu au moins un message dans sa FIFO RX (ce qui signifie queCAN.recv()retournera avec succès).L’événement
CAN.IRQ_TXse produit après que le contrôleur CAN a soit envoyé avec succès un message sur le bus CAN, soit échoué à envoyer un message. Ce déclencheur impose des exigences supplémentaires au gestionnaire, voir Drapeaux d’IRQ pour plus de détails.L’événement
CAN.IRQ_STATEse produit lorsque le contrôleur CAN est passé dans un état d’erreur plus grave. AppelezCAN.state()pour obtenir l’état mis à jour.
hard si True, une interruption matérielle est utilisée. Cela réduit le délai entre l’événement du contrôleur CAN et l’appel du gestionnaire. Les gestionnaires d’interruption matérielle ne peuvent pas allouer de mémoire ; voir Écriture de gestionnaires d’interruption.
Renvoie un objet irq. Si appelée sans argument, un objet irq précédemment configuré est renvoyé.
Voir Drapeaux d’IRQ pour un exemple.
- cancel_send(index: int) bool¶
Demande au contrôleur CAN d’annuler l’envoi d’un message sur le bus.
L’argument index identifie un seul tampon de transmission. Ce doit être un entier dans la plage
0àCAN.TX_QUEUE_LEN(exclu). En général, il s’agira d’une valeur précédemment renvoyée parCAN.send().Le résultat est
Truesi un message était en attente de transmission dans ce tampon et que la transmission a été annulée.Le résultat est
Falsesinon (soit aucun message n’était en attente de transmission dans ce tampon, soit la transmission a déjà réussi).L’événement IRQ
CAN.IRQ_TXdoit être utilisé pour déterminer si un message a été ou non effectivement envoyé, mais notez qu’il existe des conditions de concurrence potentielles si une transmission est annulée puis que le même tampon est utilisé pour envoyer un autre message (surtout si l’IRQ du contrôleur CAN n’est pas « matérielle »).
- state() int¶
Renvoie une valeur entière indiquant l’état actuel du contrôleur. La valeur sera l’une des valeurs définies dans États.
Les états d’erreur de moindre gravité peuvent se résorber automatiquement si le bus se rétablit, mais l’état
CAN.STATE_BUS_OFFne peut être récupéré qu’en appelantCAN.restart().
- get_counters(list: list | None = None, /) list¶
Renvoie les valeurs des compteurs d’erreurs du contrôleur. Le résultat est une liste de huit valeurs. Si le paramètre facultatif list est spécifié, l’objet liste fourni est mis à jour et renvoyé comme résultat, afin d’éviter une allocation.
Les éléments de la liste sont :
valeur du TEC (Transmit Error Counter)
valeur du REC (Receive Error Counter)
Nombre de fois où le contrôleur est passé de l’état Active à l’état Warning.
Nombre de fois où le contrôleur est passé de l’état Warning à l’état Error Passive.
Nombre de fois où le contrôleur est passé de l’état Error Passive à l’état Bus Off.
Nombre total de messages TX en attente dans la file d’attente matérielle.
Nombre total de messages RX en attente dans la file d’attente matérielle.
Nombre de fois où un débordement (overrun) RX s’est produit.
Note
Selon le contrôleur, ces valeurs peuvent revenir par débordement à 0 après une certaine valeur.
Note
Si un contrôleur ne prend pas en charge un compteur particulier, il renverra
Nonepour cet élément de la liste.
- get_timings(list: list | None = None, /) list¶
Renvoie une liste d’éléments indiquant les temporisations actuellement configurées dans le contrôleur CAN. Cela peut être utilisé pour vérifier les temporisations à des fins de débogage. Le résultat est une liste de six valeurs. Si le paramètre facultatif list est spécifié, l’objet liste fourni est mis à jour et renvoyé comme résultat, afin d’éviter une allocation.
Les éléments de la liste sont :
Débit binaire exact utilisé par le contrôleur. Peut différer de l’argument bitrate passé à
CAN.init()en raison de la quantification nécessaire pour respecter les contraintes matérielles.Largeur de saut de resynchronisation (SJW) en unités de quanta de temps pour les bits nominaux. A la même signification que le paramètre sjw de
CAN.init().Emplacement du point d’échantillonnage en unités de quanta de temps pour les bits nominaux. A la même signification que le paramètre tseg1 de
CAN.init().Emplacement du point de transmission en unités de quanta de temps pour les bits nominaux. A la même signification que le paramètre tseg2 de
CAN.init().Informations de temporisation CAN FD.
Nonepour les contrôleurs qui ne prennent pas en charge le CAN FD, ou si le CAN FD n’est pas initialisé. Sinon, une liste imbriquée de quatre éléments correspondant aux éléments ci-dessus mais applicables à la fonctionnalité BRS du CAN FD.Informations de temporisation facultatives propres au contrôleur. Selon le contrôleur, ce sera soit
Nonesi le contrôleur n’en signale aucune, soit une liste de longueur constante dont les éléments sont spécifiques à un contrôleur matériel particulier.
Note
Si
CAN.init()n’a pas été appelée, cette fonction renvoie tout de même un résultat, mais celui-ci dépend des éléments internes du contrôleur et peut ne pas être précis.
- restart() None¶
Fait sortir le contrôleur de l’état
STATE_BUS_OFFsans effacer aucun autre état interne. Réinitialise également certains des compteurs d’erreurs (toujours le nombre de fois où chaque état d’erreur a été atteint, et éventuellement le TEC et le REC selon le contrôleur).L’appel de cette fonction annule également tous les messages en attente d’envoi. Aucune interruption
IRQ_TXn’est délivrée pour ces messages.Notez que cette fonction peut ou non faire sortir le contrôleur de l’état « Error Passive », selon que le matériel du contrôleur remet ou non à zéro le TEC et le REC.
- deinit() None¶
Désinitialise une instance CAN précédemment active. Tous les messages en attente (transmission et réception) sont abandonnés et le contrôleur cesse d’interagir sur le bus. Pour réutiliser cette instance, appelez
CAN.init().Aucune interruption
IRQ_TXouIRQ_RXn’est appelée en réponse à l’appel de cette fonction.Voir aussi
CAN.restart().
Constantes¶
- TX_QUEUE_LEN: int¶
Nombre maximal de messages CAN pouvant être mis en file d’attente dans la file d’attente de messages matérielle sortante du contrôleur. Les « index de tampon de transmission » utilisés par
CAN.send(),CAN.cancel_send()et Drapeaux d’IRQ seront dans cette plage.
Modes¶
Ces valeurs représentent les modes de fonctionnement du contrôleur, tels que passés à
CAN.init(). Tous les contrôleurs ne prennent pas nécessairement en charge tous les modes.Changer le mode d’un contrôleur en cours d’exécution nécessite d’appeler
CAN.deinit()puis d’appeler à nouveauCAN.init()avec le nouveau mode.- MODE_NORMAL: int¶
Le contrôleur est actif en tant que nœud standard d’un réseau CAN (il accusera réception des messages valides et pourra transmettre des erreurs selon son État actuel).
- MODE_SLEEP: int¶
Le contrôleur CAN est en veille dans un mode basse consommation. Selon le contrôleur, cela peut permettre de réveiller le contrôleur et de le faire passer en
CAN.MODE_NORMALsi du trafic CAN est reçu.
- MODE_LOOPBACK: int¶
Un mode de test. Le contrôleur CAN est toujours connecté au bus externe, mais il recevra également ses propres messages transmis et ignorera toute erreur d’ACK.
États¶
Ces valeurs sont renvoyées par
CAN.state()et reflètent l’état d’erreur du contrôleur CAN :- STATE_ACTIVE: int¶
Le contrôleur est actif et les compteurs d’erreurs
TECetRECsont tous deux en dessous du seuil d’avertissement de 96. VoirCAN.get_counters().
- STATE_WARNING: int¶
Le contrôleur est actif mais au moins l’un des compteurs d’erreurs
TECetRECest compris entre 96 et 127. VoirCAN.get_counters().
- STATE_PASSIVE: int¶
Le contrôleur est dans l’état « Error Passive », ce qui signifie qu’il ne transmet plus d’erreurs actives sur le bus, mais qu’il reste par ailleurs fonctionnel. Cet état est atteint lorsqu’au moins l’un des compteurs d’erreurs
TECetRECest supérieur ou égal à 128, mais queTECest inférieur à 255. VoirCAN.get_counters().
- STATE_BUS_OFF: int¶
Le contrôleur est dans l’état Bus-Off, ce qui signifie que le compteur d’erreurs
TECest supérieur à 255. Le contrôleur CAN n’interagira pas avec le bus dans cet état, et doit être redémarré viaCAN.restart()pour continuer.
Drapeaux de message¶
Ces valeurs représentent des métadonnées sur un message CAN. Les fonctions
CAN.send(),CAN.recv()etCAN.set_filters()acceptent ou renvoient une valeur entière composée de zéro ou plusieurs de ces drapeaux combinés par OU bit à bit.- FLAG_EXT_ID: int¶
Si défini, indique qu’un identifiant de message est étendu (29 bits). Si non défini, indique qu’un identifiant de message est standard (11 bits).
- FLAG_UNORDERED: int¶
Si défini dans l’argument
flagsdeCAN.send(), indique qu’il est acceptable que les messages ayant le même ID CAN soient envoyés sur le bus dans n’importe quel ordre.Sinon, tenter de mettre en file d’attente plusieurs messages ayant le même ID peut entraîner l’échec de
CAN.send()si le matériel du contrôleur ne peut pas garantir l’ordre.Ce drapeau n’est jamais défini sur les messages reçus, et est ignoré par
CAN.set_filters().
Drapeaux d’erreur de réception¶
Le résultat de
CAN.recv()comprend une valeur entière composée de zéro ou plusieurs de ces drapeaux combinés par OU bit à bit. S’ils sont définis, ces drapeaux indiquent des problèmes généraux potentiels lors de la réception de messages CAN.Valeurs d’IRQ¶
- IRQ_RX: int¶
À passer à l’argument
triggerdeirq()pour déclencher le gestionnaire chaque fois que le contrôleur CAN a reçu un message complet dans la FIFO RX. À l’intérieur du gestionnaire, lisez le message avecrecv().
- IRQ_TX: int¶
À passer à l’argument
triggerdeirq()pour déclencher le gestionnaire chaque fois que le contrôleur CAN termine une tentative de transmission (réussite ou échec). À l’intérieur du gestionnaire, utilisez les bits supplémentaires ci-dessous pour déterminer quelle boîte aux lettres s’est terminée et si elle a échoué – voir Drapeaux d’IRQ.
- IRQ_STATE: int¶
À passer à l’argument
triggerdeirq()pour déclencher le gestionnaire chaque fois que le contrôleur passe d’une valeurSTATE_*à une autre (active / warning / passive / bus-off). Utilisezstate()à l’intérieur du gestionnaire pour lire le nouvel état.
- IRQ_TX_FAILED: int¶
Drapeau d’état qui peut être défini dans
irq().flags()lorsqu’un événementIRQ_TXse déclenche. Indique que la tentative de transmission a échoué (généralement parce quecancel_send()a été appelée, ou que le contrôleur est entré dans un état d’erreur).
- IRQ_TX_IDX_SHIFT: int¶
Position du bit du champ d’index de la boîte aux lettres de transmission au sein de la valeur
irq().flags()lors d’un événementIRQ_TX. L’index de la boîte aux lettres est extrait par(flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.
- IRQ_TX_IDX_MASK: int¶
Masque de bits du champ d’index de la boîte aux lettres de transmission au sein de la valeur
irq().flags()lors d’un événementIRQ_TX. L’index extrait correspond à l’entier renvoyé par l’appelsend()correspondant (un int dans la plage0àTX_QUEUE_LEN).
Drapeaux d’IRQ¶
L’appel de CAN.irq() enregistre un gestionnaire d’interruption avec un ou plusieurs des déclencheurs CAN.IRQ_RX, CAN.IRQ_TX et CAN.IRQ_STATE.
La fonction renvoie un objet IRQ, et l’appel de la fonction flags() sur cet objet renvoie un entier indiquant quel(s) événement(s) déclencheur(s) ont déclenché l’interruption. Un gestionnaire d’IRQ CAN doit appeler la fonction flags() de manière répétée jusqu’à ce qu’elle renvoie 0.
Lorsque la fonction flags() retourne avec le bit CAN.IRQ_TX défini, le gestionnaire peut également vérifier les bits de drapeau suivants dans le résultat pour obtenir des informations supplémentaires sur l’événement TX :
Le bit
CAN.IRQ_TX_FAILEDest défini si la transmission a échoué. Habituellement, cela ne se produira que siCAN.cancel_send()a été appelée, bien que cela puisse également se produire si le contrôleur entre dans un état d’erreur.CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFTest une région masquée par bits de la valeur des drapeaux qui contient l’index du tampon de transmission ayant généré l’événement. Ce sera un entier dans la plage0àCAN.TX_QUEUE_LEN(exclu), et correspondra au résultat d’un appel précédent àCAN.send().
Exemple d’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
Si le déclencheur CAN.IRQ_TX est défini, le gestionnaire doit appeler flags() de manière répétée jusqu’à ce qu’elle renvoie 0, comme indiqué dans cet exemple. Sinon, les interruptions CAN pourraient ne pas être correctement réactivées.