Le bus CAN

(Le bus CAN : dernière mise à jour par Benjamin le 9 avril 2024)

Le bus de données CAN (Controller Area Network) est un bus série bidirectionnel, asynchrone (pas de fil d’horloge, les différents éléments connectés doivent tous être configurés avec le même débit) et Half Duplex (on parle chacun à son tour, à condition que le bus soit libre).

Le but de cette page n’est pas de faire un exposé théorique exhaustif au sujet du CAN, mais d’expliquer quelques notions élémentaires pour aider le lecteur (constructeur amateur d’aéronef, pilote ou hobbyiste) à réaliser une implémentation simple dans le cadre d’un projet avionique personnel.

Le bus CAN met en application une approche connue sous le nom de multiplexage : un même câble (le bus) relie entre eux plusieurs équipements ou « nœuds » (organes de commande, capteurs… etc.) qui communiquent donc à tour de rôle. La couche physique du CAN est constituée du bus lui-même, constitué de 2 fils qui véhiculent les données et de tous les contrôleurs (il y en a un par nœud, voir plus bas ce qu’est un contrôleur CAN).

Cette technique élimine le besoin de câbler des lignes dédiées pour chaque information à faire transiter, comme c’est le cas dans une connexion de type point-à-point, par exemple UART ou RS232.

Le bus

Le bus CAN est constitué d’une paire torsadée (blindée ou non) terminée à chaque extrémité par une résistance de 120 ohms, comme ci-dessous (fig. 1) :

Figure 1 : Schéma d’un bus CAN avec ses deux résistances de terminaison de 120 ohms

Chaque nœud peut être connecté au bus par l’intermédiaire d’une paire torsadée (blindée ou non) (fig. 2). La longueur de cette connexion doit être la plus courte possible, au maximum 30 cm. Le bus lui-même peut s’étendre linéairement sur plusieurs dizaines de mètres, voire plus. La longueur diminue cependant le débit maximum du bus. Le bus CAN a une topologie linéaire. Une topologie en étoile est à proscrire.

Figure 2 : Schéma d’un bus CAN avec 3 nœuds.

Si la distance d’un nœud au bus doit dépasser 30 cm, il est alors préférable d’adopter une configuration comme celle-ci (fig. 3).

Figure 3 : Il est préférable de dévier le bus vers un nœud plutôt que d’allonger exagérément une connexion en T.

La déconnexion d’un nœud ne doit jamais interrompre la continuité du bus qui doit pouvoir continuer à fonctionner normalement.

L’information est véhiculée par le bus CAN sous la forme d’une tension différentielle entre les deux fils de la paire, nommés CAN_H et CAN_L. Cela assure une excellente immunité face aux perturbations électromagnétiques : comme les perturbations touchent les deux fils, la différence de potentiel entre les fils reste la même.

Les contrôleurs et leurs rôles

Chaque nœud d’un bus CAN comporte, en sus des capteurs ou autres actionneurs qui lui sont propres, un microcontrôleur, un contrôleur CAN et un transceiver CAN (voir plus loin la figure 5). Les microcontrôleurs 32 bits récents comme ceux qui équipent les cartes Teensy intègrent un ou plusieurs controleurs CAN. Il faut néanmoins leur adjoindre un transceiver pour pouvoir les connecter à un bus CAN (voir plus bas). Le microcontrôleur ATmega328P des cartes Arduino 8 bits comme la carte UNO Rev3 n’intègre pas de contrôleur CAN, il faut donc lui adjoindre un contrôleur externe ET un transceiver.

Tous les nœuds connectés au bus ont les mêmes droits, il n’y a ni maître ni esclave. Le protocole régissant les échanges de messages est codé « en dur » dans le contrôleur. Il est basé sur le principe de diffusion générale : lors des transmissions, aucune station n’est adressée en particulier.

Le contenu de chaque message émis sur le bus est explicité par un identifiant, le message est reçu par tous les «abonnés». Grâce à cet identifiant, les nœuds, qui sont en permanence à l’écoute du réseau, reconnaissent et traitent les messages qui les concernent, et ignorent simplement les autres. Le bus CAN est donc un bus réseau.

L’identifiant d’un message n’est pas une adresse de destination ni de provenance, mais plutôt une indication (convenue par le programmeur dans la couche logicielle, au moment de la programmation des nœuds) sur la nature de l’information contenue dans le message.

Pour éviter la « cacophonie » un système d’arbitrage est indispensable. Afin d’être traitées en temps réel, les informations doivent non seulement être transmises rapidement (ce qui suppose une voie physique autorisant un fort débit, jusqu’à 1 Mbit/s), mais encore, l’assignation du bus à un nœud prioritaire doit être immédiate, si plusieurs stations souhaitent transmettre simultanément des messages.

L’urgence des informations échangées sur le bus peut en effet être très diverse : une valeur variant rapidement, comme l’état d’un capteur ou l’asservissement d’un moteur, doit être transmise plus fréquemment et avec un retard moindre que d’autres valeurs comme la température du moteur, qui évolue lentement.

Sur un réseau CAN, l’identifiant de chaque message, qui est une séquence de 11 bits (format standard) ou 29 bits (format étendu), détermine sa priorité. Les priorités sont donc attribuées lors de la conception du programme informatique (la couche logicielle), au moyen de ces valeurs binaires. Plus la valeur binaire de l’identifiant est faible, plus grande est la priorité du message.

Les nœuds qui tentent d’émettre simultanément sur le bus, comparent l’identifiant de leur message avec celui des messages compétiteurs. Les messages de priorité moins élevée perdent la compétition face à celui qui a la priorité la plus élevé. Quand un nœud perd la compétition, il cesse d’émettre. Il devient alors automatiquement un simple récepteur du message, et il ne tente à nouveau d’émettre son message que lorsque le bus se libère.

Cette gestion des priorités est totalement transparente pour le programmeur qui n’a pas à s’en préoccuper, sauf au moment du choix des identifiants. Elle est intégralement assurée par le protocole contenu dans le contrôleur CAN de chaque nœud, si bien que chaque message est finalement toujours émis, et qu’il n’y a jamais aucune information perdue.

Structure des messages

On ne parle ici que du protocole CAN « classique », limité à des messages de 8 octets de données avec un débit max de 1 Mbit/s. Le CAN FD, plus récent, autorise des messages de 64 octets de données avec un débit max de 2 Mbit/s, mais en dehors de cela, il reprend exactement les mêmes principes.

Le CAN « classique » existe lui-même en 2 versions : CAN 2.0A avec identification sur 11 bits, et CAN 2.0B avec une identification comportant 18 bits supplémentaires, donc sur 29 bits. On parle de format CAN étendu pour cette version 2.0B. La structure des trames est représentée ci-dessous (fig. 4).

Figure 4 : structure des messages CAN 2.

Une trame est composée des champs suivants :

  • Bit SOF (Start Of Trame) : passage de HIGH (état de repos) à LOW
  • Champ Identifiant et Arbitrage (11 ou 29 bits)
  • Bit RTR (Remote Transmission Request) : détermine s’il s’agit d’une trame de données ou d’une trame de demande de message.
  • Bit IDE qui établit la distinction entre format standard (état LOW ou dominant) et format étendu (état HIGH, ou récessif)
  • Champ R, 1 ou 2 bits : réservé pour une utilisation future
  • Champ DLC de 4 bits : nombre d’octets contenus dans la zone de données
  • Champ de données, de longueur comprise entre 0 et 8 octets
  • Champ CRC de 15 bits (Cyclic Redundancy Code). Ces bit sont recalculés à la réception et comparés aux bits reçus. S’il y a une différence, une erreur CRC est déclarée.
  • Champ ACK composé d’un bit à l’état HIGH ainsi qu’un bit séparateur ACK. Le premier bit doit être forcé à l’état LOW par les stations ayant bien reçu cette trame.
  • Champ EOF (End Of Frame) de 7 bits HIGH : permet d’identifier la fin de la trame.

Avec un identifiant sur 11 bits et un message de 8 octets, on arrive donc à une longueur théorique de message de 108 bits. Mais il faut rajouter des bits de « bit stuffing », une technique qui impose au transmetteur d’ajouter automatiquement un bit de valeur opposée lorsqu’il détecte 5 bits consécutifs de même valeur. Ce qui fait que la longueur d’un message peut atteindre presque 130 bits. Il faut en tenir compte pour calculer la charge du bus et déterminer si cette charge est compatible avec le débit de données du bus.

Les contrôleurs CAN qui admettent le format étendu peuvent aussi émettre et recevoir des messages au format standard. Mais si on utilise sur le réseau des contrôleurs ne maitrisant que le format standard, les messages étendus seront mal interprétés.

Les contrôleurs CAN des cartes Teensy utilisées dans le projet AvionicsDuino admettent le format étendu. Compte tenu des besoins modestes du projet, ils sont utilisés avec le format standard, donc avec des identifiants sur 11 bits. Ce qui permet d’utiliser 2048 identifiants différents, un nombre plus que largement suffisant.

La sécurité et la fiabilité

Le protocole CAN intègre donc des mécanismes de détection et de gestion des erreurs. Tous les nœuds du réseau surveillent simultanément le bus, ils détectent immédiatement des différences entre bits reçus et bits émis. Dès qu’une erreur est détectée, la transmission en cours est interrompue par l’émission d’un indicateur d’erreur (« Error Flag »). L’émetteur doit donc recommencer à émettre son message.

Ce système de gestion des erreurs est transparent pour le développeur et l’utilisateur. Le système est capable de gérer automatiquement ses conflits et ses erreurs en émettant des trames d’erreurs pour renseigner l’émetteur du message sur le type d’erreur rencontrée. Une station est même capable de faire la distinction entre des perturbations temporaires et des défauts permanents. Les stations en défaut permanent sont déconnectées automatiquement du réseau. Ainsi, la probabilité qu’une erreur reste non détectée est inférieure à 4,7 x 10-11.

La puissance, la robustesse et l’efficacité du bus CAN sont liées à cette gestion rigoureuse des erreurs et des priorités par le protocole, qui est « hardcoded » dans les contrôleurs CAN de chaque nœud, et à l’immunité vis-à-vis des perturbations électromagnétiques des paires torsadées véhiculant un signal différentiel.

Contrôleurs et transceivers

Toute la complexité du protocole est donc gérée par un circuit électronique spécialisé, le contrôleur (ou driver) CAN. Comme déjà mentionné plus haut, le microcontrôleur 8 bits des cartes Arduino Uno, Nano et Mega ne comporte pas de driver CAN. Si on veut établir une liaison CAN avec ces microcontrôleurs, il faut leur ajouter un module externe, généralement connecté en I2C ou SPI. Ce module est le plus souvent équipé du circuit contrôleur de CAN bus MCP2515, associé à un transceiver très variable selon les modules, MCP2551, MCP2562, TJA1050, SN65HVD1050… etc.

Le rôle du transceiver est de convertir les signaux TTL générés par le contrôleur CAN, en signaux différentiels qui véhiculent l’information sur la paire CAN_H et CAN_L constituant le CAN bus. Les microcontrôleurs 32 bits qui équipent les cartes Teensy 4.x utilisées dans le projet AvionicsDuino comportent plusieurs contrôleurs CAN. Si on souhaite utiliser plusieurs contrôleurs CAN d’un même microcontrôleur, il faut leur adjoindre chacun un transceiver.

Chaque nœud d’un bus CAN comporte donc un microcontrôleur, un contrôleur CAN et un transceiver CAN (fig. 5).

Figure 5 : Schéma complet d’un bus CAN avec les microcontrôleurs, les contrôleurs CAN et les transceivers.
Câbles et connecteurs

La réalisation pratique du bus est peu documentée : quels câbles, quels connecteurs ? Le concepteur dispose d’une certaine liberté, seule la notion de paire torsadée est bien établie et à respecter scrupuleusement. Sauf à décider de respecter des normes beaucoup plus strictes comme celles édictées par CANAerospace (cf. plus bas). Nous utilisons un câble composé d’un fil de masse et de deux paires torsadées blindées individuellement (Ref. Belden 8723, fig. 6). Ce câble léger, robuste et facile à connecter est malheureusement assez onéreux. On peut aussi utiliser du câble Ethernet, beaucoup plus répandu et moins cher, mais moins facile à connecter en raison du très petit diamètre des fils. La paire rouge-noire du câble Belden est utilisée si nécessaire pour l’alimentation des nœuds, la paire blanc-vert constitue le bus CAN. Les nœuds sont tous censés partager une masse commune dans l’avion, éventuellement via le fil noir. Le fil de masse non isolé permet de relier tous les blindages à la masse, mais à une seule extrémité du bus car il ne doit être parcouru par aucun courant. Sa continuité doit être assurée dans les connecteurs des nœuds . Ce fil de masse ne doit pas être utilisé pour un autre usage.

Figure 6 : Câble à double paire torsadée blindée

Le connecteur CAN « standardisé » est un SUB-D9 (fig. 7). Les broches 7 et 2 sont dédiées aux signaux CANH et CANL, les broches 3 et 6 sont dédiées à la masse, une alimentation externe peut si nécessaire être connectée sur la broche 9. Le blindage général du bus peut être connecté à la broche 5 d’un seul nœud, lequel doit assurer la mise à la masse unique de ce blindage.

Figure 7 : Brochage standard d’un connecteur CAN SUB-D9

Il n’existe pas de connecteur en T standard et économique pour relier de façon fiable un câble issu d’un nœud au bus lui-même. On a vu plus haut qu’un tel câble, lorsqu’on ne peut pas l’éviter, doit être le plus court possible. Il est donc nettement préférable de dévier le bus vers un nœud plutôt que d’allonger exagérément une connexion en T (voir la figure 3). Le connecteur SUB-D est alors inséré sur le bus lui-même (fig. 8).

Figure 8 : Connecteur SUB-D inséré sur le câble d’un CAN Bus.

Un capot SUB-D9 à double entrée comme celui de la figure 9 (Ref. MH Connectors MHDU45ZK9-K) offre plus de place pour réaliser les connexions. Les fils des câble pénétrant de chaque côté du capot sont reliés entre eux selon leur couleur et connectés aux broches correspondantes du connecteur SUB-D. Si bien que le bus traverse cette connexion sans être interrompu. On peut ôter le nœud sans perturber le fonctionnement du bus. Et lorsque le nœud est connecté, il est directement sur le bus, ce qui est conforme à l’impératif de connexion courte évoqué plus haut.

Figure 9 : connecteur SUB-D à double entrée
Le logiciel

Le contrôleur CAN gère le protocole, c’est à dire la tâche la plus complexe. Le programmeur va essentiellement avoir pour rôle général de décider des attributions d’ID aux messages du réseau en fonction de leurs priorités. Et de programmer le microcontrôleur de chaque nœud. En particulier pour que le dit nœud réagisse de façon appropriée en fonction du contexte : émission d’un message sur le réseau lorsque ses capteurs lui fournissent de nouvelles informations, écoute et tri des messages du réseau pour répondre de façon adéquate ou entamer une action particulière.

Le programmeur peut s’aider de très nombreuses bibliothèques, plus ou moins génériques, plus ou moins dédiées à certains contrôleurs CAN. Dans le monde Teensy, et plus particulièrement Teensy 4.x, une bibliothèque communément utilisée est Flexcan_t4.

Cette bibliothèque exploite pleinement les nombreuses possibilités offertes par les contrôleurs CAN des microcontrôleurs iMXRT1062 qui équipent les cartes Teensy 4.x. En particulier la gestion des buffers de réception, des mailboxes, et des mécanismes de filtrage qui permettent aux contrôleurs de n’accepter que les messages qui les concernent et d’ignorer les autres sans avoir à les traiter. En pratique, pour nos besoins basiques, seule une petite partie des fonctionnalités de cette bibliothèque est utilisée.

CANaerospace

CANaerospace est un projet open source développé par Stock Flight Systems. Il s’agit de la description d’un ensemble standardisé de protocoles et de formats de données conçus pour assurer une communication hautement fiabilisée entre systèmes informatiques aéronautiques, via le Controller Area Network (CAN).

La lecture de cette présentation est très instructive, le concept d’IMA (Integrated Modular Avionics Concept) y est bien exposé.

Le CAN bus du projet AvionicsDuino

Les besoins sont modestes. Il s’agit seulement de relier quatre, cinq, voire six nœuds qui échangent quelques messages entre eux à des fréquences modérées entre 5 et 20 Hz. Aucune technique de filtrage n’est utilisée. Tous les nœuds lisent l’ID de tous les messages qui transitent sur le bus et ne décodent que les informations qui les concernent. Nous n’avons pas cherché à appliquer les contraintes et préconisations du protocole CANaerospace, disproportionnées par rapport à notre projet.

Première configuration du CAN bus

La figure 10 ci-dessous montre l’architecture du réseau de communication tel qu’il était initialement installé dans l’un des avions participant au projet AvionicsDuino. Il n’y avait que 4 nœuds . En effet, pour des raisons historiques, le module AHRS était encore connecté à l’unité principale de l’EFIS par une connection UART série.

Figure 10 : Architecture du réseau de communication CAN et UART. Première configuration

Le tableau ci-dessous (fig. 11) résume les échanges de données sur le CAN bus de cet avion, dans cette première configuration. La vitesse du bus était fixée à 0,5 Mbit/s. Les éléments en réseau étaient l’unité principale de l’EFIS, le module distant magnétomètre, l’EMS, et le micro-EMS.

Dans cette première configuration, en estimant des longueurs totales de messages de 130 bits (pour 8 octets), 115 bits (pour 6 octets) et 100 bits (pour 4 octets), et compte tenu des fréquences d’envoi, on peut calculer une estimation haute de la charge du bus à 13,825 Kbit/s, soit seulement 2,7% du débit maximum du bus. Donc très loin de la zone de risque de perte de données !

Seconde configuration du CAN bus

La figure 12 ci-dessous montre l’architecture actuelle du CAN bus, dans le même avion que précédemment. Six nœuds y sont connectés, ce qui reste très peu comparé à la centaine de nœuds des voitures modernes, souvent répartis sur plusieurs bus. L’ancienne liaison UART entre l’unité principale de l’EFIS et l’AHRS a été supprimée. Un nouveau Flight Data Recorder (FDR) fait son apparition, son design hardware est terminé, les premiers essais en vol sont très satisfaisants. Il est basé sur un module ESP32 couplé à un lecteur de carte micro-SD. Une mise à jour substantielle de la page dédiée à l’enregistreur de vol a été réalisée, elle sera complétée dès que les derniers developpements du logiciel de cet enregistreur seront achevés.

Figure 12 : Architecture du CAN bus. Deuxième configuration.

Le tableau ci-dessous (fig. 13) résume les échanges de données sur le CAN bus dans cette seconde configuration. La vitesse du bus reste fixée à 0,5 Mbit/s.

Figure 13 : Tableau des ID et des messages CAN du projet AvionicsDuino. Deuxième configuration.

Dans cette deuxième configuration, on voit que le nombre de messages émis sur le bus a beaucoup augmenté, que la plupart ont un contenu de 8 octets, que tous sont destinés au FDR, et beaucoup uniquement au FDR. Le rôle du FDR est bien entendu d’enregistrer tout le trafic du bus CAN. Une estimation haute de la charge du bus est calculée à 23,650 Kbit/s, soit seulement 4,7% de la charge maximale possible compte tenu de la vitesse du bus.

Les logiciels compatibles avec ces deux configurations du CAN bus sont téléchargeables sur GitHub. Il convient évidemment de ne pas les panacher. Le logiciel du nouveau FDR ne sera pas compatible avec les logiciels de la première configuration. Il est important de lire soigneusement les fichiers README sur GitHub, ils détaillent les versions logicielles et leurs compatibilités

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

The maximum upload file size: 5 Mo. You can upload: image, document, text, archive. Drop files here