Contacts
Enseignant: Jérôme Collin, responsable (local M-4013, poste 5060)
Support technique supplémentaire: Laurent Tremblay (local M-4011, poste 7181)
Chargés de laboratoire: Section 1: Stefan Cotargasanu (Lundi AM)
Raphaël Tremblay (Mercredi PM)
Section 2: Ely Cheikh Abass (Mardi PM)
Manel Keddam (Jeudi AM)
Section 3: Tristan Rioux (Lundi PM)
Charles De Lafontaine (Jeudi PM)
Section 4: Paul Petibon (Mardi AM)
Julien Bourque (Vendredi AM)
Section 5: Sunnee Chevalier (Mercredi AM)
Meriam Ben Rabia (Vendredi PM)
Section 6: Ghali Chraibi (Mardi soir)
Xavier Caron (Jeudi soir)

Le simulateur SimulIDE et un peu plus...


Le manque d’accès à un montage physique comme une carte mère à microcontrôleur ou simplement le besoin d’accéder à un environnement de débogage avancé justifient souvent la nécessité de se tourner vers la simulation. Pour la série des microcontrôleurs Atmel/Microchip AVR, les possibilités sont nombreuses et intéressantes sous Linux.


SimulIDE


Un microcontrôleur est toujours utilisé dans un système réel où des périphériques externes lui sont branchés. Il existe une solution avec une interface graphique permettent l’ajout de composantes de périphériques et de plus facilement suivre le déroulement de la simulation. SimulIDE est probablement la meilleure option pour parvenir à simuler un système plus complet et de façon flexible. SimulIDE a une très grande collection de composantes qui permet de construire des systèmes élaborés. Ce sera donc l’option privilégiée. SimulIDE possède une interface Qt qui peut être instable parfois (lire erreur de segmentation…), mais les résultats de simulation sont corrects puisque SimAVR est utilisé comme moteur de simulation en arrière-plan sans qu’on s’en aperçoive.


À noter qu’un simulateur avec un nom presque semblable, Simultron, existe également et ressemble à SimulIDE dans son fonctionnement. Il est cependant un peu moins récent et offre beaucoup moins de composantes pouvant être ajoutées. On évitera de l’utiliser, mais il ne faut pas confondre les deux options cependant.


Utilisation de SimulIDE


Après avoir les outils logiciels, on peut démarrer le simulateur:


% /home/<votreCompte>/SimulIDE_0.3.12-SR3/bin/simulide &


Il vous faudra donc adapter le chemin à la réalité de l’endroit où vous avez fait l’extraction lors de l’installation.


Sur la gauche de l’interface graphique, la bibliothèque de pièces est suffisamment garnie pour avoir un réel intérêt pour une simulation élaborée. On retrouve aussi de vrais capteurs de distance (section Micro/Sensors) comme le HC-SR04. On peut avoir sa fiche technique du manufacturier SprakFun et comprendre comment il fonctionne. On a également des portes logiques. SimulIDE reste aussi beaucoup plus près de certaines réalités électriques. La façon de brancher les DEL et les boutons-poussoirs doit respecter les bonnes pratiques ce qui est d’un grand intérêt. On a aussi accès dans la section Meters à des voltmètres et des oscilloscopes.


Les programmeurs de SimulIDE ont aussi prévu des rectangles de texte et des lignes pour permettre de documenter le circuit plus facilement. Bref, on a des moyens de monter un système intéressant! On ne peut cependant utiliser qu’un seul processeur dans le système, mais ce n’est pas une restriction importante.


Le circuit en exemple à la figure 1 plus bas montre un circuit simple de base avec SimulIDE. Le code (souvent appelé firmware dans la documentation de SimulIDE) correspondant au compteur 32 bits en exemple du travail pratique 1 a été chargé dans le ATmega324a. On verra les «sondes» (probes) changer de couleur, mais aussi une petite DEL qui est ici en série avec une petite résistance comme il se doit. Elle change aussi de couleur (si la résistance n’est pas trop élevée!) ce qui est conforme au résultat attendu. Noter aussi le bouton jaune ou rouge au haut de la fenêtre vers le centre et qui permet de démarrer ou arrêter la simulation en cours.


Le processeur choisi ici est le atmega324a qui est identique au atmega324pa sauf pour certaines réalités électriques de très bas niveau. Mais au niveau logique et de simulation numérique, les deux sont identiques.




Figure 1: aperçu de SimulIDE avec un circuit simple


Bien prendre en note également qu’il faut cliquer avec le bouton droit de la souri sur le processeur AVR instancié pour charger le code à exécuter (load firmware) et qu’il faut prendre le fichier exécutable en format .hex généré par le Makefile du cours. Il faut aller dans «properties» du même menu pour changer la vitesse d’exécution qui est de 16 MHz par défaut et la placer à 8MHz.


Le circuit construit avec SimulIDE peut être sauvegardé dans un fichier dont l’extension est .simu. Il s’agit d’un fichier ASCII respectant le format XML qu’on peut donc éditer ou au moins regarder pour avoir une idée de ce qu’il contient. À la rigueur, un tel fichier aurait pu être également un fichier VHDL (comme en INF1500) puisqu’il s’agit d’une liste de pièces interconnectées (netlist) correspondant au matériel. Les icônes à gauche du bouton d’arrêt/démarrage de la simulation permettent de gérer le fichier de circuit (ouvrir, sauvegarder, etc.)


Le code, quant à lui, est celui des AVR sans modifications et marcherait avec la vraie puce physique directement.


Pour les autres aspects de l’utilisation de SimulIDE, on trouve beaucoup de vidéos sur youTube à commencer par celle-ci https://www.youtube.com/watch?v=k6Eu72MWyyQ. Toutefois, on peut arriver à maîtriser l’outil assez rapidement par la pratique, tout simplement. Aussi, le simulateur vient avec un éditeur de code intégré, mais il est préférable de manipuler son code avec l’éditeur VS-Code à l’extérieur et de seulement charger l’exécutable dans le ATMega324a pour la simulation.


Autres options plus complexes (pas nécessaires pour le cours)


L’option du logiciel SimulAVR a longtemps été la seule option pour la simulation sous Linux des microcontrôleurs AVR mais n’est plus réellement maintenue de façon sérieuse par la communauté. SimAVR est maintenant le logiciel le plus utilisé. Il faudra donc faire attention à ne pas confondre les deux malgré des noms très semblables, car ils sont différents. SimAVR est un simulateur peu convivial à utiliser et qui doit être complété par d’autres programmes pour former une solution complète. Par contre, il permet d’obtenir les signaux au plus bas niveau des opérations du processeur.


SimAVR permet de charger un programme déjà compilé pour un modèle d’AVR précisé et d’en faire l’exécution sous une plate-forme Linux. Il faudra faire quelques ajustements au code pour aider à la simulation. De manière spécifique, il faudra ajouter quelques lignes de code pour générer des signaux dans un fichier texte généré par le simulateur pour pouvoir les observer avec le visualisateur GTKWave. SimAVR s’invoque sur la ligne de commande Linux et n’a pas, à proprement parlé, d’interface graphique.


Le fichier texte de type .VCD obtenu en fin de simulation peut devenir de taille assez importante puisqu’il contient la valeur des signaux spécifiés pour chaque cycle d’horloge du processeur. Il faudra en tenir compte et essayer d’utiliser ces traces de signaux de façon judicieuse et parcimonieuse. GTKWave a une interface dont il faut savoir quelques petites subtilités pour éviter les surprises au départ.


En cours de simulation, l’utilisation du débogueur GDB est possible, mais il faudra utiliser la variante pour compilation croisée avr-gdb. Le débogueur avr-gdb se connectera à SimulAVR par TCP avec un socket Unix local. On pourra donc suivre l’évolution du programme en ajoutant des points d’arrêt (breakpoints) et en affichant les valeurs des variables, mais aussi de différents registres internes du microcontrôleur, ce qui peut être très utile. GDB possède quelques options pour ce qui est de l’interface graphique, mais invoquer avr-gdb avec l’option --tui suffit en général à une utilisation convenable puisque, comme le nom l’indique, une interface texte plus élaborée sera fournie.


Un microcontrôleur est toujours utilisé dans un système réel où des périphériques externes lui sont branchés. Bien entendu, il est toujours possible de forcer des valeurs (surtout en entrée sur les registres PINx de l’AVR) pour contourner le problème et bien simuler l’ensemble. Évidemment, ce travail peut devenir assez ardu et très long, mais il peut s’avérer nécessaire dans certaines situations, mais on voudra en général le limité le plus possible.


Compiler pour SimAVR et GTKWave (la méthode un peu compliquée...)


SimAVR accepte du code tel que compilé normalement pour la puce physique elle-même, tout comme avr-gdb d’ailleurs. Le seul vrai petit problème arrive lorsqu’on doit obtenir les signaux qui forment une trace de l’exécution de la simulation et qui devront être visualisés avec GTKWave une fois la simulation terminée. Il faut alors, à même le code, préciser dans quel fichier écrire les résultats de simulation ainsi que la liste des signaux en observation. Ces directives doivent impérativement se retrouver dans un code C strict, et non dans un fichier avec du code C++. Les deux langages, bien qu’ayant une base commune élargie, n’ont pas exactement les mêmes règles pour certains aspects, surtout pour ce qui concerne les appels de fonctions. L’ensemble de la démarche est bien expliquée au point 1 de l’article du Magazine Linux France Développer sur microcontrôleur sans microcontrôleur: les émulateurs.


Le plus simple est donc de regrouper dans un court fichier appelé ici sepupSim.c les directives pour la génération des signaux de simulation. Notez que l’extension .c est importante et doit être préservée pour assurer une compilation en langage C par le compilateur. Si vous êtes un mordu de ces questions, l’explication compliquée est disponible. Quelques autres directives autres que celles montrées ici se trouvent décrite directement dans /usr/include/simavr/avc/avr_mcu_section.h directement. Pour aller directement à l’essentiel, on peut s’en tenir à ce qui suit en acceptant d’y ajouter ou de retirer ce qui convient comme signaux désirés en sortie (à noter qu’on peut ajouter des registres internes du microcontrôleur ce qui peut être très intéressant) :




Figure 1: les directives de simulation pour SimAVR et GTKWave


Dans ce fichier, il y aura une fonction «main» qui aura comme rôle d’appeler ce qui était jusqu’à maintenant le «main» par une légère modification. Le code du compteur 32 bits de la semaine subit donc quelques modifications. Les modifications seront aux lignes 12 et 14. La ligne 12 précise au compilateur que la fonction «monMain» devra être appelée avec les normes du langage C (stricte), donc depuis setupSim.c. La ligne 14 change le nom du «main» par «monMain» pour terminer le lien d’appel correctement.




Figure 2: modification au code du compteur 32 bits


Il faudra faire deux modifications au Makefile pour s’ajuster à cette réalité:



Après avoir recompilé le code de manière habituelle (à noter que la commande «make install» a complètement perdu de son sens…), on peut invoquer le simulateur:


% simavr -f 8000000 -m atmega324a simExemple.elf


On notera bien entendu les arguments qui spécifient la fréquence d’horloge et le modèle de processeur. À noter le «a» et on le «pa» à la fin du modèle. L’un et l’autre ne pouvant être distingué que par des caractéristiques physiques au niveau électrique sans que cela ne change la simulation au niveau numérique.


La simulation devrait se terminer si le programme se termine. Un «CTRL-C» au terminal peut aussi y mettre fin. Un fichier au nom de gtkwave_trace.vcd devrait être visible maintenant dans le répertoire courant. On peut procéder à la visualisation:


% gtkwave gtkwave_trace.vcd


L’interface de GTKWave a ceci de surprenant: les signaux n’apparaissent naturellement dans la portion de droite. Il faut plutôt double-cliquer sur «logic» à gauche. Cette action affichera la liste des signaux disponibles un peu plus bas. Il faudra sélectionner chacun avec la souri puis appuyer sur «Insert» tout au bas et toujours à gauche pour voir le signal sur la portion de droite. Une fois tous les signaux en place, on pourra jouer avec les boutons «Zoom In», «Zoom Out» et «Zoom Fit» (juste sur la droite des deux autres) pour ajuster l’affichage de façon appropriée. L’emploi du curseur, de l’ascenseur (scroller) horizontal et des autres options sont également à considérer.




Figure 3: Analyse des signaux avec GTKWave


GDB


L’analyse des signaux avec GTKWave a ses limites. Premièrement, l’ensemble des données peut devenir passablement volumineux puisque la simulation y ajouter constamment de nouvelles valeurs. De plus, on doit pouvoir préciser des valeurs en entrée à différents moments pour exercer certaines portions de code. GDB peut aider à contrôler la simulation de façon plus directe comme l’explique l’article Debugging ATtiny85 Code, Part 1: SimAVR and GDB.


Avant de lancer GDB, il faut que la simulation débute et qu’on rajoute un argument «-à SimAVR pour lui préciser que la simulation sera sous le contrôle du débogueur. Plus précisément, SimAVR ouvrira alors un port de communication local (unix socket) pour communiquer avec GDB. Le numéro de ce port est 1234 (hé oui, très original…)


% simavr -g -f 8000000 -m atmega324a simExemple.elf


GDB peut être démarré par la suite dans un autre terminal. Donc, selon ce qui vous convient, vous faites l’une des trois choses suivantes:


% avr-gdb –tui

% ddd --debugger avr-gdb

% gdbfrontend --gdb-executable=avr-gdb


Peu importe la manière dont l’arrivée dans avr-gdb se fera, il faudra taper les deux commandes de base suivantes pour se connecter au simulateur.


(gdb) file simExemple.elf

(gdb) target remote :1234


Un bon article pour faire les premiers pas avec GDB et les AVR reste Debugging ATtyny85 Code, Part 1: SimAVR and GDB aux sections «Start simavr» et les suivantes. À note que je n’ai pas eu besoin de la commande «load» après «file» et «target» tel que mentionné dans l’article. Par contre, le reste de l’article demeure une très bonne introduction aux commandes les plus simples de GDB pour commencer tout en montrant comment travailler dans les situations les plus habituelles. L’avantage avec avr-gdb est qu’on est capable de forcer des valeurs, tout particulièrement sur les PINx en entrée du microcontrôleur et on peut ainsi simuler des actions réelles, comme l’appui sur un bouton-poussoir par exemple, et de voir le résultat dans l’exécution du code. On peut donc utiliser une expression comme celle-ci:


(gdb) set PINB = PINB | 1<<PIN_USB


De telles commandes, combinées à d'autres commandes de contrôle de l’exécution permettent d’arriver à simuler complètement le déroulement d’un code pour AVR.


Bien entendu, en arrière-plan, SimAVR continue d’exécuter les instructions et peut continuer de générer des traces pour GTKWave. Cette combinaison peut d’ailleurs aider grandement à la mise au point d’un programme.


Le problème de l’utilisation de GDB reste la difficulté à modeler le comportement réel de périphériques plus complexes dans une situation plus représentative de l’utilisation d’un système complet comme un robot. Des simulateurs utilisant SimAVR en arrière-plan peuvent permettre de contourner ce problème. SimulIDE en est un et c’est pourquoi son utilisation est privilégiée plutôt que la combinaison SimAVR-GTKWave-GDB. Toutefois, si des signaux précis doivent être analysés, la combinaison des trois outils devra être utilisée.