dimanche 3 décembre 2017

abeille laborieuse et luciole désespérée

Introduction

Jusqu'à tout récemment je connaissais Silicon Labs pour leur produits radio-fréquences et je ne savais pas qu'ils vendaient aussi des microcontrôleurs. Il vendent entre autre des MCU 8 bits affublés du nom commercial de busy bee que je traduirais par abeille laborieuse plutôt que abeille occupée comme le suggère un certain traducteur en ligne. Il n'existe pas de version DIP de ces microcontrôleurs par contre il existe une version SOIC-16, le EFM8BB10F8G-A-SOIC-16. Très économique, actuellement 0,86cent chez digikey.ca. Évidemment il me fallait aussi un programmeur que Sillicon Labs appelle USB Debug Adapter. Il existe 2 versions de ce débogueur une pour les MCU 8 bits et une autre pour les MCU 32 bits. D'apparence ils sont identiques sauf pour la couleur, à ne pas confondre.

Présentation des Busy Bee

Comme mentionné en introduction il s'agit de MCU1 8 bits. Ils sont basés sur un CPU1 appelé CIP-51 par Silicon Labs. Il s'agit d'une version modernisé et 100% compatible avec le vénérable CPU d'Intel MCS-51 qui était au coeur des premiers microcontrôleurs mise en marché en 1980, les Intel 8051. Intel a abandonné la commercialisation des i8051 il y a longtemps mais de nombreux fournisseurs ont prie le relais. Les Busy Bee sont donc des descendant direct mais plus performant du i8051. Les Busy Bee fonctionnent jusqu'à 25Mhz. Il y a aussi des Universal Bee pour les application USB ainsi que les Laser Bee qui peuvent fonctionner à 72Mhz. Dans cette introduction il sera question du Busy Bee modèle EFM8BB10F8G-A-SOIC16.

Particularités des MCU de la famille Bee

Le CPU a quelques particularités qu'il est bon de souligner par exemple il utilise les 32 premiers octets de la RAM comme 4 banques de 8 registres. Une seule banque est active à la fois. Pour l'assembleur ces registres sont nommés R0 à R7. l'intérêt d'avoir 4 banques se situe au niveau des appels de sous-routines et surtout des interruptions. Le délais de réponse d'une interruption peut-être réduit si elle n'a pas besoin de sauvegarder les registres sur la pile. Elle peu s'éviter cette tâche en utilisant une autre banque de registres. Autre particularité les adresses RAM entre 32 à 48 sont accessibles par certaines instructions au niveau du bit. Pour ces instructions il ne s'agit pas d'octets mais d'un tableau de 128 bits adressable de 0 à 127. Il faut aussi mentionner que même plus économique des Busy Bee possède un multiplicateur en hardware. Je ne connais aucun autre MCU 8 bits à moins de 1$ qui en possède un.

Première étape

Silicon Labs fournis gratuitement l'environnement de développement appelé simpliciy studio. Il faut créer un compte pour le télécharger. Je l'ai installé sur mon laptop qui est en Windows 10 mais comme vous le verrez sur le site il est aussi disponible pour OSX et Linux.

Une fois le logiciel installé on découvre qu'il utilise le compilateur C/C++ de Keil et qu'il faut enregistrer son installation auprès de Silicon Labs pour bénéficier de toutes les fonctionnalités du compilateur gratuitement. Avant de lancer l'IDE2 ne pas oublier de brancher le USB Debug Adapter à l'ordinateur, ainsi il sera vu par l'IDE.

Simplicity studio

Même si cet environnement s'appelle Simplicity Studio ce n'est pas simple à utiliser comme l'IDE de Arduido. Il faut un certain temps pour se familiariser mais heureusement il y a un tour guidé. C'est basé sur l'environnement Eclipse CDT donc plus facile d'accès si vous avez déjà travaillé avec Eclipse. L'environnement utilise le concept de perspective. Selon la tâche à accomplir on passe d'une perspective à l'autre. Dans Symplicity Studio les boutons pour passer d'une perspective à l'autre sont dans la barre d'outils en haut à droite. Il y en a 5, Launcher, Configurator, Simplicity IDE, C/C++ et Debug. Au premier démarrage de l'application on se retrouve dans la perspective Launcher et par la suite dans la perspective visible lors de la fermeture de l'application.

Ma première tentative de créer un projet fut un échec. J'ai eu l'idée de créer un projet vide. Quand Simplicity Studio dit Empty C project il veut vraiment dire projet vide. Lorsqu'on clique avec le bouton droit de la souris sur le nom du projet dans la perspective Simplicity IDE la fenêtre des propriétés du projet s'ouvre. Cette fenêtre contient plusieurs onglets et de nombreuses options dans chaque onglet. Si vous avez choisi empty C project vous devez définir chacun de ces paramètres. Disons que c'est pour les utilisateurs avancés.

On retourne donc à la perspective Launcher et on clique sur le bouton new solution.


On inscris le nom du MCU sur la ligne sous le bouton new solution, EFM8BB10F8G-A-SOIC16. Un dossier jaune apparaît avec le nom du MCU sous lui. On peut renommé le dossier en cliquant bouton droit dessus. Appelons le luciole désespérée

Maintenant on va cliquer sur le bouton new project.

Le nom du MCU qu'on a sélectionné apparaît, on clique sur le bouton next.
On conserve la sélection par défaut soit Simplicity Configurator Program et on appuie encore sur next.
À cette étape on nomme notre projet, les espaces ne sont pas permis dans le nom: luciole_désespérée donc. next
On garde ça tel quel et on clique sur finish. C'est lent avant de passer automatiquement à la perspective Configurator.

Il s'agit d'un outil de configuration visuel. On nous présente le brochage du composant sélectionné pour ce projet. Pour ce projet on va utilisé seulement la broche 8/P1.3. On clique dessus pour la sélectionner. A droite la fenêtre Properties nous permet de configurer cette broche. Pour ce projet on doit avoir la configuration suivante:

On va brancher une LED3 à cette broche on l'a donc nommé ainsi.
En bas de la figure du composant on va maintenant cliquer sur DefaultMode peripherals.
Dans cette nouvelle vue on configure des valeurs par défaut des périphériques. J'ai sélectionné Clock Control et dans les propriétés j'ai choisis pour la propriété Select clock source, Low Frequence Oscillator. Il s'agit d'un oscillateur interne fonctionnant à 80Khz. Pour la propriété Clock Source Divider, j'ai choisi SYSCLK/32.
Ensuite j'ai sélectionné LFOSC
Il s'agit d'activé l'oscillateur et de choisir de diviser sa fréquence par 8 tel qu'indiqué dans la fenêtre properties.
Il nous reste maintenant à désactivé le Watchdog Timer

Problèmes

Lorsqu'on est dans le configurateur et qu'on clique sur PB2 dans le fenêtre Outline la fenêtre properties demeure vide. Hors le registre PB2 est celui qui permet d'activer le crossbar. Le crossbar est le multiplexeur qui permet de sélectionner quel périphérique est relié à quel broche. Il faut qu'il soit activé même si dans cette application on n'utilise aucun périphérique. Heureusement dans la fenêtre Problèmes un avertissement apparaît pour nous dire que le crossbar n'est pas activé. En double cliquant sur cet avertissement la fenêtre propriété du registre PB2 s'affiche et on peut activé le crossbar.

Pour ce projet simple c'est tout ce que nous avons à faire comme configuration mais ça nous évite pas mal de travail de codage manuel. Le configurateur va générer automatiquement le code nécessaire dans le fichier InitDevice.c. Le fichier qui contient l'information de configuration matérielle s'appelle luciole_desespérée.hwconf.

Luciole désespérée

Lorsqu'on travaille pour la première fois avec un MCU il est bon de commencer avec le projet le plus simple qu'on appelle habituellement blinky et qui consiste à faire clignoter une LED. Puisque Silicon Labs a décidé de donner un nom d'insecte à ses MCU, je joue le jeu en nommant mon blinky luciole désespérée. Désespérée parce qu'elle ne se contente pas de clignoter à vitesse régulière mais émet plutôt répétitivement un SOS en morse. Montage super simple pour un projet super simple:

schématique

montage expérimental
Notez que le débogueur n'utilise que 3 fils, GND position 2 sur le connecteur du débogueur, C2CLK position 7 sur le connecteur du débogueur et C2D position 4 sur le connecteur du débogueur. Lors du développement il il n'y a donc que 5 broche du MCU qui sont utilisées, 4=GND,5=+3Volt,6=C2CK,7=C2D et 8=LED. Les broches 6 et 7 sont débranchées lorsque le développement est complété.

Le code source en C

Puisque le configurateur a fait une bonne partie du travail pour nous il ne nous reste que très peu à écrire dans le fichier luciole_desespérée_main.c lui aussi créé par le configurateur.

C'est simple je cré un tableau appelé sos qui contient 4 octets. en fait ce tableau est lu comme une série de bits. Un bit à 0 signifie LED éteinte et un bit à 1 signifie LED allumée. La variable b est incrémentée de 0 à 27 et est utilisée pour lire séquentiellement les bits et lorsque b=28 on réinitialise b à zéro et le cycle recommence. Comme sos est un tableau d'octets on accède le bon octet en divisant b par 8 et le bon bit en prenant le modulo de b par 8. Les bits sont numérotés à l'inverse donc on soustrait le modulo de 7. Le code morse est fait de signaux courts dit et longs dah. Les dah sont 3 fois la longueur des dit. Donc en prenant le signal dit comme unité de temps pour produire un dah il suffit de mettre 3 bits consécutifs à 1. Les 5 derniers bits de la séquence sont a zéro pour produire une pose entre chaque appel.

Pour compiler le projet on utilise le marteau. et pour programmer le MCU avec le fichier binaire on utilise l'icône flèche verte au dessus d'un circuit intégré. Il faut choisir le fichier binaire à programmer.

Le fichier généré utilise 257 octets de mémoire programme et 13 octets de mémoire RAM. On peu demander au compilateur de généner le code assembleur. On va allez dans les propriétés du projet et cocher assembly code dans l'option listing du compilateur Keil.

Maintenant si on recompile on va voir à la fin du fichier luciole_désespérée_main.lst qui se trouve dans le dossier src, le code assembleur. J'ai oublié de mentionner que le configurateur génère 2 configurations une configuration release et une configuration debug. Lorsqu'on modifie les propriétés du projet ça s'applique seulement à la configuration active.

Conclusion

Quelques problèmes se sont présentés lors de cette prise en main de Simplicity Studio.

  • J'ai été capable de créer une variable de type bit mais lorsque j'ai voulu convertir le tableau const char sos[4] en const bit sos[28] le compilateur m'a donné une erreur! Il est possible de créer une variable scalaire de type bit mais pas un vecteur de ce type.
  • J'ai essayé d'imbriquer du code assembleur à l'intérieur du code C sans succès. La simple ligne de code suivante:
    
      asm("nop");
    
    suffie pour déplaire au compilateur qui répond avec l'erreur suivante:
    
    *** ERROR C272 IN LINE 50 OF C:\Users\Jacques\SimplicityStudio\v4_workspace\
    luciole_desespérée\src\luciole_desespérée_main.c:
     '__asm' requires src-control to be active
    
    Je n'ai pas encore trouvé la solution de ce problème.
  • Lorsque j'essaie de déboguer le programme pour suivre l'exécution en pas à pas la session plante, le programmeur s'appelle pourtant USB Debug Adapter!
    Erreur fatale lorsque j'essaie d'utiliser le débogueur

Bien sur je ne suis encore qu'un néophyte avec cet environnement j'ai encore beaucoup à apprendre.

Petite expérience

J'ai décidé de créer une version plus permanente de la luciole désespérée et de l'alimenter avec une pile lithium CR2032. L'objectif est de voir combien de temps va duré la pile. Le premier décembre à 15:00 EST j'ai mis une pile neuve et je surveille la luciole. Je vais compter le nombre de jours qu'elle va clignoter. Vous avez noté que j'ai inséré une résistance de 1Kohm en série avec la LED pour réduire le courant à 1mA environ. De plus le CPU fonctionne à une fréquence à 312,5Hertz pour réduire la consommation de celui-ci à environ 120µA comparativement à environ 5mA à la configuration par défaut qui utilise l'oscillateur haute fréquence avec un diviseur à 8 ce qui donne Fsys de 3,0625Mhz. Vous avez aussi notez qu'à fréquence de 312,5Hertz je n'ai pas besoin d'un boucle de délais pour prolonger la duré entre chaque bit. En fait à cette fréquence la durée entre chaque bit est d'environ 0,12 seconde. Il résulte donc un code morse facile à lire.


Le montage est fait directement au dos du porte pile. Le MCU est collé à celui-ci avec de la colle chaude et la résistance ainsi que la LED sont collés au dos du MCU avec de la colle cyanate (Creazy glue). D'après mes calculs luciole désespérée devrait clignoter environ 20 jours. Je vais mettre à jour cet article lorsque j'aurai le résultat final.

mise à jour 2017/12/04

J'ai trouvé comment inclure du code assembleur dans un fichier en C. Dans la fenêtre Project explorer, dans le dossier src du projet il faut cliquer bouton droit sur le fichier dans lequel on veut inclure du code assembleur et dans le menu surgissant il faut sélectionner Properties.

Dans les options générales il faut cocher l'option Generate assembly SRC from "*.c" file.
Pour inclure du code assembleur dans le fichier en question il encadrer les instructions assembleurs par les directives #pragma asm/#pragma endasm.
Curieusement le fait d'ajouter 2 instructions nop a fait passer la taille du code binaire de 257 octets à 268 octets alors que chacune de ces instructions n'occupe qu'un octet.

J'ai trouvé la solution sur le site de Keil dont l'aide est beaucoup plus complète que l'aide qui viens avec simplicity studio.

mise à jour 2017-12-17

La luciole s'est éteinte au cours de la nuit. Elle aura donc vécue moins de 16 jours. 4 de moins que ce que j'avais estimé sur la base d'une capacité de la pile de 240mah. Possiblement que la pile avait une capacité inférieure à celle utilisée pour mon calcul. La pile utilisé était sans spécification et j'avais utilisé la valeur d'une marque connue.


  1. MCU signifie Micro Controller Unit, tandis que CPU signifie Central Processing Unit. Il ne faut pas confondre les deux. tout MCU a en son coeur un CPU mais ne se limite pas à celui-ci elle possède aussi de la mémoire et des périphériques programmables.
  2. IDE Integrated Development Environment est une application utilisée pour le développement de logiciel qui contient un éditeur de texte mais aussi le support intégré au compilateur ainsi que d'autre outils nécessaire à la réalisation d'un projet. Il permet donc d'écrire le code source, de le compiler, de l'injecté dans le microcontrôleur et aussi de le déboguer sans avoir à sortir de l'environnement. D'où son nom d'environnement intégré.
  3. LED Light Emitting Diode ou Diode Electro Luminescente en français.

Aucun commentaire:

Publier un commentaire