Un de mes clients a eu le besoin de programmer en série des clavier pour le secteur automobile (plus des engins de chantier). Par programmer, j'entends configurer. Il s'avère que Linux possède tout ce qu'il faut pour effectuer cette opération.
Le clavier utilisé est de marque Grayhill (3K Series) et semble-t-il est monté dans des véhicules de type chantier, bus ou tracteurs (je le déduis des normes supportées). Huit boutons, avec des indicateurs lumineux.
À l'arrière, un connecteur industriel fournissant l'alimentation et les deux broches du bus CAN.
Le but de l'opération est de modifier le paramètre backlight du clavier. Commençons par monter le banc de programmation, en connaissant le brochage du connecteur :
Nous allons utiliser un adaptateur de marquee PEAK SYSTEM (CAN USB) qui utilise un driver natif Linux SocketCAN.
Le gros avantage : aucun logiciel à installer, c'est du standard ! Et ça c'est un atout important lorsque l'on a affaire à plusieurs inconnues (ici : comment changer le backlight).
On installe les packages nécessaires sous Ubuntu :
sudo apt-get install can-utils
Un peut de câblage permet d'avoir une interface robuste et facilement utilisable malgré un connecteur tellement bien fixé qu'il en est difficile à retirer (il faut alors arranger un peu le connecteur mâle pour retirer les éléments les plus pénibles comme la bague en caoutchouc et la lamelle anti-retour qu'il faut casser).
Le clavier utilise la norme SAE-J1939 au dessus du bus CAN. N'étant pas trop familiarisé avec ce protocole, il faut se documenter un peu au moins pour comprendre vaguement comment c'est structuré.
Voici la structure d'un message dans cette norme, illustration tirée du site
La norme spécifie notamment le codage de l'identifiant CAN ID dont tous les éléments sur le bus doivent respecter. La taille de ce champs fait 29 bits, c'est la version étendue du standard du bus CAN due au grand nombre de capteurs et d'actionneurs dans ce genre de véhicule. La taille est de 11 bits dans les véhicules civils.
La notion de PGN (Parameter Group Number) offre un identifiant unique dans le véhicule permettant de déterminer rapidement l'appareil et la sous catégorie.
La datasheet nous donne les informations suivantes :
Pour certaines commandes, le champs PS es utilisé pour l'adresse de destination. Il existe deux familles de commandes :
Voici par exemple deux types de trames décomposées à l'aide d'un convertisseur en ligne :
Ok, nous avons quelques informations minimales, nous allons maintenant connecter le
clavier à l'ordinateur et jouer avec les commandes.
SocketCAN est la couche standardisée dans le noyau Linux permettant de communiquer avec des périphériques CAN avec les mêmes outils que les socket réseau. De plus, cette uniformisation permet d'avoir des périphériques "plug and play" comme notre adaptateur USB.
Voici quelques commandes utiles :
Lister les interfaces :
ip link show
On obtient une entrée comme ceci :
19: can0: mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can
Si le lien est DOWN, il faut d'abord le configurer à la bonne vitesse (regarder la datasheet) :
sudo ip link set can0 type can bitrate 250000
Puis le démarrer (UP)
sudo ip link set up can0
Bien vérifier que le bus est UP !! Sinon les commandes ne passent pas dans pour autant avoir un retour négatif ! Je me suis fait avoir plusieurs fois.
can0: mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can
Afficher les messages qui passent sur le bus :
candump can0
Exemple de LOG reçu avec le clavier Grayhill de branché (un reçoit plusieurs trames par secondes en temps réel, par défaut la datasheet indique une fréquence de 100ms).
can0 18FF02A1 [8] 00 00 FF FF FF FF FF FF
can0 18FF02A1 [8] 00 00 FF FF FF FF FF FF
can0 18FF02A1 [8] 00 00 FF FF FF FF FF FF
La deuxième colonne est la valeur brute du CAN ID, suivi par les 8 octets de données.
Ici l'adresse de source est 0xA1 et le PGN FF02 ce qui correspond bien à l'envoi du statut des boutons. 0x18 ici place le champs Priority en binaire à 0b110 (bits 27 et 28 à 1) ce qui donne bien une priorité de 6.
Maintenant que nous sommes légèrement familiarisés avec ce protocole, essayons de réaliser l'opération demandée, à savoir modifier le rétro-éclairage.
Voyons ce que nous dit la datasheet. Tout d'abord, le premier octet donne le numéro de la commande puis suivent les 7 octets de données. Voici la commande pour changer le paramétrage du rétro-éclairage (il y a une erreur dans le manuel, les derniers octets non utilisés sont au nombre de 5, pas 6).
Pour envoyer une commande, il faut écrire, en hexadécimal, le CANID puis les octets de données, les deux étant séparés par le caractère dièse '#'.
Rétro éclairage quasiment à fond :
cansend can0 18EFA180#80FFF0FFFFFFFFFF
Rétro éclairage éteint :
cansend can0 18EFA180#80FF00FFFFFFFFFF
Voici le script final qui s'assure que la liaison est toujours UP (ça se déconnecte des fois, aucune idée pourquoi, est-ce que le device se réinitialise suite à l'envoi de la commande ?).
sudo ip link set down can0 && sudo ip link set up can0 && ip link show && cansend can0 18EFA180#80FF00FFFFFFFFFF
Et voilà, notre banc de test est opérationnel et nous permet de configurer des claviers en série de façon simple, dans développer aucun programme particulier. Linux est vraiment une boîte à outil fantastique.