Serveur web sur STM32 et acquisition de données d’un moniteur INA226¶
L’objectif de ces travaux pratiques est d’implémenter un serveur web sur une carte Nucleo-144 à base de STM32, utilisant la prise Ethernet et une clef USB connectée contenant les fichiers à servir.
Le serveur web devra pouvoir être piloté par le port série (avec des commandes à définir), et enverra lorsqu’il est actif des messages de log sur le port série à chaque connexion.
Une extension de ces travaux sera d’implémenter un mode où des données seront récoltées d’un moniteur INA 226 de Texas Instruments branché à la carte et rediffusées en UDP sur la carte réseau.
Étapes préliminaires¶
Installation de l’IDE et allumage de la led bleue¶
Installer sur votre ordinateur STM32CubeIDE
Ouvrir l’IDE précédemment installé et créez un nouveau projet led-bleue
ainsi:
Menu
File -> New -> STM32 Project
Dans la nouvelle fenêtre qui vient de s’ouvrir, allez dans l’onglet à gauche
Board Selector
et saisissez la référence de la carte: NUCLEO-F207ZG (ou une autre carte selon la carte fournie par votre enseignant). Sélectionnez dans la liste la carte trouvée et choisissezNext
Donnez un nom à votre projet (
led-bleue
) et choisissez les paramètres par défaut (Use default location
,C
,Executable
etSTM32Cube
), puis sélectionnezFinish
.Répondre
No
à la question: « `Initialize all peripherals with their default mode? ».
À ce stade, vous devriez être sur une fenêtre vous présentant le schéma du MCU STM32F207ZGTx, LQFP144. Cette fenêtre permet de configurer graphiquement le comportement du MCU et de modifier le statut de ces pattes. En sauvegardant le fichier ainsi modifié (s’appelant led-bleu.ioc
), l’IDE va générer un template de code C contenant la configuration correspondant à la représentation graphique. La configuration qui vous est présentée ici est celle « par défaut » définie par l’IDE (plus précisément, par STM32CubeMX qui est l’outil utilisé par l’IDE).
En zoomant vous devriez vous la configuration des différents pattes du chip. Essayez de repérer la patte PB7. Passez cette patte en mode GPIO_Output
(voir GPIO sur Wikipédia) et associez-y le nom BLUE
. Ce sera le nom de la constante qui pourra être utilisée dans le code pour agir sur la tension électrique de la patte. On retrouve également dans l’onglet System
à gauche dans la rubrique GPIO la configuration des différentes pattes du MCU.
Pour plus d’informations sur la configuration des LED de la carte, voir UM1974 User manual, STM32 Nucleo-144 boards (MB1137), page 24
Nous allons à présent modifier le code C afin d’allumer et d’éteindre la LED bleue toutes les 100 ms.
Dans le projet créé, ouvrez le fichier main.c
se trouvant dans le répertoire Core/Src
. Repérez dans la fonction main
la boucle while
implémentant une boucle infinie. Dans ce while
, ajoutez les lignes suivantes:
HAL_GPIO_TogglePin (GPIOB, LD2_Pin);
HAL_Delay (100);
# Exercice: comment rendre ce code plus propre?
Compilez le code pour obtenir le fichier binaire en cliquant sur l’icône représentant un marteau
Branchez la carte en USB sur votre ordinateur, avec la prise USB qui est du côté du ST-Link (voir UM1974 User manual, STM32 Nucleo-144 boards (MB1137), page 12
Flashez le firmware de la carte avec votre code binaire en appuyant sur l’icône « Run » représentant un icône « play » blanc sur fond vert rond.
Normalement, la led bleue devrait clignoter.
Envoi de données sur le port série¶
Nous allons dans cette partie envoyer le message Hello, world!
sur le port série avec une transmission bloquante. Pour cela nous allons utiliser une des fonctions du HAL (Hardware Abstraction Layer), qui est une API logicielle d’abstraction du matériel fournie par ST permettant de faciliter l’accès au matériel et d’améliorer la portabilité du code entre différents MCU. La fonction que nous allons utiliser est:
HAL_StatusTypeDef HAL_UART_Transmit (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size, uint32_t Timeout)
dont on peut trouver la description dans le manuel de référence UM1940, page 660.
Créer un nouveau projet
text-over-serial
de la même manière queled-bleue
Lors de la configuration avec STM32CubeMX, repérer les pattes PD9 et PD8 qui sont connectées au port USB du ST-Link (
STLK_TX
pour l’émission etSTLK_RX
pour la réception). Ces deux pattes sont en relation avec l’USART3 (voir UART) du MCU. Aller dans l’onglet à gaucheConnectivity
et repérerUSART3
(qui doit être en orange, indiquant qu’il n’est pas configuré). Cliquer dessus et sélectionnerAsynchronous
. Sauvegarder pour générer le code correspondant.Une variable globale
huart3
a été définie, la repérer dans le code demain.c
de votre projet. Cette variable, de typeUART_HandleTypeDef
est une structure de donnée permettant d’interagir avec l’USART3. Repérer également le code qui initialise cette structure.Définir un message en variable globale dans le code de
main.c
:
unsigned char msg[] = "Hello, world\r\n";
Dans la boucle
while
infinie dans la fonctionmain
, ajouter la transmission du message et un délai d’attente:
HAL_UART_Transmit(&huart3, msg, sizeof(msg), 100);
HAL_Delay(100);
Flashez et exécutez le code.
Afin de voir le message, il faut se connecter au port série sur le port USB de votre machine correspondant au port USB de la carte. Le port série sur macOS doit être de la forme
/dev/ttyUSBmodemxxx
, sous Linux de la forme/dev/ttyACM0
, sous Windows il s’agit d’un portCOMx
qu’il faut repérer en examinant la configuration des périphériques du système. Dans les logiciels que nous allons utilise ci-dessous, bien penser à régler la vitesse à 115200 bauds.Pour se connecter, vous pouvez utiliser soit:
Minicom (macOS et Linux):
minicom -D /dev/ttyACM0
(quitter avec CTRL-a x)Screen (macOS et Linux):
screen /dev/ttyACM0 115200
(quitter avec CTRL-a k)Putty (Windows et Linux)
Hyperterminal (Linux)
En vous connectant, vous devriez voir apparaître les messages
Hello, world!
Utilisation des interruptions¶
Modifier le code précédent pour utiliser des interruptions, en utilisant les fonctions:
HAL_UART_TxCpltCallback()
HAL_UART_Transmit_IT()
Dans ce cas, il faut absolument aller dans le configurateur de votre .ioc
pour activer les interruptions sur votre USART:
Première étape: messages et mini-shell¶
Écrire un programme qui envoie des messages quelconques sur le port série avec un délai de l’ordre de 1 seconde entre les messages (ce délai peut varier en cas de besoin), en faisant également clignoter l’une des LED de la carte à chaque écriture de message.
Programmer un mini-shell attendant l’envoi d’un caractère utilisateur et effectuant une opération en fonction du caractère appuyé, en suspendant l’envoi des messages le temps que l’opération soit
effectuée (à vous de définir la liste des opérations et les caractères
associés, a
peut par exemple être l’opération qui envoie hello
sur
le port série, b
l’opération qui allume une LED, c
l’opération qui
éteint cette LED, h
l’affichage d’une aide.
Un article de blog Building a Tiny CLI Shell for Tiny Firmware détaille la construction d’un shell sur un petit système embarqué.
Un autre article Hello, World! sur STM32 détaille également un interpréteur de commandes simple (d’autres articles du même blog: Template et Présentation générale) peuvent également être intéressants.
Deuxième étape: lecture de fichiers depuis une clef USB¶
Cette deuxième étape peut être faite en dernier, après la construction du serveur web de l’étape suivante.
En vous aidant de l’exemple disponible sur Github, ajouter une commande l
au mini-shell précédent permettant de lister les fichiers présents sur une clef USB branchée à la carte NUCLEO et une commande “i” envoyant le contenu du fichier index.html
sur le port série si ce fichier est présent sur la clef.
Notes: pour créer un système de fichiers sur une clef USB sous macOS ou Windows, utilisez les utilitaires de disque respectifs de ces deux OS. Le système de fichier doit être au format FAT32. Sous Linux, utilisez les outils suivants en ligne de commande après avoir monté la clef sur votre machine:
# !! Attention: prudence, soyez sûr du nom de votre périphérique.
# En cas de doute, demandez à votre enseignant.
lsblk # pour repérer le périphérique (par exemple /dev/sda)
sudo fdisk /dev/sda # Taper 'o' puis 'w' pour créer une table de partition DOS vide
sudo cfdisk /dev/sda # Pour créer une partition unique de type Primary/W95 Fat32 (par ex /dev/sda1)
sudo mkfs.vfat -F 32 /dev/sda1 # Création du système de fichiers
sudo mlabel -i /dev/sda1 -s ::"TLSE9" # Pour donner le nom TLSE9 à la clef (apt-get install mtools)
Prochaines étapes¶
Avec les explications données par vos enseignants, modifier votre serveur pour qu’il récupère les données d’un capteur INA226 via le port I2C de la carte et reserve ces données sur le port Ethernet en UDP vers un client (votre machine).
Créer un serveur web permettant de servir les fichiers présents sur la clef USB
Afficher pour chaque requête un message de log sur la console
Mesurer avec locust la performance de votre serveur
Comment améliorer ces performances?
Rendu de travaux¶
Envoyez votre code final à votre enseignant sous la forme d’un fichier tgz
ou zip
(en excluant les fichiers binaires situés dans le répertoire Debug
).
Ressources¶
STMicroelectronics¶
UM1739 User manual, Getting started with STM32CubeF2 firmware package for STM32F2 Series
Librairies logicielles à la base de STM32CubeMX: STM32Cube MCU Full Package for the STM32F2 series, avec de nombreux exemples (Pilotes HAL et LL, CMSIS, midleware libraries). Voir également: AN4733, Application note, STM32Cube firmware examples for STM32F2 Series
PM0056 Programming manual,STM32F10xxx/20xxx/21xxx/L1xxxx Cortex-M3 programming manual
PM0059 Programming manual, STM32F205/215, STM32F207/217 Flash programming manual
UM1713 User manual, Developing applications on STM32Cube with LwIP TCP/IP stack
UM1721 User manual, Developing applications on STM32Cube™ with FatFs
UM1722 User manual, Developing applications on STM32Cube with RTOS
UM1727 User manual, Getting started with STM32 Nucleo board software development tools
UM1940 User manual, Description of STM32F2 HAL and low-layer drivers
UM2298 User manual, STM32Cube BSP drivers development guidelines