Serveur web sur STM32#

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.

É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. Sélectionnez dans la liste la carte trouvée et choisissez Next

  • Donnez un nom à votre projet (led-bleue) et choisissez les paramètres par défaut (Use default location, C, Executable et STM32Cube), puis sélectionnez Finish.

  • 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 qui a le label associé LD2 [Blue]. Le nom LD2 sera le nom de la constante qui pourra être utilisée dans le code pour agir sur la tension électrique de la patte. En cliquant sur la patte, on peut voir que la patte est en mode GPIO_Output (voir GPIO sur Wikipédia). 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);

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 que led-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 et STLK_RX pour la réception). Ces deux pattes sont en relation avec l’USART3 (voir UART) du MCU. Aller dans l’onglet à gauche Connectivity et repérer USART3 (qui doit être en orange, indiquant qu’il n’est pas configuré). Cliquer dessus et sélectionner Asynchronous. Sauvegarder pour générer le code correspondant.

  • Une variable globale huart3 a été définie, la repérer dans le code de main.c de votre projet. Cette variable, de type UART_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 fonction main, 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 port COMx 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:

activate interrupt

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.

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)

Troisième étape: serveur HTTP#

En vous aidant de l’exemple disponible sur Github, ainsi que de la série d’articles sur Controllers Tech (voir également ci-dessous dans les Ressources), ajouter une commande “w” démarrant un serveur web renvoyant un message fixe Hello, world! à toute requête GET et écrivant sur le port série un message de log, avec notamment l’adresse IP de la machine cliente.

Ajouter une commande “s” au mini-shell stoppant le serveur web.

Quatrième étape: serveur web complet#

Faire en sorte que le serveur web serve le fichier index.html présent sur une clef USB connectée à la carte NUCLEO.

De manière alternative, prévoyez un protocole permettant via une requête POST de changer une page sur le serveur (avec écriture de cette page dans la mémoire du STM32).

Travail alternatif: micro Python sur STM32F2#

Comme travail alternatif, vous pouvez également tenter de porter Micro Python ou Pika Python sur la carte STM32F2.

Attention: il n’est pas du tout garanti que ces deux versions de Python puissent tourner sur la carte STM32F2: ce travail est exploratoire.

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#

Tutoriels#