11 juillet 2025
Alors, oui, nous avons une piste pour régler nos problèmes de communication, surtout que l’USB nous avait été chaudement recommandé à la coupe.
Mais nous avions un autre souhait pour notre robot, avoir des logs. Mais pas juste une LED qui s’allume en cas de soucis, des vrais logs, des gros fichiers avec plein de données dedans !
Nous voyons que notre code de démonstration supporte la classe "Mass Storage", nous sommes donc sur la bonne voie. Mais que se passe-t-il lorsque nous connectons une clé USB ? Eh bien, pas grand-chose :
A device with address 1 is mounted
A device with address 1 is unmounted
Alors comment aller plus loin ?
La bibliothèque TinyUSB propose une liste de fonctions pour gérer les périphériques "Mass Storage", accessible dans le fichier msc_host.h. Mais en observant ces fonctions, il n’y a rien qui ressemble à ouvrir ou fermer un fichier.
Les fonctions USB vont permettre de lire ou d’écrire une plage d’octet sur le périphérique, comme si nous accédions à une mémoire — ce qui est le cas. C’est très bien pour écrire une donnée brute, mais pour créer des fichiers qui seront lisibles sur un ordinateur, il manque toute une couche logicielle. Ces fonctions USB sont inspirées du protocole SCSI dont nous avons la liste compréhensible des commandes. Et rien là-dedans ne permet d’ouvrir, lire ou écrire des fichiers. Il s’agit plutôt de fonctions pour copier des morceaux de mémoire.
Pour gérer des fichiers, il faut un système de fichier. Un système de fichier est une organisation de la mémoire qui contient :
Sur microcontrôleur, il n’y a pas beaucoup de systèmes de fichier qui seraient à la fois simples et reconnus par un ordinateur. Le principal candidat est FAT/exFAT. Il s’agit en réalité d’une famille de système de fichiers (FAT12, FAT16, FAT32, exFAT). FAT12, le plus ancien date de 1980 et était utilisé sous QDOS, l’ancêtre de MS-DOS tandis que exFAT est encore couramment utilisé sur les cartes SD. Ces systèmes de fichier regroupent la mémoire par blocs pour faciliter sa gestion.
Si nous parlons d’une famille de système de fichier, c’est qu’au lieu d’implémenter la spécification, nous utilisons une bibliothèque qui gère toute cette famille. Cette bibliothèque, c’est FsFAT !
L’interface en TinyUSB et FsFAT se résume à quelques fonctions. Chacune de ces fonctions prend en argument le numéro du "disque" sur lequel effectuer les opérations.
Le code à étudier est certainement l’explorateur de fichier fourni dans les exemples de TinyUSB.
C’est un détail, mais FsFAT demande une fonction qui renvoie la date actuelle. Si vous n’avez pas d’horloge à l’heure sur votre microcontrôleur, Vous pouvez renvoyer n’importe quelle date, mais c’est cette date qui apparaîtra comme date de création ou de modification du fichier.
Côté architecture logicielle, nous avons "juste" rajouté la couche FsFAT à notre projet précédent :
Nous étions un peu là pour ça, non ?
Pour écrire dans un fichier, la procédure est la suivante :
Rien de sorcier, mais il y a une petite subtilité. Les chemins sont sous cette forme :
[disque#:][/]répertoire/fichier
Les crochets [...] indiquent des éléments facultatifs. Si vous n’indiquez pas de disque, FsFAT supposera que vous cherchez à écrire sur le disque 0. Dans notre cas, ceci nous a joué un tour. Si nous connections la clé USB directement sur le Raspberry Pi Pico, elle obtenait l’adresse 1. Nous avions codé en dur l’adresse du disque dans nos fonctions disk_*. Mais en ajoutant un hub, l’adresse de la clé passait à 2 et plus rien ne marchait. C’est embêtant au début, mais très flexible par la suite. Vous pouvez gérer plusieurs clés USB par exemple. Imaginez en garder une en permanence sur le robot et une qui reçoit automatiquement les derniers logs lorsque vous la branchée.
Pour plus de détails, lisez la bonne documentation.
Les performances ? Pas terribles, nous ne dépassons pas les 64 ko/s, ce qui est aussi la limite trouvée par rppicomidi dans son projet pico-usb-host-msc-demo... D’après le projet de rppicomidi, c’est la conception de l’USB sur le Raspberry Pi Pico qui n’est pas faite pour obtenir de bonnes performances en mode "hôte". De notre côté, nous n’avons pas les compétences pour nous prononcer sur la cause, mais nous réalisons le même constat...
Alors 64 ko/s, ça paraîtrait OK pour du log, mais ça veut dire que nous utilisons un cœur complet pour écrire sur la clé, et que notre ressource USB ne fait qu’écrire les logs, Or nous comptons sur l’USB pour la communication intra-robot, pas question de partir sur une solution qui semble déjà montrer ses limites...
Vous trouverez notre code en ligne ici !