Les interfaces de communication de la Raspberry Pi

Liaison série

Généralités

Selon la version de la Raspberry Pi, on peut disposer d’un nombre différent de liaisons série :

  • 2 pour les Raspberry Pi Zero, 1, 2 and 3

  • 6 pour les Raspberry Pi 4 et 400

Au niveau du microcontrôleur, une liaison série est gérée à partir d’un contrôleur appelé UART pour Universal Asynchronous Receiver Transmitter. Les Raspberry Pis disposent donc de 2 ou 6 UARTs selon leur version.

Parmi ces UARTs, il y en a un qui est moins performant que les autres : on l’appelle le “mini-UART”. Les autres sont appelés “PL011”.

Le “mini-UART” présente les limitations suivantes :

  • Buffer de réception plus petit

  • Vitesse liée à l’horloge du microcontrôleur et non à une horloge dédiée (→ moins de choix possibles, fluctuations possibles)

  • Pas de détection des conditions de “break

  • Pas de détection des erreurs de trame

  • Pas de gestion de la parité

  • Pas de mise à disposition d’une interruption matérielle suite à l’expiration d’un délai d’attente en réception

  • Pas de gestion des signaux DCD, DSR, DTR ou RI

Au lycée, nous disposons essentiellement de Raspberry Pis 3.

Sur ce modèle de Raspberry Pi — qui dispose donc d'1 “mini-UART” et d'1 “PL011” — le “PL011” est assigné par défaut à la fonction Bluetooth. Ainsi, la liaison série UART — appelée parfois aussi “liaison série TTL” — présente sur les broches 8 et 10 du connecteur GPIOs est gérée par le “mini-UART”.

Cependant, il est possible, par configuration, d’inverser les UARTs en charge du Bluetooth et de la liaison UART accessible sur le connecteur GPIOs.

Quel que soit l’UART choisi pour piloter la liaison série présente sur le connecteur GPIOs, celui-ci est désigné comme l’UART primaire. L’UART utilisé pour dialoguer avec le contrôleur Bluetooth est, quant à lui, désigné comme l’UART secondaire.

Au niveau de l’OS, la liaison série gérée par le “mini_UART” est représentée au niveau du système de fichiers par le device /dev/ttyS0. Celle gérée par le “PL011” par le device /dev/ttyAMA0.

pi@raspberrypi:~ $ ls  -l /dev/tty[AS]* /dev/serial*
lrwxrwxrwx 1 root root          5 Jan 28 12:27 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root          7 Jan 28 12:27 /dev/serial1 -> ttyAMA0
crw-rw---- 1 root dialout 204, 64 Jan 28 12:27 /dev/ttyAMA0
crw-rw---- 1 root dialout   4, 64 Jan 28 12:27 /dev/ttyS0

Les liens symboliques /dev/serial0 et /dev/serial1 représentent respectivement les UARTs primaire et secondaire.

Le screenshot précédent indique que, dans cet exemple de configuration, l’UART primaire correspond au “mini-UART” et le secondaire au “PL011”.

Le device /dev/ttyS0 n’apparaît que si la liaison série matérielle a été activée avec raspi-config (→ désactivation du serial login shell en faveur du serial port hardware)

Voir Configuring UARTs ou Configuration  Configuring UARTs link pour le document qui a servi de référence pour ces généralités.

Assigner le “PL011” à l’UART primaire

  • En désactivant le Bluetooth :

    1. Désactiver la console Linux puis activer la liaison série matérielle depuis l’option “Interface  Serial” de raspi-config

    2. Désactiver le Bluetooth en ajoutant dtoverlay=disable-bt au fichier /boot/config.txt

    3. Désactiver le service système d’initialisation du modem Bluetooth en exécutant sudo systemctl disable hciuart

    4. Rebooter le système

  • En laissant le Bluetooth activé :

    Cette procédure tirée de UARTs and Device Tree link n’a pas été testée.

    Elle doit peut-être adaptée avec les informations sur l’overlay miniuart-bt présentes dans ce document.

    1. Désactiver la console Linux puis activer la liaison série matérielle depuis l’option “Interface  Serial” de raspi-config

    2. Assigner le “mini-UART” à la communication avec le contrôleur Bluetooth et le “PL011” à la liaison série du connecteur GPIOs en ajoutant dtoverlay=miniuart-bt au fichier /boot/config.txt

    3. Définir une valeur fixe pour la fréquence du microcontrôleur en ajoutant l’option force_turbo=1 or core_freq=250 au fichier `/boot/config.txt.

Afficher la configuration actuelle d’une liaison série

Exécuter la commande :

stty -F /dev/<serial-device> -a (1)
1 <serial-device> à remplacer par la liaison série désirée
Exemple : demande de la configuration de la liaison série associée à l’UART primaire
pi@raspberrypi:~ $ stty -F /dev/serial0 -a
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

Modifier la configuration d’une liaison série

  • avec stty :

    pi@raspberrypi:~ $ stty -F /dev/serial0 115200 parenb -parodd -cstopb (1)
    1 configuration de /dev/serial0 avec une vitesse de 115200bauds (→ 115200) un contrôle de parité (→ parenb) paire (→`-parodd`) et 1 bit de stop (→ -cstopb)

Afficher l’affectation des broches de la liaison série

Exécuter la commande : raspi-pio get

Exemple :
pi@raspberrypi:~ $ raspi-gpio get
BANK0 (GPIO 0 to 27):
GPIO 0: level=1 fsel=0 func=INPUT
GPIO 1: level=1 fsel=0 func=INPUT
GPIO 2: level=1 fsel=0 func=INPUT
GPIO 3: level=1 fsel=0 func=INPUT
GPIO 4: level=1 fsel=0 func=INPUT
GPIO 5: level=1 fsel=0 func=INPUT
GPIO 6: level=1 fsel=0 func=INPUT
GPIO 7: level=1 fsel=0 func=INPUT
GPIO 8: level=1 fsel=0 func=INPUT
GPIO 9: level=0 fsel=0 func=INPUT
GPIO 10: level=0 fsel=0 func=INPUT
GPIO 11: level=0 fsel=0 func=INPUT
GPIO 12: level=0 fsel=0 func=INPUT
GPIO 13: level=0 fsel=0 func=INPUT
GPIO 14: level=1 fsel=4 alt=0 func=TXD0 (1)
GPIO 15: level=1 fsel=4 alt=0 func=RXD0 (1)
GPIO 16: level=0 fsel=0 func=INPUT
[...]
1 GPIO 14 (broche 8 du connecteur GPIOs) est utilisée pour la transmission du “PL011” (UART0 ⇒ TXD0) et GPIO 15 (broche 10 du connecteur GPIOs) pour la réception

Créer une paire de ports série virtuels

Il est parfois utile en phase de développement de pouvoir simuler par logiciel une paire de ports série virtuels rebouclés l’un sur l’autre de façon à tester les échanges par liaison série entre 2 applications s’exécutant sur la même machine.

virtual nullmodem

Dans l’illustration ci-dessous on peut alors imaginer que “APP1” est un programme Qt en cours de développement et “APP2” un émulateur de terminal série comme CuteCom.

On peut alors visualiser sur CuteCom les trames série envoyées par le programme Qt et/ou, inversement, constater comment réagit le programme Qt suite à la réception de trames envoyées par CuteCom.

Pour mettre en place cette fonctionnalité, on utilise sur Linux le programme socat :

  1. Installation du paquet socat :

    sudo apt-get install socat
  2. Création d’une paire de ports série virtuels

    sudo socat -d -d pty,raw,echo=0,mode=666,link=/dev/ttySocat0,group-late=dialout pty,raw,echo=0,mode=666,link=/dev/ttySocat1,group-late=dialout (1)
    1 Création de la paire de ports série virtuels rebouclés l’un sur l’autre et qui seront identifiés par /dev/ttySocat0 et /dev/ttySocat1
  3. Vérification du bon fonctionnement

    Dans un terminal :

    pi@raspberrypi:~ $ cat < /dev/ttySocat1 (1)
    1 On affiche sur l’écran ce que l’on reçoit depuis /dev/ttySocat1. Rien ne s’affiche pour l’instant car rien n’a encore été reçu.

    Dans un 2ème terminal :

    pi@raspberrypi:~ $ echo hello > /dev/ttySocat0 (1)
    1 On envoie “hello” sur /dev/ttySocat0

    On doit alors obtenir sur le 1er terminal :

    pi@raspberrypi:~ $ cat < /dev/ttySocat1
    hello (1)
    1 Le 1er terminal affiche “hello” puisque /dev/ttySocat0 est rebouclé sur /dev/ttySocat1

Sur Windows cette fonctionnalité de rebouclage de ports série virtuels est également disponible via le logiciel Com0Com link

Exemple de mise en œuvre avec un programme Qt et CuteCom

Comme CuteCom ne sait pas détecter automatiquement un port série virtuel, il faut éditer son fichier de configuration pour qu’il le prenne en compte.

  1. Ouvrir le fichier ~\.config\CuteCom\CuteCom5.conf

  2. Ajouter la ligne suivante dans la section appelée [sessions]:

    1\Device=<nom-port-serie-virtuel> (1)
    1 remplacer <nom-port-serie-virtuel> par le nom utilisé dans la commande socat (Ex. /dev/ttySocat1)

Ressources

🞄  🞄  🞄