TP Systèmes embarqués (ATMega328p, ATMega32u4 et ATMega16u2)Xavier Redon2021 - 2022 |
Le but de ces travaux pratiques est de programmer des systèmes embarqués à base de microcontrôleurs 8 bits en utilisant du C pur.
Vous devrez :
Eventuellement vous pourrez :
Pour ces travaux pratiques vous disposerez :
Vous pourrez aussi manipuler quelques mini-robots Polytech’Lille et quelques mini-robots MaQueen avec leur carte MicroBit.
Voici quelques précisions sur les programmes à réaliser. La programmation doit se faire en C en utilisant le compilateur avr-gcc. Pour la programmation USB, vous n’utilisez pas directement les registres du microcontrôleur mais vous utiliserez la bibliothèque libre LUFA. Pour télécharger l’exécutable AVR dans le microcontrôleur vous utiliserez l’utilitaire avrdude pour les systèmes avec un convertisseur USB / série, et l’utilitaire dfu-programmer pour les systèmes avec un microcontrôleur ATMega{16|32}u{2|4}.
Sous un système Linux dérivé de Debian, vous devez installer :
La programmation se fait sur le microcontrôleur ATMega328p. Vous pouvez trouver un projet vide à l’adresse ManetteSerie.tgz. Vous y
gagnerez au moins le fichier Makefile qui permette de lancer facilement la compilation et le téléchargement par la commande make.
Je vous propose la progression suivante pour la programmation de la manette :
La programmation se fait sur le microcontrôleur ATMega32u4. Comme le u de son nom l’indique, ce micro-contrôleur possède une gestion matérielle du bus USB (USB2.0).
Sur le principe vous devez implanter un périphérique USB HID (périphérique d’interface homme-machine, "human interface device" en patoi).
Un tel périphérique comporte une interface de classe HID avec au minimum un point d’accès entrant (IN).
Utilisez le joystick de la carte pour votre HID, l’accéléromètre est probablement grillé (sauriez-vous dire pourquoi en regardant le schéma de la carte ?).
Sur le site http://www.fourwalledcubicle.com/LUFA.php, téléchargez la dernière version de la bibliothèque USB LUFA. Créez un
répertoire I2L au même niveau que les répertoires Demos et Projects.
Dans ce répertoire copiez la démonstration du sous-chemin Device/ClassDriver/Joystick sous le nom, par exemple, Manette.
Renommez aussi les fichiers dans le répertoire et modifiez le makefile. Au niveau
du makefile indiquez atmega32u4 comme micro-contrôleur, NONE comme platine, ajustez le chemin d’accès LUFA_PATH
et passez à 16Mhz.
Ajoutez les fonctions de gestion de la carte Polytech’Lille (boutons, joystick) dans le répertoire PolytechLille/Manette.
Pensez à modifier le fichier makefile pour compiler votre nouveau fichier source.
La procédure à suivre pour charger votre programme sur l’ATMega32u4 est la suivante :
dfu-programmer atmega32u4 erase dfu-programmer atmega32u4 flash Manette.hex dfu-programmer atmega32u4 reset
Si vous voulez aller plus loin, vous pouvez ajouter la gestion des LED et des vibreurs à votre manette. En toute théorie, il est possible d’intégrer
la gestion des LED et des vibreurs sous la classe USB HID. Le moins que l’on puisse dire c’est que cela complexifie considérablement le descripteur
HID et encore il faut faire de l’ingéniérie inverse pour le constituer. Nous allons donc procéder autrement. Vous allez ajouter, à l’interface standard
HID, une autre interface de classe spécifique au vendeur (USB_CSCP_VendorSpecificClass, pas de descripteur supplémentaire nécessaire) peuplé
d’un point d’accès de type interruption en écriture (endpoint OUT). La communication avec le point d’accès doit se faire sur un octet. Pour les vibreurs
la commande peut passer par le point d’accès de contrôle qui pré-existe pour tous les périphériques USB. Pour la gestion du point d’accès interruption,
vous pouvez vous aider de la démonstration Keyboard dans le répertoire Device/LowLevel. La déclaration de l’interfaces et du point d’accès
est clairement montrée dans les fichiers Descriptors.c et Descriptors.h de cette démonstration. La gestion de points d’accès de type interruption
est montrée dans l’autre source C de la démonstration, cherchez les fonctions Endpoint_ConfigureEndpoint, Endpoint_SelectEndpoint, etc.
N’hésitez pas à consulter la documentation de la bibliothèque sur Internet. Pour la gestion du point d’accès de contrôle examinez le projet LUFA
Projects/RelayBoard, en particulier le fichier RelayBoard.c. Utilisez un numéro de requête en dehors de la plage des requêtes système.
Le prétexte à cet exercice est de réaliser un keylogger, c’est à dire un dispositif d’espionnage clavier. Le dispositif est composé de deux parties :
La seconde carte scrute les touches du clavier USB et les transmet par liaison série à la première carte. La première carte transmet les codes de touches
au PC mais en prenant soin de les sauver dans sa mémoire. Sur pression des boutons de la première carte, cette dernière bascule en mode stockage de masse
pour permettre la lecture des touches sauvegardées.
L’exercice ne concerne que la permière carte et encore dans son mode de stockage de masse (Mass Storage en patoi). Dans ce mode elle se comporte comme
une clef USB de (très) faible capacité (quelques Mo).
Commencez par un test basique de la clef : faire clignoter une ou plusieurs LED. Vous pouvez aussi tester les boutons. Vous pouvez repartir du projet
de la manette série mais en modifiant le téléchargement pour utiliser dfu-programmer à la place d’avrdude.
La seconde étape est de tenter de communiquer avec les mémoires SPI. Utilisez le code SPI donné dans le cours. Lisez la documentation de la mémoire, elle
aussi disponible dans le cours, pour récupérer les octets d’identification de ces mémoires. Deux solutions pour communiquer les octets reçus : la liaison
série disponible sur des connecteurs de la carte ou en utilisant les LED de la carte.
Continuez d’écrire les fonctions de gestion de la mémoire. Il vous faut principalement les fonctions de lecture et d’écriture de blocs.
Ecrivez des programmes de tests pour vous assurer que les fonctions de lecture et d’écriture soient fonctionnelles.
Vous pouvez enfin passer à l’utilisation de la bibliothèque LUFA pour implanter un périphérique USB de classe Mass Storage.
Dans le répertoire I2L, créé pour la manette USB, copiez la démonstration de périphérique USB bas niveau MassStorage.
Au niveau du makefile indiquez atmega16u2 comme microcontrôleur, NONE comme platine et restez à 8Mhz.
Il faut ensuite modifier la configuration de la mémoire et les fonctions d’accès à cette mémoire dans le sous-répertoire Lib
du répertoire I2L/MassStorage. Pour vous aider une version modifiée de la démonstration MassStorage est disponible MassStorageI2L.tgz.
Dans cette version, vous n’avez à modifier que les fichiers Lib/DataflashManager.h et Lib/DataflashManager.c.
Une tendance naturelle est de créer un tableau pour stocker une page mémoire mais avec un ATMega16u2 il vaut mieux éviter : ce microcontrôleur
ne possède que 512 octets de mémoire vive. Même allouer un tableau pour une page de 256 octets n’est pas une bonne idée sachant que la bibliothèque
LUFA consomme déjà de la mémoire. Vous écrirez donc les octets un à un dans le tampon d’écriture des mémoires et vous lirez les octets d’une page mémoire un à un.
Pour tester le bon fonctionnement de votre carte, procédez comme suit :
Pour ceux qui souhaitent approfondir la programmation d’un système embarqué, vous pouvez récupérer l’un des mini-robots Polytech’Lille. Vous pouvez dupliquer le projet de la manette série, en effet la carte de contrôle des mini-robots reprend l’architecture ATMega328p couplé à une puce FTDI.
Vous pouvez alors tenter d’implanter, en C, les fonctionnalités suivantes :
Si vous tenez vraiment à utiliser du Python, vous pouvez programmer le robot MaQueen / MicroBit pour réaliser les mêmes fonctions que pour le robot AVR. La fin du cours vous permet d’avoir des indices sur la façon de procéder.
Ce document a été traduit de LATEX par HEVEA