Programmation des SOCs RT4/IIA4 Travaux Pratiques I- INTRODUCTION Contrairement au développement d’applications pour les PCs ou un programme peut être ‘généralement’ exécuté sur n’importe quelle machine à base d’un microprocesseur compatible x86, le développement d’une application embarqué est plus compliqué. Rien ne garantit qu’une application fonctionnant sur une plateforme matérielle puisse fonctionner sur une autre. D’où la nécessité d’adapter le programme : - A la structure interne du microcontrôleur utilisé. - Au schéma électrique de la carte à programmer (connexions entre pins du microcontrôleur et composants externes tels que les leds les boutons poussoirs, afficheurs, etc.. . - A la librairie de fonctions supportées par l’environnement de développement. Ainsi, pour la programmation de la plateforme, il est indispensable d’utiliser principalement 3 documents conjointement : Board Manual.pdf Document qui décrit le schéma électrique de la carte à programmer Déterminer les périphériques et les ports, à utiliser en fonction du fonctionnement ciblé du système et du schéma électrique. Fonctionnement du système Option : Développement embarqué STM32 Reference manual.pdf Document qui décrit l’architecture interne de la famille des mc STM32 Firmware Library Description des variables et fonctions de la librairie fournie par ST. Déterminer : - les signaux d’horloge à activer - les entrées d’interruptions à utiliser. Déterminer : - les structures et fonctions à utiliser. - Les valeurs à attribuer aux propriétés Programme 1 INSAT 2019 II - Généralités II-1 : Les plateformes utilisées Au cours des séances de TPs, plusieurs cartes à base de microcontrôleurs STM32 seront utilisées : 1- Les cartes NUCLEO F103 (à base de microcontrôleurs STM32F103RB) : qui possèdent des connecteurs compatibles avec les cartes d’extension pour arduino. On trouve : Une LED reliée au pin PA5 Un Bouton poussoir relié au pin PC13 Un adaptateur de communication USB/série UART E. DAMERGI 2I INSAT2019 Programmation des SOCs RT4/IIA4 2- Les cartes Discovery (à base de microcontrôleurs STM32F100RB) On trouve : - 2 Leds reliées aux pins PC8 et PC9. - Un bouton poussoir relié au pin PA0. Option : Développement embarqué 3 INSAT 2019 3- Les cartes Nucleo F401 (à base de microcontrôleurs STM32F401RE) On trouve : - 1 Led reliée aux pins PA5. - Un bouton poussoir relié au pin PC13. - Un adaptateur USB/Série (UART) - Des connecteurs compatibles Arduino E. DAMERGI 4I INSAT2019 Programmation des SOCs RT4/IIA4 4- Les cartes DiscoveryF4 (à base de microcontrôleurs STM32F407VG) On trouve : 4 Leds reliées aux pins PD12,13,14 et 15. Un bouton poussoir relié au pin PA0 Un axeléromètre 3 axes relié au périphérique SPI. Un microphone. Un DAC 24 bits (Digital ANalog Converter) pour générer des signaux analogiques audio. Un jack Audio. Option : Développement embarqué 5 INSAT 2019 II-2 : Utilisation de l’IDE keil 1- Commencer par ouvrir le projet contenant la manip i, i étant le numéro de la manip. Son chemin est : « Projets / manipi / manipi.uvprojx » 2- Compléter le code permettant d’assurer le fonctionnement décrit dans le paragraphe relatif à la manip. 3- Une fois le code terminé, le compiler avec l’outil IAR pour générer l’exécutable en utilisant la commande Project>>Rebuild All (voir figure ci-dessous). Si tout se passe bien, on doit obtenir l’affichage suivant au niveau de la fenêtre « Messages » en bas de l’IDE de l’outil IAR. Sinon, des messages d’erreurs seront affichés. E. DAMERGI 6I INSAT2019 Programmation des SOCs 4- RT4/IIA4 Finalement il est possible de charger le programme sur la plateforme cible (Project>>Download and Debug) et l’exécuter (Go) : Rq : Il est possible qu’un programme ne fonctionne pas comme prévu (même si la compilation est réussie). Dans ce cas, il est possible de trouver les erreurs en procédant au débogage du programme : il s’agit de l’exécuter pas à pas ou en insérant des breakpoints. A chaque arrêt du programme, il est possible de consulter les contenus des registres du microcontrôleur ainsi que les valeurs des variables utilisées et de vérifier s’ils correspondent au fonctionnement désiré. Option : Développement embarqué 7 INSAT 2019 III - Travail demandé : Les Manips 1- Programmation par accès direct aux registres (2heures30) L’objectif est la familiarisation avec l’environnement de développement intégré Keil ainsi que le principe de fonctionnement et de programmation des interfaces de périphériques par accès direct aux registres. MANIP 1-1 : « STM32_NucleoF401_RegAccess\manip1_1_Led_Blink\MDK-ARM\*.uvprojx » On veut développer un programme ‘C’ qui permet de faire clignoter le(s) Led(s) de la carte à base du microcontrôleur STM32. Trouver les adresses des registres des ports auxquels sont connectées les Leds ainsi que les positions des bits qui permettent de contrôler les pins. (consulter le STM32F4 Reference manual.pdf). Ecrire le programme en ‘C’en utilisant l’accès direct aux registres. compiler le programme et le charger dans la carte afin de l’exécuter et tester son bon fonctionnement (voir parag II : Utilisation de l’IDE Keil) MANIP 1-2 : «STM32_NucleoF401_RegAccess\manip1_2_Button_Led\MDK-ARM\*.uvprojx » On veut développer un programme en ‘C’ en utilisant l’accès direct aux registres et qui permet d’allumer les Leds quand on appuie sur le bouton poussoir et de les éteindre quand on le relâche. Trouver les adresses du port auquel est connecté le bouton poussoir ainsi que les positions des bits qui permettent de contrôler les pins. (consulter le STM32 F4 Reference manual.pdf). Ecrire le programme en ‘C’en utilisant l’accès direct aux registres Compiler le programme et le charger dans la carte afin de l’exécuter et tester son bon fonctionnement. E. DAMERGI 8I INSAT2019 Programmation des SOCs RT4/IIA4 MANIP 1-3 : «STM32_NucleoF401_RegAccess\manip1_3_Button_Led_MemMap\MDK-ARM\*.uvprojx » On veut développer un programme en ‘C’ qui assure le même fonctionnement que celui de la manip_1-2, avec : 1) Faire abstraction des adresses des registres au niveau de la configuration des GPIOs et utiliser des instructions d’accès ayant la forme PERIPH Registre (exemple GPIOAMODER) pour accéder au registre MODER du GPIOA. Pour cela : Au niveau du fichier « gpiosmap.h » ajouter le code (structure et pointeurs) permettant de décrire le Memory Map (Cartographie) relatif au GPIOs (A F). 2) Le test du bouton poussoir, Allumer une Led ou l’éteindre devrait se faire en faisant appel respectivement à des fonctions uint8_t HAL_TestPin(GPIOx, GPIO_Pin) : qui retourne l’état (0 ou 1) du Pin passé en paramètre void HAL_SetPin(GPIOx,GPIO_PIN) : qui met à 1 le Pin passé en paramètre void HAL_ResetPin (GPIOx, GPIO_PIN) : qui met à 1 le Pin passé en paramètre Pour cela : Au niveau du fichier « gpiofunctions.c » ajouter le code de chacune des fonctions. Au niveau du fichier « gpiofunctions.h », ajouter les prototypes des 3 fonctions . Compiler le programme et le charger dans la carte afin de l’exécuter et tester son bon fonctionnement. Option : Développement embarqué 9 INSAT 2019 2- Programmation par utilisation de la librairie HAL (4 heures) L’objectif est de comprendre la programmation des interfaces de périphériques en utilisant les drivers fournis avec la librairie ST (ST HAL : Hardware Abstraction Layer). Partie I : Les GPIOs MANIP 2-1 : « STM32_NucleoF401_HAL\manip2_1_HAL_Led\MDK-ARM \ * . uvprojx » On veut développer un programme ‘C’ qui permet de faire clignoter le(s) Led(s) de la carte STM32. Trouver les fonctions de la librairie qui permettent de mettre un pin à 1, ainsi que la fonction de mise à 0 d’un pin (voir figure ci-dessous). Dans la fenêtre « project », cliquer sur l’onglet « Functions», et ensuite sur le fichier relatif au périhérique : stm32fxx_ppp.c, ppp étant le nom du périph (exemple : stm32Fxxx_gpio.c) Compléter le code source (main.c), compiler le programme et le tester sur la carte. MANIP 2-2 : « STM32_NucleoF401_HAL\Manip2_2_HAL_PushB_Led\MDK-ARM \ *.uvprojx » On veut développer un programme qui permet d’allumer le(s) Leds quand on appuie sur le bouton poussoir et de les éteindre quand on le relâche. La lecture de l’état du bouton étant assurée par le mécanisme de scrutation. Trouver les fonctions de la librairie qui permettent de lire l’état d’un pin. Ecrire le programme en ‘C’en utilisant les fonctions des drivers. Compiler le programme et le charger dans la carte afin de l’exécuter et tester son bon fonctionnement. E. DAMERGI 10I INSAT2019 Programmation des SOCs MANIP 2-3 : RT4/IIA4 « STM32_NucleoF401_HAL\HAL_Inverser\MDK-ARM\*.uvprojx » Ajouter une fonction HAL_GPIO_InverseBits à la librairie de ST (ST HAL) et écrire un programme (en utilisant cette fonction) de telle sorte à ce qu’à chaque appui sur le bouton poussoir le(s) led(s) changent d’état. Rq : L’appel à la fonction devrait s’effectuer de la sorte HAL_GPIO_InverseBits (GPIOx, GPIO_Pin) GPIO_Pin étant est un Pin ou une combinaison de pins (GPIO_Pin_1 | GPIO_Pin_4 | ……) Indication : utiliser l’opérateur XOR (^). Partie II : USART : Transmission Série Asynchrone ( Polling Mode) II-A- Fonctionnement : Pour les 2 manips suivantes, il s’agit d’utiliser la scrutation (test continu) pour recevoir et envoyer des données sur le port série USART2. Le code à développer doit répéter continuellement, et tant que le bouton poussoir n’est pas appuyé (==1) les actions suivantes : - Attendre jusqu’à ce qu’un caractère soit reçu sur l’interface série USART2 (Pin RX= PA3). S’il s’agit du caractère ‘G’, alors le microcontrôleur envoie le contenu de la chaine MessageOK[] à travers l’interface série USART2 (Pin TX= PA2) et allume la Led. - Sinon il envoie le contenu de la chaine MessageKO[] et éteint la Led (PA5). Si le bouton poussoir est appuyé, envoyer le message « End of Comm » par liaison série. Manip 2-4 : Communication série par Polling ‘Scutation’ « STM32_NucleoF401_HAL\HAL_USART2_Polling\MDK-ARM\*.uvprojx » Au niveau du projet : - Compléter le code permettant d’initialiser les périphs utilisés (GPIO Pins, USART Pins et USART) au niveau du fichier main.c, en utilisant les Alias pour les pins et les interfaces GPIOs (voir mxconstants.h ou bien main.h selaon la version de CubeMX). Option : Développement embarqué 11 INSAT 2019 - Compléter le code de la fonction USART2_Send_Data L’accès direct aux registres pour l’envoi et la réception des données. La fonction __HAL_UART_GET_FLAG pour scruter les bits de Flag RXNE et TXE. - Compléter le code au niveau de la boucle while(…………. ;) - Tester le code sur la carte. Manip 2 -5: Communication série en mode polling avec CubeMx/HAL Il s’agit du même fonctionnement (voir II-A). Pour cette manip , aucun code n’est fourni. Le code permettant la configuration et l’initialisation des périphériques doit être généré par utilisation de l’outil CubeMX, et le code permettant d’assurer le fonctionnement doit être complété en utilisant les fonctions de la librairie HAL. Commencer par générer le code d’initialisation à partir de l’outil CubeMX en utilisant l’option generate Peripheral Initialization as pairs .h/.c files per IP. C’est-à-dire que pour chaque périph PPP utilisé, les paramètres et le code permettant sa configuration et son initialisation vont être mis dans des fichiers PPP.c et PPP.h et non pas au niveau des fichiers main.c et main.h. Utiliser les Alias Led, PushButton, Serial_Tx et Serial_Rx pour les différents pins utilisés. - Au niveau de quelle fonction et quel fichier se fait l’initialisation des pins TX et RX relatifs à l’interface série USART2 ? - Au niveau de quelle fonction se fait l’appel à cette dernière (la fonction d’initialisation des pins TX et RX). - Que serait le code au niveau de la fonction d’initialisation des pins TX et RX si on a utilisé deux interfaces série USART2 et USART3 ? - Quelles fonctions de la librairie HAL doivent être utilisées pour l’envoi (resp. réception) des données en mode polling ? Compléter le code et le tester sur la carte STM32. E. DAMERGI 12I INSAT2019 Programmation des SOCs RT4/IIA4 3- Mécanisme d’interruptions : EXTI, SYSTICK, USART (4 Heures) Il s’agit de programmer les interfaces de périphériques de telle sorte à exploiter le mécanisme d’interruptions : on traite principalement les interruptions relatives aux entrées externes des GPIO (EXTI : EXTernal Interrupts) ainsi que celle relative au Timer système (SysTick). Manip 3-1 : External Interrupts avec HAL (\01_HAL_EXTI) Il s’agit d’écrire un programme qui permet de faire clignoter une fois le(s) led(s) à chaque appui sur le bouton poussoir, en utilisant le mécanisme d’interruptions et en se basant sur la librairie HAL. - Compléter le code permettant d’initialiser les périphs utilisés au niveau main.c. - A quel niveau (Fichier, Fonction) doit-on ajouter le code à exécuter à chaque appui (ISR ou Handler). - Plusieurs fonctions sont disponibles pour la remise à 0 du Pending Bit : a) __HAL_GPIO_EXTI_CLEAR_IT “stm32f10x_hal_gpio.h” b) __HAL_GPIO_EXTI_CLEAR_FLAG “stm32f10x_hal_gpio.h” c) HAL_NVIC_ClearPendingIRQ (IRQn_Type IRQn) “stm32f10x_hal_cortex.c” Comparer ces fonctions (niveau code) et préciser quelle est la plus appropriée pour remettre à 0 le pending bit au niveau du Handler. Expliquer. - Ecrire le Handler et tester. - Comment change le comportement du programme quand on met la fonction, permettant la remsie à 0 du pending bit, au début ou à la fin du Handler. Expliquer. Dans les 2 manips suivantes (3-2 et 3-3), l’objectif et de comprendre l’organisation du code généré automatiquement par l’outil CubeMX pour la configuration des périphériques et l’exécution du code relatif aux interruptions (Handlers) Manip 3-2 : External Interrupts avec HAL/CubeMX (\02_CubeMX_EXTI) Il s’agit de travailler sur un code se basant sur la librairie HAL mais généré automatiquement par CubeMx et dont l’organisation diffère un peu de celle du code de la manip 3-1. - A quel niveau (fonction/fichier) se fait l’initialisation des périphs ? Option : Développement embarqué 13 INSAT 2019 - Quelles sont les fonctions exécutées après la détection d’un évènement. Préciser les fonctions (dans quel fichier), l’ordre d’appel ainsi que le rôle des différentes parties du code. - A quel niveau doit-on ajouter le code utilisateur ? - Ajouter le code et tester le programme. Manip 3-3 : SysTick avec HAL/CubeMX ( \03_CubeMX_SysTick) Il s’agit d’écrire un programme qui permet de faire clignoter le(s) led(s) toutes les 2 secondes en utilisant le mécanisme d’interruptions. Une partie du code est déjà générée automatiquement par CubeMX. - Compléter le code permettant de configurer le System Timer de telle sorte à générer une interruption toutes les 1 msec (utiliser le System HCLK comme fréquence d’horloge pour le timer). - Ecrire au niveau du Handler le code permettant d’assurer le fonctionnement désiré. Dans les manips suivantes (3-4 et 3-5), aucun code n’est donné. Il faut générer soi-même le code d’initialisation des périphériques avec l’outil CubeMX et compléter le code permettant d’assurer le fonctionnement du système. Manip 3-4 : EXTI & SysTick / CubeMX Il s’agit d’utiliser conjointement les interruptions du System Timer et celles des EXTI : Au début, fait clignoter la Led toutes les 2 secondes. A chaque appui sur le bouton poussoir, la période de clignotement est divisée par 2 (c’est-à-dire au 1er appui, on a une période de 1sec, ensuite 500msec, 250 msec, etc…). - Commencer par générer le code d’initialisation et de configuration des périphs en utilisant l’outil CubeMX. - Compléter le code de telle sorte à assurer le fonctionnement souhaité. Rq : aussi bien la temporisation que la détection de l’état du bouton doit être gérée par utilisation du mécanisme d’interruptions. E. DAMERGI 14I INSAT2019 Programmation des SOCs RT4/IIA4 Manip 3_5 : Il s’agit de réaliser une communication série (UART) entre un microcontrôleur STM32 et un PC en utilisant le mécanisme d’interruption pour la réception L’interface série USART1 (9600 bps, Pas de Parité, 2 bits de stop) est configurée pour déclencher en plus des interruptions à chaque réception d’un caractère (envoyé à partir du Terminal). Ces caractères étant sauvegardés dans une variable char Receive_Buffer[10]. STM32 DMA BUS AHB Bridge NVIC PCPPC Terminal (Hecules) BUS APB TX USART1 RX_Int_Request Usb To Serial Driver RX Serial To Usb (Nucleo) usb Une fois 10 caractères sont reçus, il faut comparer la chaine de 10 caractères à une chaine de caractères password[ ]= "9876543210". Si les 2 chaines sont les mêmes, alors allumer la LED et attendre (delay (0xFFFFF)), sinon la faire clignoter lentement. Option : Développement embarqué 15 INSAT 2019