On ne l’avait pas vue venir, celle-là ! La Fondation nous l’a glissée en loucedé sur le Raspberry Pi 3 : pas de page d’information sur leur blog, juste des réponses dans les forums…
L’adjonction du Bluetooth au Raspberry Pi 3 a amené les concepteurs de la framboise à détourner l’UART du BCM2837 précédemment relié aux bornes 8 et 10 du GPIO vers le Bluetooth.
Le port Série du Raspberry Pi 3
Les UART du Raspberry Pi
Un UART, pour Universal Asynchronous Receiver Transmitter, est un émetteur-récepteur asynchrone universel. En langage courant, c’est le composant utilisé pour faire la liaison entre l’ordinateur et le port série . L’ordinateur envoie les données en parallèle (autant de fils que de bits de données). Il faut donc transformer ces données pour les faire passer à travers une liaison série qui utilise un seul fil pour faire passer tous les bits de données. (Wikipedia)
UART0 = PL011
Le SoC du Raspberry Pi est toujours basé sur le même hardware, le BCM2835. Seul le microprocesseur a évolué. Le BCM2835 comporte deux UART, pour les liaisons série. Le premier, le PL011 est un « vrai » UART :
C’est à dire qu’il est autonome, doté de son propre générateur de Baud Rate, et de tous les circuits nécessaires à son fonctionnement.
UART1 = « mini » UART
Le second UART est quand à lui un « mini » UART :
Il ne comporte pas de générateur de Baud Rate et utilise la fréquence du cœur du CPU. Ça pourrait être bien, sauf que la fréquence du CPU est susceptible de varier en fonction de sa charge
Il ne gère pas non plus la parité.
C’était mieux avant ! Le port série du Raspberry Pi 2
Sur les premières générations de Raspberry Pi (model 1 B, B+ et 2) l’UART0 PL011 est utilisé et il est connecté aux broches 8 et 10 du GPIO. Les messages du système en cours de démarrage sont envoyés par défaut sur ce port. Il suffit de brancher un terminal pour les lire.
Cette entrée série peut également être connectée à un terminal qui servira alors à se connecter au Raspberry Pi après s’être logué.
Enfin, cette E/S série est utilisée dans des applications industrielles ou domotiques, pour lire des données GPS, relier deux Raspberry Pi entre eux, un Raspberry Pi avec un Arduino etc.
Le port série du Raspberry Pi 3 : la cata !
Le SoC du Raspberry Pi 3 est un BCM2837 SoC. C’est un BCM2836 avec un CPU quad-core ARMv8 qui peut fonctionner en 32 ou en 64 bits. Le mode 32 bits est actuellement sélectionné par défaut la firmware du VideoCore sur le Raspberry Pi 3.
Un autre changement intervient dans l’utilisation des UART. Sur tous les Raspberry Pi précédents, le PL011 était le seul UART en service. Le Raspberry Pi 3 accueille un module Bluetooth qui utilise un UART pour se connecter au SoC. Par défaut, c’est le PL011 qui est utilisé pour le Bluetooth car il a une pile FIFO plus importante que celle du « mini » UART.
Le mini UART est donc relié au port GPIO (broches 8 et 10).
Cette modification importante et non documentée a « cassé » des applications qui tournaient bien avec le port série du Raspberry Pi 2 et qui refusaient de fonctionner sur le Pi3. De nombreux articles de blogs qui fonctionnaient avec les générations précédentes de Raspberry Pi sont devenus inopérants. Les auteurs ne pensent pas forcément à revenir sur ces anciens articles et il faudra être prudent(e) si vous les utilisez.
Un UART pour mon SIGFOX
Dit comme ça ça peut sembler bizarre, mais je vous explique. La SNOC (Société Nationale des Objets Connectés) située à Saint-Sylvain-d’Anjou a sorti fin janvier une carte de prototypage pour SIGFOX. Cette BRKWS01 distribuée par Yadom, se connecte… sur le port série du Raspberry Pi (ou tout autre port série en 3,3v). Comme je prépare un article sur cette carte j’avais besoin du port série du Raspberry Pi 3.
Voilà, vous avez tout compris.
Pour faire fonctionner dans de bonnes conditions cette carte SIGFOX, je voulais la connecter au port série du GPIO (8 et 10) mais … ça ne fonctionnait pas et du coup bin voilà cet article
Rendre à César…
La première chose à faire c’est un choix. Est-ce que j’ai besoin du Bluetooth ? Ma réponse est non. Ça veut dire que je peux dévalider le Bluetooth et du coup récupérer l’UART « kivabien » pour ma carte SIGFOX.
Vous avez 4 options
- Option 1 : Utiliser l’UART (le vrai !) en perdant la fonction Bluetooth. Il faut permuter les E/S des deux UART. Pour cela, ajoutez à /boot/config.txt : dtoverlay = pi3-disable-bt
Puis supprimer :
console=serial0,115200 dans cmdline.txt - Option 2 : Faire fonctionner l’interface série et le Bluetooth correctement, mais la vitesse d’horloge du processeur sera fixée (à une vitesse faible [250MHz] ou à une vitesse élevée [500MHz?]). Ajoutez enable_uart = 1 à /boot/config.txt. Cela affectera les performances du processeur car ça contrôle la vitesse du cache L2, et on notera également une réduction de la qualité audio analogique (voyez ici et là).
Si vous optez pour la vitesse d’horloge élevée (il faudra vraiment prévoir un ventilateur et un radiateur) pour garder la performance du processeur et la qualité audio, ajoutez également force_turbo = 1 à /boot/config.txt. - Option 3 : Avoir une interface série « pourrie » sur le GPIO (vitesse variable) mais avoir un Bluetooth correcte : Ne rien faire. Ce sont les paramètres par défauts
- Option 4 : Faire fonctionner correctement l’interface série (UART), avec un Bluetooth qui fonctionne lentement. Permutez les UART : ajoutez dtoverlay = pi3-miniuart-bt au fichier /boot/config.txt, puis définissez la fréquence à une valeur fixe (faible) en ajoutant, toujours à /boot/config.txt : core_freq = 250. Cela affectera les performances du processeur. Si vous préférez conserver des performances plus élevées n’ajoutez pas la ligne core_freq = 250 mais plutôt la ligne force_turbo = 1 mais cela nécessite d’utiliser un ventilateur et un radiateur.
J’ai choisi la première.
Les ports série
Si tout va bien en faisant un ls -l /dev vous devriez retrouver un port serial0 qui pointe vers ttyAMA0.
Les tests
Bien entendu pas question de connecter quoi que ce soit derrière le port série sans savoir d’abord si ça fonctionne. Vous me voyez venir ? Alors c’est une question dans les commentaires à la fin de l’article sur la carte SIGFOX (j’imagine, bien sûr : ça ne se produira pas ! ) :
« Bonjour, j’ai suivi le tuto mais ça ne marche pas ! »
Réponse : « Est-ce que vous avez testé le port série avant de connecter la carte SIGFOX ? »
« Non, mais j’ai bien suivi le tuto !! ça doit marcher !!«
Eh bien non, cher(e) lecteur(trice) ! Point ne suffit de suivre à la lettre un tuto ! Tu te dois de vérifier à chaque étape que le résultat attendu est bien au rendez vous…
Certes me diras tu, mais comment qu’je fais moi ? pour tester le port série ?
Fastoche :
Tu vas relier les ports GPIO 8 et 10 correspondant à TXD et RxD (Données émises => Données reçues).
Lorsque tu vas envoyer des données sur le port série TxD, elles vont revenir par le port RxD… Hop là retour à l’envoyeur (ça s’appelle un loopback) ! Et le programme utilisé pour envoyer les données va les recevoir et les afficher
Suite à une remarque de msg (voir les commentaires) reliez les bornes 8 et 10 avec une résistance pour éviter la destruction des ports (ou pire) en cas d’erreur. 680 Ω ou 560 Ω fera l’affaire.
Bon avant de sortir la grosse artillerie on va dégainer un petit bout de Python, déjà pour se rendre compte de ce qui se passe.
Un programme en Python
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Test du port série import serial test_string = "Je teste le port série 1 2 3 4 5" port_list = ["/dev/ttyAMA0", "/dev/ttyAMA0", "/dev/ttyS0", "/dev/ttyS0",] for port in port_list: try: serialPort = serial.Serial(port, 9600, timeout = 2) print "Port Série ", port, " ouvert pour le test :" bytes_sent = serialPort.write(test_string) print "Envoyé ", bytes_sent, " octets" loopback = serialPort.read(bytes_sent) if loopback == test_string: print "Reçu ", len(loopback), "octets identiques. Le port", port, "fonctionne bien ! \n" else: print "Reçu des données incorrectes : ", loopback, " sur le port série ", port, " bouclé \n" serialPort.close() except IOError: print "Erreur sur ", port, "\n"
Ce programme (adapté d’un prog du forum raspberrypi.org) va envoyer des données en sortie sur le port série, puis les récupérer sur l’entrée. Ici le test qui nous intéresse est celui de /dev/ttyAMA0. Vous pouvez mettre les ports que vous voulez tester dans la liste.
Lancez le programme de test et vous devriez obtenir :
pi@raspberrypi:~ $ python tesTxRx.py Port Série /dev/ttyAMA0 ouvert pour le test : Envoyé 33 octets Reçu 33 octets identiques. Le port /dev/ttyAMA0 fonctionne bien ! Port Série /dev/ttyAMA0 ouvert pour le test : Envoyé 33 octets Reçu 33 octets identiques. Le port /dev/ttyAMA0 fonctionne bien ! Erreur sur /dev/ttyS0 Erreur sur /dev/ttyS0
Si vous n’avez pas la confirmation que le port ttyAMA0 fonctionne correctement, inutile de continuer. Il faut d’abord faire fonctionner ce port pour pouvoir l’utiliser.
Minicom un mini émulateur de terminal sous Linux
Pour utiliser Minicom, commencez par l’installer sur votre Raspberry Pi.
pi@raspberrypi:~ $ sudo apt-get install minicom
Configurez le :
Pour adapter le fonctionnement à la carte SIGFOX qui rejoindra ce Raspberry Pi, il faut régler les paramètres du port série à 9600 bits par seconde, 8 bits de données, pas de parité et un bit de stop. Ceci se traduit par 9600 8N1.
Choisissez également le port série pour qu’il corresponde au port raccordé au GPIO : /dev/ttyAMA0.
Il ne reste plus qu’à tester : tapez… n’importe quoi sur le clavier et ça doit apparaître sur l’écran. Si rien n’apparait… C’est que le port série ne fonctionne pas ou que quelque chose est mal configuré.
Conclusion
Ce n’est pas la première fois que la Fondation Raspberry Pi nous fait le coup. On avait déjà connu ça avec l’introduction de systemd, peu documentée. Les habitués de Linux s’en sortaient tant bien que mal, mais cela avais mis de nombreux débutants en mauvaise posture. Pas ou peu d’infos, pas de doc… Système D ( ) obligatoire.
Eh bien là c’est rebelotte. On modifie les ports série, pas ou peu d’infos… Des surprises à la clé !
Eh les gars pensez aux utilisateurs… Le Raspberry Pi est fait pour l’éducation (aussi) et ceux/celles qui le mettent en œuvre ne sont pas forcément des vieux linuxiens barbus ! Alors s’il vous plait un peu d’infos et de doc, juste un peu
Sources
- https://www.element14.com/community/thread/55627/l/how-to-use-serial-port-in-raspberry-pi-3?displayFullThread=true
- https://www.element14.com/community/message/195438/l/re-raspberry-pi-3-und-enocean-pi-kompatibilit%C3%A4tsproblem#195438
- https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=153514
Cet article Le port série du Raspberry Pi 3 : pas simple ! a été publié en premier sur Framboise 314, le Raspberry Pi à la sauce française.....