STM32MP1 - noyaux + Linux = microcontrôleur parfait

Par la nature de mon activité, je suis engagé dans le développement de différents appareils: mesure, contrôle, contrôle, etc. La grande majorité de l'appareil est divisée en 2 parties:

  1. Microcontrôleur à ressources élevées et ne nécessitant pas d'interface utilisateur graphique (GUI) en temps réel.
  2. Consommer peu de ressources et travailler dans le matériel dur en temps réel de l'appareil.

Et en règle générale, la transition vers une nouvelle série de microcontrôleurs a été déterminée par l'amélioration de l'interface graphique: plus de couleurs, une résolution plus élevée, des éléments de conception plus complexes. À une époque, l'idée était d'utiliser une sorte de carte Raspberry comme interface graphique.

Mais avec l'avènement de la nouvelle gamme de microcontrôleurs STM32MP1 de STM, mon tourment a pris fin et c'est ce qui s'est produit jusqu'à présent.

Contrôleur parfait


Un contrôleur idéal pour moi devrait avoir les caractéristiques suivantes:

  • avoir des capacités graphiques décentes, telles que la prise en charge simple de divers formats graphiques, la prise en charge des polices vectorielles
  • grande quantité de mémoire pour les graphiques
  • Prise en charge du clavier et de la souris USB
  • Prise en charge Ethernet
  • un grand nombre de minuteries matérielles
  • Génération PWM
  • un grand nombre de GPIO
  • ADC 16 bits

Ce sont ces exigences qui sont nécessaires pour construire divers appareils avec une interface utilisateur graphique décente.

Et j'étais donc très heureux de voir une nouvelle série de STM: STM32MP1.

Première rencontre


Pour se familiariser avec la nouvelle puce, la carte STM32MP157C-DK2 a été achetée. En voici une (photo prise sur Internet): la



carte de démonstration est construite sur une puce STM32MP157CAC, qui comprend:

  • 2 cœurs A7, 650 MHz chacun
  • 1 cœur M4, 208 MHz

Mémoire


La toute première différence qui attire votre attention est le manque de mémoire flash sur la puce. Pour le cœur A7, qui est essentiellement un microprocesseur, il s'agit d'une situation normale et le code est toujours exécuté à partir de la DRAM. Les microcontrôleurs basés sur M4 incluent généralement une mémoire flash dans laquelle le code exécutable est stocké.

Dans ce cristal, le noyau M4 n'a que de la RAM et le code est exécuté à partir de celui-ci (à partir de la fiche technique):

708 kilo-octets de SRAM interne: 256
kilo- octets d' AXI SYSRAM + 384 kilo-octets de AHB SRAM +
64 kilo-octets de AHB SRAM dans le domaine de sauvegarde
et 4 kilo-octets de SRAM dans le domaine de sauvegarde

Le noyau A7 possède un contrôleur DDR intégré (à partir d'une fiche technique):
Les périphériques STM32MP157C / F intègrent un contrôleur pour SDRAM externe qui prend en charge les
périphériques suivants:

  • LPDDR2 ou LPDDR3, données 16 ou 32 bits, jusqu'à 1 Go, horloge jusqu'à 533 MHz.
  • DDR3 ou DDR3L, données 16 ou 32 bits, jusqu'à 1 Go, jusqu'à 533 MHz d'horloge.

D'une part, la mémoire du noyau M4 semble être inférieure à celle de la version en mémoire flash, mais d'autre part, la mémoire RAM fonctionne à la fréquence de base. La mémoire flash ne peut pas faire cela, et là, vous devez utiliser un diviseur de fréquence.

Organisation du lieu de travail


Puisque Linux est nécessaire pour travailler avec la carte, j'ai dû installer un disque dur supplémentaire sur mon ordinateur et y déployer Ubuntu 16.04. Cet OS est recommandé par STM.

Mode ingénierie et production


La carte peut démarrer dans l'un des deux modes (déterminé par le commutateur DIP). En mode Ingénierie, le cœur M4 fonctionne séparément. En mode Production, le cœur M4 s'exécute sous le contrôle du cœur A7. Je n'ai pas utilisé le mode Ingénierie, je ne travaillais qu'en mode Production. Dans ce mode, vous n'avez pas à vous soucier de régler l'horloge principale. La synchronisation est configurée pendant le processus de démarrage à des valeurs maximales. J'ai vérifié plusieurs registres dans le débogueur, déduit certaines des fréquences sur le MCO et regardé l'oscilloscope. A7 fonctionne à une fréquence de 650 MHz, M4 à une fréquence de 208 MHz.

Noyau M4. Télécharger et exécuter des programmes


Étant donné que le noyau M4 exécute A7, cela signifie exécuter OpenSTLinux. Le framework Linux remoteproc (RPROC) est utilisé pour contrôler le noyau M4. Ce cadre vous permet d'activer et de désactiver le noyau, de télécharger et de déboguer le logiciel (fichiers ELF).

Pour charger le programme dans le noyau M4, utilisez la commande suivante:

echo -n <firmware_name.elf >> / sys / class / remoteproc / remoteproc0 / firmware

Pour démarrer le programme:

echo start> / sys / class / remoteproc / remoteproc0 / state

Pour arrêter:

echo stop> / sys / class / remoteproc / remoteprocX / state

Noyau M4. SW4STM32


Les commandes mentionnées ci-dessus ont été essayées, tout fonctionne :) Mais pour fonctionner, vous avez besoin d'une sorte d'IDE normal. La STM recommande d'utiliser le logiciel AC6 SW4STM32 à cet effet. Dans le même temps, le site Web OpenSTM32 a un titre très cool:
Avec System Workbench pour Linux, Embedded Linux sur la famille STM32MP1 de MPU de ST n'a jamais été aussi simple à construire et à entretenir, même pour les nouveaux venus dans le monde Linux.
Et, si vous installez System Workbench pour Linux dans System Workbench pour STM32, vous pouvez facilement développer et déboguer des applications asymétriques s'exécutant en partie sur Linux, en partie sur le Cortex-M4.
Autrement dit, vous pouvez écrire du code pour le noyau m4 et A7. Mais c'est une version payante. Et la version gratuite, disponible en téléchargement, vous permet d'écrire et de déboguer du code uniquement pour le noyau M4.

IDE SW4STM32 a été téléchargé, installé et essayé. Tout fonctionne, le processus d'écriture et de compilation n'est pas différent de la version sous Windows.
La seule différence est le chargement et le débogage du code, car Ethenet et la connexion SSH sont utilisés pour écrire des logiciels. Pour le débogage et l'arrêt par points, la carte ST LINK intégrée est utilisée.

Noyau A7. Compilateur croisé


Pour compiler des programmes sur un PC, STM propose un compilateur croisé. Le processus de chargement et d'exécution du script de compilateur croisé est décrit en détail dans le wiki STM32MP1, lien ci-dessous. Tout a été fait selon les instructions, tout fonctionne comme il se doit. :)

Exécution du compilateur croisé pour l'écosystème v1.1.0:

SDK source / environnement-setup-cortexa7t2hf-neon-vfpv4-openstlinux_weston-linux-gnueabi
, puis la
commande make
et le code source, selon makefile, sont compilés en codes ARM :)

Noyau A7. Télécharger et exécuter des programmes


Pour charger le programme dans la carte de démonstration, utilisez la commande:

scp gtk_hello_world root@192.168.1.18: / usr / local

Cette commande télécharge le fichier gtk_hello_world dans la section / usr / local, qui se trouve sur la carte avec l'adresse IP: 192.168.1.18. Root - le mot de passe qui se trouve sur la carte par défaut.

Échange de données intercœur


La plupart du temps a été consacré à la compréhension du mécanisme d'échange de données entre les cœurs. Dans les exemples fournis par STM, il existe plusieurs options pour implémenter un tel échange. Vous pouvez travailler directement avec le pilote depuis OpenSTLinux ou utiliser le mécanisme UART virtuel. J'ai décidé de simplifier le partage via des ports virtuels.

Côté Linux, cela ressemble à ceci:

Ouvrez l'appareil:

fd = open ("/ dev / ttyRPMSG0", O_RDWR);

Ensuite, nous y écrivons ou lisons:

write (fd, "LED_Toggle \ r \ 0", 10);
len = read (fd, buf, sizeof (buf));

Tout est assez simple, mais il y a une petite nuance. Pour que le périphérique ttyRPMSG0 apparaisse, vous avez besoin du noyau M4 pour accéder au noyau A7 sous cette forme:

ce sont les lignes du code du noyau M4:

VIRT_UART_Init(&huart0); //  
VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) //      .

Réception des données d'un port virtuel par le noyau M4:

if (VirtUart0RxMsg)
{
      //     VirtUart0ChannelBuffRx
     
      VirtUart0RxMsg = 0;
}

Écriture de données sur le port virtuel:

VIRT_UART_Transmit(&huart0, TxArray, TXCounter);

Tout fonctionne, mais il y a une petite nuance que je ne peux pas encore comprendre. La réception de données par le cœur A7, qui est transmise par le cœur M4, ne commence pas si le cœur A7 n'écrit pas auparavant de données sur le port.

L'ensemble de ce mécanisme est implémenté par un ensemble de bibliothèques OpenAMP tierces. Cette bibliothèque doit être incluse dans le projet de noyau M4 et initialisée en conséquence.

Plans futurs


Installez et configurez Eclipse pour écrire et déboguer du code pour A7.
Écrivez une démo graphique normale, comme un oscilloscope à partir d'un ADC M4.
Et enfin, faites votre carte contrôleur basée sur cette puce. :)

Liens utiles

Wiki STM32MP1
OpenSTM32
ST Community
AC6

All Articles