La sortie de la carte Raspberry Pi Pico de la Fondation Raspberry Pi avec le microcontrôleur RP2040 a fait de grandes vagues ces derniers mois dans la communauté des fabricants. Beaucoup ont démontré comment les deux périphériques de machine d’état d’E / S programmables (PIO) peuvent être utilisés pour créer des générateurs vidéo DVI et d’autres périphériques numériques.

Parallèlement à cette excitation, cela soulève la question de savoir si tout cela provoquera un bouleversement majeur pour ceux d’entre nous qui utilisent STM32, SAM et d’autres MCU basés sur Cortex-M. Le RP2040 serait-il peut-être une option valable pour certains de nos projets? Le RP2040 étant un MCU à double processeur Cortex-M0 +, il semble juste de le mettre en contact avec les offres de l’un des poids lourds actuels de l’espace ARM MCU 32 bits: ST Microelectronics.

Le pipsqueak de la Fondation Raspberry Pi a-t-il réussi à montrer aux ingénieurs de ST comment procéder, ou le premier devrait-il revoir certaines de leurs hypothèses? Et à quel point sera-t-il difficile de porter du code de bas niveau de STM32 vers RP2040?

À quel point cela pourrait-il être difficile?

Carte à base de Raspberry Pi Pico RP2040, connectée à un Raspberry Pi SBC faisant office de dongle SWD.

Pour faire court, après que le RP2040 a attiré mon attention, j’ai pensé qu’il pourrait être intéressant d’essayer de porter mon framework STM32 basé sur C ++ sur ce nouveau MCU. Pas tellement pour les cœurs doubles Cortex-M0 +, cependant, car j’ai des MCU double cœur STM32H7 (M4 et M7) qui traîneront facilement le bourrage d’un RP2040 avec plus d’E / S à revendre. Ce qui m’a le plus intrigué, c’est ce périphérique de machine à états (PIO) du RP2040 qui semblait digne d’être examiné de plus près.

Sur la base de mon expérience avec STM32, j’ai pensé que je pourrais rapidement porter certains fichiers, créer une nouvelle branche d’architecture «RP» dans le projet et partir en course. Cortex-M est Cortex-M, non? La procédure habituelle avec un nouveau MCU basé sur ARM consiste à obtenir les fiches techniques, le manuel de référence et les fichiers du périphérique CMSIS. Après cela, on peut facilement adapter le code de bas niveau pour utiliser la nouvelle disposition de nommage et de registre des périphériques, tandis que les périphériques de niveau central (SysTick, NVIC, etc.) restent les mêmes.

Peut-être naïvement, j’avais passé une commande pour une carte Raspberry Pi Pico avant même de vérifier le support CMSIS, ou de jeter un coup d’œil au manuel de référence. À ma grande surprise, j’ai constaté que le support CMSIS ou même l’interopérabilité avec le reste de l’écosystème Cortex-M n’était pas encore sur le radar. Pourtant, le fichier SVD pour RP2040 MCU est fourni dans le «Pico SDK», qui peut être utilisé pour générer l’en-tête du périphérique à partir de. Grâce aux efforts de Chris Hockuba pour amorcer CMSIS avec le RP2040, j’ai finalement eu une solution de travail ensemble.

Cela pourrait être plus facile

Séquence de démarrage du RP2040 (fiche technique du RP2040, Fig.15).

Avec un projet STM32, quelques éléments sont nécessaires pour qu’un projet bare-metal fonctionne sur un MCU cible. Ceux-ci incluent le code de démarrage qui effectue une configuration de base de l’environnement ainsi que la table vectorielle pour les gestionnaires d’interruptions. Il existe également le script de l’éditeur de liens pour s’assurer que tous les bits se retrouvent au bon décalage de mémoire. Tout cela est assez minime, le MCU au démarrage chargeant l’image du micrologiciel à partir de la ROM Flash à l’adresse par défaut.

Le premier obstacle avec le RP2040 est de comprendre son processus de chargeur de démarrage en chaîne. Tout comme avec les disquettes amorçables d’autrefois, ou un disque dur / SSD dans un PC, la ROM Flash QSPI externe est essentiellement traitée comme un périphérique de démarrage potentiel par le MCU. Le chargeur de démarrage de premier étage est intégré dans le MCU dans la ROM de démarrage, adresse 0x0000 0000, qui au démarrage vérifie l’interface QSPI pour essayer de charger 256 octets à partir de celle-ci. Cela sera vérifié pour une correspondance de hachage CRC32 valide et supposé être le chargeur de démarrage de deuxième étape s’il correspond.

Il y a beaucoup de choses que ce chargeur de démarrage de deuxième étape pourrait faire et certaines sont nécessaires. Qu’il suffise de dire pour l’instant que par rapport à certains clones STM32 célèbres – tels que les GigaDevices Je ne peux pas croire que ce n’est pas un STM32 authentique clones – qui utilisent également des ROM SPI, tout ce processus avec le RP2040 n’est pas aussi intuitif, bien documenté ou transparent qu’il pourrait l’être, avec de nombreuses pierres d’achoppement.

Copie de bons artistes

Il m’a fallu un peu de fouille dans la fiche technique du RP2040 et de demander aux alentours de comprendre comment le gestionnaire d’horloge périphérique de STM32 correspond à l’architecture du système RP2040. Il s’avère que la version du RP2040 s’appelle RESETS et fonctionne fondamentalement en sens inverse: vous devez désactiver la condition de réinitialisation sur un bloc pour activer l’horloge pour cela. Pour activer l’horloge GPIO, vous devez basculer le bit 8 dans RESETS_RESET (PADS_BANK0).

Schéma fonctionnel d’un pad GPIO RP2040.

Cela compris, j’ai regardé la section des périphériques GPIO dans la documentation (section 2.19). Une chose est immédiatement apparente: c’est complètement différent des STM32, AVR, SAM et de la plupart des autres périphériques GPIO que j’ai jamais vus.

Alors que la plupart des puces ont un ou deux registres par fonction et que vous y déplacez des bits pour activer cette fonction pour une broche particulière, le RP2040 a un registre par broche et vous déplacez les bits dans un endroit qui dicte la fonction. C’est un choix unique, et j’ai dû écrire un code personnalisé pour rechercher l’adresse mémoire des registres de contrôle pour chaque broche.

Après avoir traversé tous ces efforts, cela fonctionnera sûrement, non?

Boot Shenanigans

Comme mentionné précédemment, le chargeur de démarrage du deuxième étage doit être situé au début de l’image du micrologiciel. Depuis que j’ai pensé que cela devait être un code générique, j’ai simplement pris le code ASM prêt à l’emploi qui a été recraché par le PicoSDK officiel lors de la construction du Blinky Exemple. Avec cela ajouté au port RP2040 Nodate, le Blinky exemple construit sans problèmes.

Le prochain défi consistait à faire clignoter le binaire ELF résultant sur le RP2040, car il n’y a pas d’adaptateur SWD de style ST-Link intégré sur la carte Raspberry Pi Pico, et en tant que MCU Cortex-M double cœur, il nécessite un SWD multi-drop adaptateur. Jusqu’à présent, les seuls adaptateurs SWD multipoints que j’ai sont intégrés sur les cartes Nucleo STM32H7. J’ai donc décidé d’utiliser le fork OpenOCD personnalisé qui a été créé par la Fondation Raspberry Pi, en l’exécutant sur un Raspberry Pi SBC.

Avec tout cela en place, j’ai flashé avec succès le firmware sur le RP2040 et… je n’ai absolument rien obtenu. Après une inspection superficielle, il est apparu que le code n’a jamais dépassé le chargeur de démarrage initial et n’est jamais entré dans le firmware réel de la ROM SPI. Que cela soit dû à un problème lié à l’ASM du chargeur de démarrage de deuxième étape, quelque chose dans les fichiers expérimentaux RP2040 CMSIS que j’ai dû emprunter aux efforts de quelqu’un d’autre, ou à autre chose, est difficile à dire à ce stade.

À suivre?

Après avoir passé quelques heures à faire fonctionner le RP2040 sans système d’exploitation à l’aide de fichiers CMSIS et de chargeur de démarrage de deuxième étape, le moment était venu de prendre du recul et de réévaluer. Depuis mon évaluation initiale du RP2040, la demande de fonctionnalité CMSIS dans le tracker Pico SDK a été joyeusement mise à jour avec la suggestion que le support officiel CMSIS peut être ajouté avec la version 1.2.0 du Pico SDK.

Je pense qu’il est logique pour quiconque souhaite se familiariser avec le RP2040 en utilisant des outils standard de l’industrie d’attendre cette version. Une fois qu’il tombe, je finirai probablement par revoir d’abord l’exemple de Nodate Blinky, puis enfin vérifier le périphérique PIO. Après avoir lu sur son architecture de machine à deux états, cela semble assez intéressant. Pas aussi puissant qu’un CPLD ou FPGA, mais toujours extrêmement utile.

La seule «  fiche technique  » du RP2040 (plus un manuel de référence et une fiche technique écrasés ensemble) semble parfois oublier qu’elle est censée couvrir le MCU et deviendra un didacticiel Pico SDK. Bien qu’utile pour ceux qui souhaitent utiliser le SDK, il est nettement moins utile pour ceux qui écrivent leur propre implémentation.

Du périphérique GPIO alambiqué, du processus de démarrage multicœur compliqué et de l’obstacle supplémentaire de devoir intégrer un chargeur de démarrage de deuxième étage avec une ROM externe non transparente, une grande partie est plutôt grêle. Vous allez vouloir utiliser le SDK officiel.

Il est possible qu’une fois que l’on s’habitue à ces choix de conception, cela ne soit pas aussi choquant. Ou peut-être s’agit-il simplement d’intégrer le RP2040 dans la chaîne d’outils standard. Chaque nouveau MCU est un peu une expérience d’apprentissage, après tout.