La semaine dernière j'ai découvers l’existence d'un compilateur PASCAL pour les microcontrôleurs PIC 8 bits. Ce compilateur s'appelle PIC micro Pascal ou en abrégé PMP. Lorsque je programme des MCU je le fais en assembleur ou en 'C'. Mais comme j'ai programmé en Turbo Pascal et en Delphi par le passé j'ai décidé de mettre ce compilateur au banc d'essai. Pour ce faire j'ai utilisé la version 2.06 qui est encore en version bêta. J'ai d'ailleurs découvers et rapporté un bug régressif1 dans cette version. Je reparlerai de ce bug plus loin dans cet article.
Présentation
L'initiateur et auteur principal de PMP est Philippe Paternotte, la contribution des autres membres de l'équipe consiste principalement en des librairies. Il a écris ce compilateur en Delphi, il s'agit d'une application Windows. PMP est disponible gratuitement mais le code source ne l'est cependant pas. Il ne s'agit pas simplement d'un compilateur mais aussi d'un IDE basé sur Scintilla.
PMP est un sous-ensemble de Turbo Pascal, les principales restrictions étant les suivantes.
- Ne supporte pas la programmation par objets.
- Les ARRAY ne peuvent avoir qu'une seule dimension.
- Ne supporte pas les fonctions et procédures imbriquées.
- Ne supporte que les RECORD simple, i.e. sans RECORD imbriqués, ni ARRAY ou CASE.
- Ne supporte qu'un seul niveau d'indirection, i.e. v1^m1^x n'est pas supporté.
PMP ne génère pas de code binaire pour les PIC il génère plutôt un fichier source pour l'assembleur MPASM. Donc MPLAB ou MPLABX doit-être installé avant de procéder à l'installation de PMP. Lors de l'installation PMP recherche mpasm.exe et mplink.exe et doit les trouvés pour fonctionner correctement.
Puisque PMP n'est pas intégré à MPLAB(X), pour flasher le microcontrôleur il faut soit utiliser un outil externe comme Pickit 2 programmer ou ce qui est plus malcommode créer un projet dans MPLAB(X) et y importer le fichier source assembleur généré par PMP. Une autre possibilité est d'utiliser les outils GPUTILS. Dans sa version 2.06 PMP supporte les outils GPUTILS. Pour utiliser GPUTILS sous windows il faut installer mingw32.
En ce qui concerne la documentation qui viens avec PMP elle existe sous forme de fichier PDF et d'un fichier d'aide Windows CHM pour l'aide en ligne.
Installation
L'installation est si simple qu'elle se passe d'explications. Au premier lancement l'IDE demande si on veut associé les fichiers avec l'extension .pmp et .pas avec celle-ci. Sous Windows 7 l'installation se fait dans C:\Program Files (x86)\PMP\V2.0.6. Ce dossier contient un dossier examples.
Premier programme
Mon objectif principal pour ce banc d'essai était de voir si PMP fait une bonne optimisation du code. Dans ce but j'ai réécris le code de mon article intitulé chandelle électronique. J'ai recréé exactement la même structure de programme en Pascal que celle que j'avais en assembleur.
Ce programme utilise un PIC10F202. Ce MCU n'est pas du tout conçu pour supporter la programmation dans un langage de haut niveau comme PASCAL, ce qui rend l'optimisation encore plus difficile. Voici donc le code source créé dans l'IDE de PMP.
Comparaison
usage | ASM | PMP | XC8 free |
---|---|---|---|
octets RAM | 9 | 12 | 18 |
code FLASH | 77 | 90 | 94 |
- __BitStack, 1 octet, sert à sauvegarder les status bits pour la donnée qui est dans __STACK__0.
- __STACK__0, 1 octet, utilisé comme variable temporaire.
- __FLAGS, 1 octet, est utilisé pour les variables de type boolean définies dans le programme PASCAL.
var
LED :boolean @ GPIO.2 ;
Signifie que la LED est sur le BIT 2 du SFR GPIO. Ce qui en assembleur est traduis par:
flicker.LED equ 2 flicker.LED ; Bit 2 in GPIO
Puisque __FLAGS n'est pas utilisée dans ce programme le compilateur aurait du optimiser en supprimant cette variable ainsi que l'instruction clrf __FLAGS dans la section d'initialisation.
Bug régressif dans la version 2.06B
A la ligne 49 du code PASCAL on retrouve la ligne:
if (7<rand_val) then rand_val:= rand_val div 2;
Ce n'est pas le code que j'ai écris au départ mais plutôt:
if (rand_val>7) then rand_val:= rand_val div 2;
Mais pour faire la comparaison le compilateur a généré:
movf flicker.rand_val, W ; Get variable in acc
bsf __BitStack, 0 ; Prepare bit ACC (true)
sublw h'07' ; subtract W to constant
Le problème c'est que l'instruction sublw n'existe pas dans le jeux d'instructions des PIC baseline. Mais simplement en inversant la comparaison le code généré deviens:
movlw h'07'
movwf __STACK__0 ; Push byte
movf flicker.rand_val, W ; Get variable in acc
bsf __BitStack, 0 ; Prepare bit ACC (true)
subwf __STACK__0, W ; Compare to stack byte
Lorsqu'on étudie le code assembleur généré par PMP on comprends rapidement pourquoi ça prend 16% de plus d'instructions. Il semble que toutes les comparaisons sur les variables passe par __BitStack et __STACK__0.
Conclusion
Bien sur ce banc d'essai est bref et je vais certainement poursuivre d'autres expérimentations avec PMP mais ça m'a quand même permis de me faire une idée du prix a payer en terme d'utilisation de l'espace de code. Le résultat est meilleur que celui obtenu avec XC8 version gratuite. Donc pour ceux qui préfère le PASCAL au 'C' ça peut-être intéresssant. Personnellement pour un programme PIC qui a moins de 512 instructions je préfèrerai toujours programmer en assembleur. Donc pour tous les PIC10F, PIC12F qui disposent de 256/512 instructions de FLASH.
NOTES:
1) un bug régressif est un bug qui a été introduit dans la version courante alors que la même fonctionnalité fonctionnait correctement dans une version antérieure.
Aucun commentaire:
Publier un commentaire
Remarque : Seuls les membres de ce blogue sont autorisés à publier des commentaires.