Vous êtes sur la page 1sur 32

Les microcontrleurs PIC programms

en Objective Caml
Benot Vaugon1 , Philippe Wang 2 , Emmanuel Chailloux 2
1: Universit Pierre et Marie Curie (Paris 6)
Benoit.Vaugon@etu.upmc.fr
2: Laboratoire dinformatique de Paris 6 (LIP6), CNRS UMR 7606,
Universit Pierre et Marie Curie (Paris 6)
Philippe.Wang@lip6.fr
Emmanuel.Chailloux@lip6.fr
Rsum. Les microcontrleurs PIC sont des circuits intgrs programmables. Ils se distinguent par leurs bas prix et leur faible consommation nergtique. Les principaux langages de programmation disponibles sont lassembleur PIC et des sous-ensembles des langages C et Basic. Ils demandent souvent au programmeur de se proccuper mticuleusement
des limitations du matriel. Dans ces conditions, il est souvent difficile dexprimer des algorithmes complexes utilisant des allocations dynamiques.
Nous introduisons Objective Caml, un langage applicatif multiparadigme, allocation dynamique et rcupration automatique de mmoire. Lutilisation dun langage de haut niveau sur ces architectures apporte la possibilit dy excuter des algorithmes bien plus complexes tout en assouplissant fortement les contraintes de programmation, notamment parce
que la gestion de la trs petite quantit de mmoire est alors automatise. Cela facilite le
processus de mise au point tout en garantissant un haut niveau de sret dexcution.
Pour ce faire, nous introduisons une machine virtuelle Objective Caml dveloppe en assembleur PIC18, selon les spcifications de la machine de rfrence distribue par lINRIA.
Celle-ci permet dutiliser la totalit du langage Objective Caml sans aucune restriction. Les
performances obtenues sont par ailleurs trs satisfaisantes et soutiennent la pertinence de
lapproche adopte.
Mots-Cls : Microcontrleur PIC18, Objective Caml, Machine Virtuelle

178

JFLA 2011

1. Introduction
Lors de la conception dun circuit lectronique, si celui-ci ncessite une unit de calcul, limplantation de celle-ci est soit un
assemblage de portes logiques (programmation matrielle), soit
un microcontrleur (programmation logicielle). Les premiers ont
un trs faible cot de fabrication sils sont produits en trs grande
quantit. Lavantage des seconds est quils sont de toute manire
fabriqus en masse afin de les rendre le plus accessible possible
en rduisant au maximum leur prix, et il suffit dy embarquer un
logiciel pour quils puissent accomplir une tche spcifique.
Les PIC [1, 8] sont des microcontrleurs programmables disponibles bas prix, commercialiss par la socit Microchip1 . Leur
facilit dintgration dans un petit circuit lectronique fait quils
sont notamment trs utiliss par les bricoleurs en lectronique ,
en plus des utilisateurs industriels (e.g., robots lectromnagers).
Ils intgrent une unit de calcul, une mmoire de calcul volatile
et une mmoire de masse non volatile. Toutes trois ont une capacit trs limite, en comparaison avec ce qui se fait par ailleurs
en matriel informatique grand public . En effet, avec lunit
de calcul cadence une frquence de quelques MHz, selon les
sries et modles adopts, le nombre dinstructions excutes par
seconde varie entre 1 et 40 millions. La mmoire de calcul a une
capacit incluse entre 16o et 128ko. La mmoire de masse a une
capacit comprise entre moins dun ko et 512 ko. La taille des
mots machine dpend des sries de PIC ; celles disponibles sont
le plus souvent 8 bits (sries PIC10, PIC12, PIC16 et PIC18), 16
bits (sries PIC24, PIC30, PIC33) ou 32 bits (srie PIC32) pour les
plus rcents et puissants. On peut remarquer que cette capacit
de calcul est comparable celles de microprocesseurs des annes
1980 (e.g., Intel 8080, Zilog Z80).
Ces puces sont habituellement programmes en assembleur directement ou bien laide dun sous-ensemble de Basic ou C. Cependant, le jeu dinstructions assez particulier des PIC rend la gnration de code PIC assez difficile. Par exemple, il ny a pas dins1. http://www.microchip.com

Les PIC programms en OCaml

179

truction matrielle pour la division de nombres entiers sur la srie


PIC18, et les instructions pour la multiplication sont absentes sur
les sries antrieurs. De nombreux compilateurs napportent que
des commodits minimales tant au niveau des constructions de
langage prises en charge quau niveau de la bibliothque standard.
La faible quantit de ressources rend leur programmation assez
dlicate et parfois trs ardue, notamment lorsquil sagit dutiliser
des algorithmes complexes sur des structures de donnes dynamiques.
Nous proposons dutiliser un langage applicatif riche, non
seulement fonctionnel mais aussi modulaire, impratif et objets, statiquement typ, gestion de mmoire automatique, afin
de faciliter la programmation de telles puces et de rendre les logiciels plus srs. Nous introduisons ainsi Objective Caml [7] dans le
monde des outils ddis la programmation des microcontrleurs
PIC.
Objective Caml est dvelopp et distribu par lINRIA avec deux
compilateurs. Le premier met du code-octet pour une machine
virtuelle, appele ZAM [6] par la suite, incluse dans la distribution. Le second met du code pour le processeur matriel de
la machine relle qui hbergera les programmes ainsi compils.
Les deux compilateurs partagent une bibliothque dexcution implante en C.
En se basant sur lexistant, pour pouvoir excuter sur un PIC un
programme crit en Objective Caml, nous avons eu choisir entre
complter le gnrateur de code du compilateur natif pour cibler
les machines PIC ou bien fournir une machine virtuelle fonctionnant sur PIC pour interprter les programmes compils en codeoctet.
Modifier lun des deux compilateurs implique un travail de
maintenance consquent a posteriori du fait de lvolution de la
distribution dObjective Caml. Et lmission de code PIC tant assez difficile, lide dtendre le compilateur dans cette optique a
t assez vite abandonne, au profit de limplantation dune machine virtuelle sur PIC pour Objective Caml.

180

JFLA 2011

Cet article prsente notre ralisation, appele OCAPIC2 , qui rpond la question : comment faire tenir une machine virtuelle
pour Objective Caml sur un PIC ?
Dans la suite de cet article, nous commenons par dcrire les
caractristiques des microcontrleurs PIC plus en dtail afin de
mieux comprendre la problmatique des contraintes du matriel.
Puis, les sections 3 et 4 prsentent la machine virtuelle Objective
Caml et son implantation sur un PIC. La section 5 propose plusieurs moyens de rduction de la taille des programmes, afin de
pouvoir en embarquer davantage sur les PIC. Lenvironnement de
dveloppement fourni avec la distribution est ensuite dtaill en
section 6. Puis, une tude de performances est dcrite en section
7. Enfin, nous discutons des diffrentes exprimentations de programmation de PIC dans des langages de haut niveau pour les
comparer avec la ntre en section 8 et concluons sur notre exprience en section 9.
2. Les microcontrleurs PIC
2.1. Les microcontrleurs
Les microcontrleurs sont des circuits intgrs programmables.
Ils regroupent, au sein dune mme puce, les diffrents lments
que lon trouve habituellement dans lunit centrale dun ordinateur personnel. En particulier, ils contiennent une unit de calcul, diffrentes mmoires volatiles et non volatiles, ainsi quun ensemble dinterfaces internes facilitant la communication avec
le monde extrieur. Ils sont conus pour tre programms par un
ordinateur, puis placs dans un circuit lectronique dans lequel ils
effectuent un travail plus ou moins complexe. Aprs programmation, ils peuvent fonctionner indpendamment de tout ordinateur.
Leurs principaux domaines dapplication sont lindustrie pour
la fabrication de machines outils, la domotique (machines caf,
appareils lectromnagers, etc.), et llectronique grand public.
2. http://www.algo-prog.info/ocaml_for_pic/

Les PIC programms en OCaml

181

Diffrents exemples dapplications sont dtaills dans des revues


dlectronique, comme par exemple la revue Elektor3 . Leur production en grande srie fait baisser leur prix de revient (en gnral de lordre de quelques dollars amricains). Ceci les rend intressants pour les amateurs comme pour les industriels.
Ils peuvent dans beaucoup de cas remplacer les architectures
ddies, cest--dire les circuits intgrs conus matriellement
pour une tche prcise. Il est en effet gnralement plus facile de
concevoir et de maintenir un logiciel quun circuit lectronique.
Les architectures ddies sont cependant parfois ncessaires pour
des raisons de performances.
Diffrentes familles de microcontrleurs sont disponibles sur le
march. Parmi les plus connus, on trouve le 6800 et ses drivs
(comme le 68HC11) produits lorigine par la socit Motorola
puis par Freescale Semiconductor ; les microcontrleurs Philips
(en particulier les sries de P87 et P89) ; ainsi que les PIC de la
socit Microchip.
2.2. Les PIC
Les PIC forment une famille de microcontrleurs dvelopps
par la socit Microchip. Il existe plusieurs centaines de modles
regroups dans diffrentes sries (PIC16, PIC18, etc.) en fonction
de leurs caractristiques. Leurs prix varient entre approximativement 0,30 et 9 dollars amricains daprs le site de Microchip.
Chaque srie de PIC possde son propre langage assembleur.
Les programmes crits pour une srie ne sont en gnral pas compatibles pour les autres. Cependant, il est souvent facile de porter
de manire quasi systmatique les programmes dune srie de numro faible vers une srie de numro plus grand.
Les PIC possdent une architecture RISC. Leurs jeux dinstructions se composent dinstructions arithmtiques et logiques, dinstructions de branchement, et de quelques instructions spciales
3. http://www.elektor.fr/

182

JFLA 2011

permettant par exemple daccder la mmoire contenant le programme. Voici un petit extrait de code assembleur PIC :
1
2
3
4
5
6
7
8

exemple_de_code :
tblrd*+
movf
TABLAT , W
addwf
FSR0L , W
rcall
SOUS_PRGM
btfsc
STATUS , C
incf
FSR0H , F
return

;
;
;
;
;
;
;
;

label
lecture dans la mmoire flash
transfert dun registre vers W
addition du registre FSR0L et W
appel au sous programme SOUS_PRGM
saut de linstr suivante si CARRY =0
incrmentation de FSR0H
retour l appelant

Les PIC possdent en gnral quatre mmoires distinctes. Lune


est une mmoire non-volatile utilisant la technologie flash, appele mmoire programme . Comme son nom lindique, elle
contient le programme xcuter. La programmation dun PIC
consiste donc en lcriture du programme dans cette mmoire.
Elle est en gnral rinscriptible de 1 000 100 000 fois selon les
PIC.
Pour stocker dynamiquement des informations, les PIC utilisent
une mmoire constitue uniquement de registres. Le nombre de
registres varie selon les PIC entre quelques dizaines, jusqu plus
dune centaine de milliers. Ils sont accessibles directement par
lunit de calcul, en lecture et en criture.
Dans les anciennes sries de PIC, la mmoire programme nest
pas accessible en criture depuis le PIC, mais uniquement la
programmation. Il est cependant parfois ncessaire de stocker des
informations devant tre conserves lorsque le PIC nest plus aliment lectriquement. Pour ce faire, certains PIC possdent une
EEPROM4 de faible capacit, accessible en lecture et en criture
depuis le PIC. Ces mmoires sont en gnral rinscriptibles entre
1 000 000 et 10 000 000 de fois.
Les PIC possdent un mcanisme dappel de procdure. Il est
bas sur les instructions assembleur call et return permettant
respectivement dappeler une procdure et de retourner lappelant. Cependant, pour la plupart des sries de PIC, la taille des
4. Electrically-Erasable Programmable Read-Only Memory ou mmoire morte programmable effaable lectriquement.

Les PIC programms en OCaml

183

registres ne suffit pas pour y stocker des adresses de la mmoire


programme. Les adresses de retour sont alors stockes dans une
pile particulire. La mmoire constituant cette pile est organise
en mots dont la taille ne dpend pas de larchitecture de lunit de
calcul, mais de la taille de la mmoire programme. La taille de ces
mots est par exemple de 14 bits pour les PIC de la srie PIC16.
Le tableau 1 donne, pour chaque srie de PIC, les valeurs extrmes de leurs principales caractristiques techniques.
Famille
PIC10
PIC12
PIC16
PIC18
PIC24F
PIC24H
dsPIC30
dsPIC33
PIC32

Archi[bit]
8
8
8
8
16
16
16
16
32

Flash[ko]
.375 .75
.75 7
.75 28
4 128
4 256
12 256
6 144
6 256
32 512

Registres[o]
16 24
25 256
25 1536
256 4096
512 98304
1024 16384
256 8192
256 30720
8192 131072

EEPROM[o]
0
0 256
0 256
0 1024
0 512
0
0 4096
0
0

MIPS
12
18
48
8 16
16
40
30
30
10 20

Tableau 1 Tableau comparatif des diffrentes sries de PIC


Les PIC ne possdent pas dinstructions spcifiques pour communiquer avec lextrieur, ni pour configurer les interfaces internes. Ceci se fait en lisant et en crivant dans des registres particuliers du PIC. Les pattes du PIC sont regroupes en ports , et
chaque port correspond un registre du PIC. Par exemple, pour
appliquer une tension de 5V sur la patte numro 3 du port B, il
suffit de mettre 1 le bit numro 3 du registre PORTB. Ceci peut
se faire par linstruction assembleur :
1

bsf

PORTB , 3

De mme, pour configurer linterface EUSART5 permettant de


communiquer avec un port srie dun ordinateur, il suffit dcrire
dans le registre TXSTA.
Lune des difficults du portage dun langage de haut niveau
comme Objective Caml sur PIC est de permettre au programmeur
5. Enhanced Universal Synchronous/Asynchronous Receiver Transmitter.

184

JFLA 2011

deffectuer ce genre doprations aussi facilement quen assembleur, sans pour autant casser les principes du langage. Il faut
alors donner au programmeur des moyens lgants et performants deffectuer des oprations dont la smantique est une criture dans la mmoire une adresse fixe.
2.3. Le PIC18F4620
Dans notre ralisation, le code assembleur a t crit pour la
srie PIC18. Cette srie a la particularit davoir un jeu dinstructions tendu cr lorigine pour faciliter la compilation
depuis le langage C. Ces instructions nous ont en particulier permis de faciliter la gestion de la pile Objective Caml et damliorer
significativement les performances.
Plus prcisment, le PIC sur lequel les tests ont t effectus
est le PIC18F4620. Il a t choisi principalement pour son grand
nombre de registres. En effet, la quantit de mmoire dynamique
est le facteur qui nous a pos le plus de difficults pour porter
des programmes Objective Caml sur PIC. Ses principales caractristiques sont prsentes dans le tableau 2.
Architecture
Mmoire flash
Registres
EEPROM
MIPS
Entres/sorties

8 bits
64 ko
3968 o
1024 o
10
36 broches

Tableau 2 Caractristiques du PIC18F4620

3. La machine virtuelle Objective Caml


La machine virtuelle Objective Caml est une machine pile.
Elle permet dexcuter le code-octet gnr par le compilateur
ocamlc. Un tel excutable contient principalement trois sections :
CODE : contient le code-octet.

Les PIC programms en OCaml

185

DATA : contient la srialisation dun tableau de variables globales. Ce tableau contient des valeurs prcalcules par le compilateur (par exemple des flottants, des chanes de caractres, des
exceptions), ainsi que des cases non-initialises qui seront affectes lexcution.
PRIM : contient les noms de fonctions externes. Il associe un
numro chaque fonction externe pour y accder rapidement.
Dautres sections sont parfois prsentes. Elles permettent de reprer des bibliothques dynamiques (DLLS et DLPT), ajouter des
informations de dbogage (DBUG), ou autre. Il est difficile de leur
donner un sens sur PIC, nous avons donc dcid de les ignorer
lors du portage.
linitialisation, la machine virtuelle dsrialise le tableau des
variables globales, associe chaque fonction externe avec son numro, et dmarre lexcution du code-octet. Lors de lexcution,
elle gre diffrents lments :
stack : une pile dvaluation.
accu : un accumulateur pouvant tre vu comme le sommet de
la pile.
heap : un tas contenant les valeurs alloues.
code : un segment contenant le code-octet excuter.
pc : un compteur ordinal pointant sur le segment contenant
le code-octet.
data : un tableau contenant les valeurs des variables globales.
env : une variable pointant, lors de lvaluation du corps dune
fonction, vers la fermeture associe. Celle-ci contient entre autres
les valeurs des variables libres du corps de la fonction, ce qui permet dy accder rapidement.
trapSp : un registre stockant la position dans la pile du dernier
rattrapeur dexception pos.
extraArgs : un compteur stockant, lors dun appel de fonction,
le nombre darguments passs. Il est utilis pour reprer les appels
partiels.

186

JFLA 2011

Il existe 146 instructions de code-octet diffrentes. Cependant,


60% sont des alias permettant de factoriser le code et damliorer
la vitesse dexcution. Une instruction de code-octet est compose
dun identifiant dinstruction (opcode) et ventuellement darguments. Dans lexcutable gnr par ocamlc, chaque opcode et
chaque argument sont cods sur quatre octets. Ces instructions
peuvent tre groupes en sept catgories :
calculs arithmtiques et logiques.
contrle : branchements conditionnels et inconditionnels.
gestion de la mmoire : accs la pile et au tas, allocations
dynamiques.
gestion des fermetures : crations de fermetures, appels et
retours de fonctions.
gestion des exceptions : poses de rattrapeurs, lancements
dexceptions.
gestion des objets : appels de mthodes.
gestion des appels aux fonctions externes.
On peut se rfrer la documentation de X. Clerc concernant le
projet Cadmium [3] pour le dtail de chaque instruction.
4. Limplantation de la machine virtuelle Objective Caml sur
PIC
Cette section dcrit limplantation que nous avons ralise pour
permettre dexcuter des programmes Objective Caml sur les PIC.
Elle dtaille les techniques que nous avons utilises pour implanter linterprte de code-octet et la bibliothque dexcution, ainsi
quun ensemble dalgorithmes permettant de transformer le codeoctet pour amliorer les performances.
4.1. La chane de production
Le schma de la figure 1 dcrit la chane de production du code
source Objective Caml jusquau fichier hexadcimal transfrer

Les PIC programms en OCaml

187

sur le PIC. Le programme Objective Caml est dabord compil


en code-octet grce au compilateur standard ocamlc. Le code gnr est ensuite nettoy (par un algorithme dlimination de code
mort) et compress. Le binaire obtenu est alors li avec linterprte et la bibliothque dexcution, tous deux crits en assembleur. Le programme ainsi obtenu est assembl et transfr sur le
PIC.

Figure 1 Chane de production

4.2. Reprsentation des donnes


4.2.1. Les valeurs Objective Caml
Objective Caml utilise une reprsentation uniforme des donnes o chaque valeur est code sur un nombre fixe doctets. Une
valeur peut tre, soit une valeur immdiate (entier, boolen, etc.),
soit ladresse dun bloc allou dans le tas Objective Caml, soit
une adresse en dehors du tas. Certaines primitives du langage
(e.g., (Pervasives.compare: a -> a -> bool) pour la comparaison en
profondeur de valeurs) et le ramasse-miette (garbage collector ou
GC par la suite) ont besoin de parcourir le graphe mmoire. Il
est donc ncessaire de pouvoir distinguer, pour chaque valeur, sil
sagit dune adresse ou dune valeur immdiate. Pour ce faire, nous
utilisons le bit de poids faible des valeurs comme cela est fait dans
ocamlrun. Les adresses tant paires, leurs bits de poids faible est

188

JFLA 2011

0. Il suffit donc de coder toutes les valeurs immdiates avec un bit


de poids faible de 1. Par exemple, le boolen false est cod 0b1,
le boolen true 0b11, et les entiers sous la forme 2 n + 1.
Le nombre doctets utilis pour coder une valeur correspond
habituellement larchitecture de la machine relle sur laquelle la
machine virtuelle sexcute (4 octets sur une architecture 32 bits
et 8 sur architecture 64 bits). Cependant, les PIC utiliss ici ont
une architecture 8 bits et la taille de la mmoire dynamique est
de plusieurs ko. Il est donc impossible de reprsenter une adresse
dans la mmoire dynamique sur un seul registre. De plus, avec
des valeurs codes sur un nombre impair doctets, les adresses
nauraient pas toutes t paires. Le choix qui a t fait est donc de
coder les valeurs Objective Caml dans un PIC sur deux registres,
soit 16 bits.
Ceci implique diffrentes restrictions. Notamment les entiers
ne sont reprsents que sur 15 bits. Ils sont donc compris entre
-16 384 et 16 383. De plus, il est ncessaire de pouvoir coder une
adresse de code dans une valeur, par exemple dans une fermeture.
La taille du code-octet est donc limite 64ko.
4.2.2. Les blocs
Dans la machine virtuelle Objective Caml, toutes les valeurs
prsentes dans le tas sont regroupes dans des blocs. Un bloc est
un tableau de donnes auquel on a ajout un en-tte. Len-tte
contient habituellement trois champs : le champ size contenant
la taille du bloc, le champ color utilis par le gestionnaire mmoire pour marquer les blocs, et le champ tag donnant des informations sur le contenu du bloc. Certains blocs, comme les fermetures, contiennent des valeurs et doivent tre parcourus par le
gestionnaire mmoire. Dautres, comme les chanes de caractres,
contiennent de simples donnes brutes et ne doivent pas tre analyss par le ramasse-miette. Le tag permet de distinguer les blocs
analyser des autres.
Dans la reprsentation choisie ici, les en-ttes sont codes sur
deux octets et ne contiennent pas de champ color. Le ramassemiette utilise une autre technique pour marquer les blocs. Celle-ci

Les PIC programms en OCaml

189

est explique dans la section 4.4. Le champ tag est cod sur un
octet comme dans la reprsentation standard pour des raisons de
compatibilit. Le champ size est donc lui aussi reprsent sur un
octet, ce qui implique que les blocs contiennent au maximum 255
lments.
4.2.3. Les fermetures
Une fermeture est un bloc particulier servant reprsenter une
valeur fonctionnelle. Il y a deux types de fermetures : les fermetures simples et les fermetures rcursives. Les fermetures rcursives sont cres lorsquon dclare des fonctions rcursives ou
mutuellement rcursives. Pour tout autre dclaration ou lors dun
appel partiel de fonction, une fermeture simple est cree.
Une fermeture simple est un bloc ayant pour tag 247, pour
premier lment le pointeur de code, et pour autres lments lenvironnement. Lenvironnement correspond aux valeurs associes
aux variables libres dans le corps de la fonction, et aux paramtres
dj passs la fonction en cas dappel partiel.
La structure des fermetures rcursives est plus complique que
celle des fermetures simples. Il sagit de blocs contenant dautres
blocs. Les blocs internes sont des blocs ayant le tag infixe (249).
Le bloc externe a le mme tag quune fermeture simple (247).
Lenvironnement est commun toutes les fermetures (les internes
+ lexterne) et est stock la fin du bloc externe.
Voici la structure dune fermeture rcursive :

Le ramasse-miettes doit grer les blocs internes dune manire


particulire. En effet, lorsquil arrive sur un bloc ayant le tag infixe
(249), il ne doit pas simplement copier le bloc interne mais tout
le bloc externe. Pour retrouver le bloc externe, il utilise le champ
size du bloc infixe. Celui ci ne contient pas la taille du bloc infixe
mais la distance entre le bloc interne et le dbut du bloc externe.

190

JFLA 2011

4.3. Gestion des appels externes


Les appels externes sont des appels, depuis le programme Objective Caml, des fonctions crites lorigine en C. Ici, ces appels se font des fonctions crites en assembleur. Il reste toujours
possible dinterfacer le programme Objective Caml avec nimporte
quel langage. Pour ce faire, il est ncessaire de compiler les fonctions externes crites dans ce langage en assembleur ainsi que
davoir un contrle sur le label gnr par le compilateur au dbut du code assembleur de la fonction externe.
Comme cela a t expliqu dans la section 3, les fonctions externes sont associes un identifiant entier dfini dans la section
PRIM de lexcutable gnr par ocamlc. Lappel une fonction
externe est compil en une instruction particulire de la machine
virtuelle nomme ccall. Cette instruction prend comme argument lidentifiant de la fonction externe et le nombre darguments
quelle ncessite. Linstruction ccall consiste donc en un saut au
code de la fonction externe, puis en le dpilement des arguments
aprs le retour de la fonction.
Avant dtre transfr sur le PIC, le code-octet du programme
subit des transformations dcrites dans la section 5 pour rduire
sa taille. En particulier, celles-ci convertissent la section PRIM en
une table dindirections. Ceci permet davoir un appel aux fonctions externes en temps constant : 9 cycles machine (7 instructions).
Depuis une fonction externe, il est possible de faire tout ce qui
est possible depuis le monde Objective Caml, savoir lancer une
exception, appeler une fonction Objective Caml en utilisant sa fermeture, accder aux variables globales, etc. Il est mme possible
daccder la totalit de la mmoire en lecture et en criture.
Il faut donc prendre soin de ne pas rendre incohrent le graphe
mmoire Objective Caml, sous peine de perturber le gestionnaire
mmoire par la suite. Ceci est dautant plus vrai sur un PIC car il
ny a pas de systme dexploitation et donc pas de vrification des
accs mmoire. Dans ces conditions, un programme peut conti-

Les PIC programms en OCaml

191

nuer sexcuter indfiniement avec un comportement difficilement prvisible.


4.4. Gestion automatique de la mmoire
Le ramasse-miettes de la distribution standard dObjective
Caml combine diffrentes techniques [5]. Cest un GC incrmental deux genrations [2]. Il utilise un Stop & Copy sur la gnration jeune (GC mineur) et un Mark & Sweep incrmentiel sur
lancienne (GC majeur). Enfin il peut tre compactant si besoin
est. Dans la ralisation pour PIC, nous avons choisi de coder un
simple Stop & Copy qui ne cherche pas optimiser la localit spatiale. En effet, un PIC nayant pas de cache, il ny aucun intrt
tenter damliorer cette dernire.
Il faut nanmoins faire attention certains dtails. Comme cela
a t dit dans la section 4.2.3, les blocs infixes ncessitent un traitement particulier.
Dautre part, le ramasse-miette doit faire attention ne pas
confondre un pointeur de code et un pointeur dans le tas. Sur un
ordinateur, ce problme ne se pose pas car la mmoire est en un
seul morceau et les adresses dans le code ne peuvent pas correspondre des adresses dans le tas. Sur un PIC, cest diffrent car il
y a plusieurs mmoires. Les pointeurs de codes sont des adresses
dans la mmoire programme et les pointeurs dans le tas sont des
adresses dans la mmoire vive. Les collisions sont donc a priori
possibles. En fait, sur ces PIC, la mmoire vive est beaucoup plus
petite que la mmoire programme. Il suffit donc de ne pas mettre
de code-octet dans la mmoire programme des adresses valides
dans la mmoire vive. Cette mmoire nest pas perdue car on peut
mettre la place le code de linterprte et de la bibliothque dexcution.
De plus, lorsque le ramasse-miette copie un bloc, il stocke dans
le premier champ du bloc original ladresse de la copie. La question est : comment faire pour les blocs de taille 0 (habituellement appels atomes) ? On remarque cependant que les atomes

192

JFLA 2011

ne contiennent pas de donnes. Et de plus, aucune valeur Objective Caml ne correspond un atome de tag diffrent de 0. Il ny a
donc quun seul atome possible : celui ayant pour tag 0, pour size
0 et pas de donnes. Il suffit donc de lallouer statiquement une
fois pour toute en dehors du tas et de toujours utiliser le mme.
Enfin, le ramasse-miette doit pouvoir marquer un bloc comme
tant copi. Dans la reprsentation standard des blocs en Objective Caml, len-tte contient un champ color qui est l pour a. Cependant, dans la reprsentation choisie ici (voir la section 4.2.2),
len-tte des blocs ne contient pas de champ color. Or, comme il
a t dit prcdemment, aucun bloc prsent dans le tas nest de
taille 0. Pour marquer un bloc dans le tas comme tant copi, il
suffit donc de lui mettre le champ size de len-tte 0.
5. Diffrentes transformations du code-octet
Pour installer un programme Objective Caml compil en codeoctet sur un PIC, il serait possible de lcrire dans la mmoire
programme ct de linterprte et de la bibliothque dexcution. Linterprte ZAM du PIC devrait alors effectuer exactement
le mme travail que linterprte standard ocamlrun, savoir dsrialiser le tableau des variables globales, calculer les indices des
fonctions externes et dbuter lexcution du code.
Il ne faut cependant pas oublier quun PIC a des ressources restreintes, tant au niveau vitesse de calcul quau niveau quantit de
mmoire disponible. Une telle approche impliquerait invitablement une initialisation atteignant facilement plusieurs diximes
de secondes, et une forte contrainte sur la taille maximale des
programmes. De plus, il est possible deffectuer des analyses statiques sur le code-octet dans le but dliminer du code mort et des
allocations inutiles.
Nous avons donc dcid de transformer lexcutable gnr par
ocamlc avant de le transfrer sur le PIC. Cette transformation
consiste en une suite doptimisations visant amliorer le temps

Les PIC programms en OCaml

193

dinitialisation, loccupation de la mmoire programme, loccupation de la mmoire vive et la vitesse dexcution.


Cette passe supplmentaire sur le code-octet a de plus lavantage de nous permettre de vrifier (partiellement) la compatibilit du programme avec la machine virtuelle. En particulier, des
bornes des entiers utiliss doivent tre compris entre -16384 et
16383 avec notre machine virtuelle 16 bits.
5.1. Compression simple du code-octet
Cette optimisation consiste en llimination, instruction par instruction, dune partie importante des octets inutiles du code-octet.
Les opcodes sont alors cods sur un octet au lieu de quatre, et
chaque argument de chaque instruction est cod sur le nombre
doctets minimal (1 ou 2 selon les instructions).
Par exemple, linstruction de la machine virtuelle constint
permet de placer un entier litral dans laccumulateur. Son argument est un entier et est donc cod sur deux octets. De mme,
linstruction makeblock permet dallouer un bloc dans le tas. Elle
prend un argument un tag et une taille qui sont tous les deux
compris entre 0 et 255. Ils sont alors cods sur un octet chacun.
Cette compression simple permet de gagner un facteur 3,5 sur
la taille occupe par le code-octet dans la mmoire programme
du PIC, et par consquent le mme facteur 3,5 sur la vitesse de
lecture du code par linterprte6 . La proportion moyenne entre
le temps de lecture dune instruction par rapport au temps total
dexcution de cette instruction tant de 6%, on en dduit quon
gagne un facteur 1,15 sur la vitesse dexcution totale. Le gain
principal de cette optimisation concerne donc la taille maximale
des programmes quil est possible de mettre sur un PIC, qui est
alors multiplie par 3,5.
Par la mme occasion, quelques optimisations ont t faites
pour amliorer la vitesse dexcution de linterprte. Par exemple,
6. Rappelons que labsence de cache (que ce soit pour la mmoire ou pour les instructions) dans les PIC permet de prdire aisment les temps dexcutions.

194

JFLA 2011

les adresses de sauts ne sont plus codes par des adresses relatives
(offsets), mais par des adresses absolues. De mme, les entiers ne
sont pas cods simplement en binaire mais plutt dans leur reprsentation mmoire (sous la forme 2 n + 1). Ceci permet dviter
quelques calculs arithmtiques, et par consquent quelques cycles
machines lexcution.
5.2. Optimisation du chargement des variables globales
linitialisation du programme, le tableau des variables globales est habituellement dsrialis. Deux solutions ont t envisages et codes pour tenter damliorer le temps dinitialisation.
La deuxime sest rvle tre bien meilleure, tant sur le temps
dexcution que sur la mmoire programme utilise.
La premire solution est dajouter au dbut du programme du
code-octet optimis calculant le tableau des variables globales.
Cette solution sest rvle avoir un gain faible sur le temps dinitialisation par rapport la solution nave. De plus, elle apportait
un grave problme : laugmentation considrable de la taille du
code-octet.
La deuxime solution est de prcalculer, par ordinateur, avant
le chargement du programme sur le PIC, ltat de la pile et du
tas aprs la dsrialisation du tableau des variables globales. Le
contenu de la partie utilise du tas et de la pile est alors stock
octet par octet dans la mmoire programme. linitialisation, linterprte prsent sur le PIC na qu copier un segment de mmoire
programme dans la mmoire vive et dmarrer lexcution. Grce
cette technique, le temps dinitialisation dans le pire cas (cest-dire si le tas et la pile sont remplies linitialisation) sur un PIC
ayant une horloge 10MHz est au maximum de 2,5ms. Ce temps
trs faible est d au fait que la mmoire dynamique des PIC de la
srie PIC18 est particulirement petite : au maximum 4ko.

Les PIC programms en OCaml

195

5.3. limination de code mort (ocamlclean)


Les optimisations dcrites prcdemment ne se sont pas rvles suffisantes pour permettre lutilisation des objets Objective
Caml sur PIC. En effet, la mmoire dynamique du PIC ntait pas
suffisante pour supporter lensemble des fermetures cres linitialisation du module CamlinternalOO et de ses dpendances. La
mmoire tait alors remplie de fermetures dont la majorit tait
inutilise. Le codage dun algorithme dlimination de code mort
a alors permis lutilisation de la couche objet dObjective Caml sur
PIC.
Cette optimisation est base, entre autres, sur une analyse statique du flot de donnes et du flot de contrle. Elle consiste en
llimination du code-octet de fonctions non utilises ainsi que de
la cration des fermetures associes. Il sen suit un gain, dune
part sur la taille du code-octet et dautre part sur loccupation de
la mmoire dynamique. Grce cette optimisation, il est possible
de mettre sur un PIC des programmes plus gros et allouant plus.
De plus, comme le gestionnaire mmoire qui a t cod pour PIC
nest quun simple Stop & Copy, tous les blocs vivant sont copis
chaque lancement du ramasse-miettes. Sa frquence de lancement ainsi que son temps dexcution sont eux aussi amliors par
llimination des fermetures non utilises.
Le principal inconvnient de cette optimisation est quelle casse
le chargement dynamique de modules. Ceci nest pas une gne
pour le projet dans sa globalit car il est difficile de donner un
sens du chargement dynamique de code sur un PIC7 .
Le programme ainsi cr prend en entre un excutable standard pour la machine virtuelle Objective Caml, et gnre en sortie
un nouvel excutable standard nettoy. Il peut se dcomposer en
trois routines. Elles sont excutes en boucle jusqu lobtention
dun point fixe.
7. Les utilisateurs qui ne visent pas embarquer leur code Objective Caml sur PIC
peuvent sen servir si le chargement dynamique ne leur est pas ncessaire. Cet outil
(ocamlclean) est distribu dans une archive indpendante pour ne pas obliger rcuprer tout OCAPIC.

196

JFLA 2011

1) On analyse les variables globales nettoyer : pour chaque


bloc point par le tableau des variables globales, on teste les
accs en lecture. Ceci est possible car ces accs sont explicites
dans la machine virtuelle, ils ne peuvent se faire que par deux
types dinstructions : getglobal (affectant laccumulateur avec
une variable globale) et getglobalfield (affectant laccumulateur avec un champ dune variable globale, cette instruction ne
peut bien sr tre utilise que pour les variables globales correspondant des blocs). Les variables globales qui nous intressent sont celles sur lesquelles aucun getglobal nest effectu,
seulement des getglobalfield. Pour ces variables, on dtermine
chaque champ non utilis et on supprime son initialisation
2) On effectue ensuite une analyse du flot de donnes. Le but
est de dterminer et dliminer du code-octet les instructions
ayant cr les valeurs ntant plus stockes dans les champ des
variables globales nettoyes en 1. En particulier, on cherche
liminer les instructions de cration des fermetures (closure et
closurerec) qui ne sont jamais stockes. Cet algorithme consiste
en la cration dun graphe de dpendances entre les instructions,
puis en un parcours de ce graphe pour dterminer les instructions
dont le seul effet a t de calculer des valeurs qui ne sont jamais
lues.
3) Enfin, on effectue une analyse standard du flot de contrle
pour dterminer les blocs de code non-atteignables lors de lexcution. De tels blocs nexistaient pas dans le code original, mais
sont apparus lorsque lon a supprim des instructions de cration
de fermetures ltape 2.
Cet algorithme a t entirement cod en 1800 lignes de code
Objective Caml. Il a t aussi test avec ocamlrun sur les compilateurs ocamlc et ocamlopt et semble fonctionner correctement.
6. Environnement de dveloppement
Lensemble des algorithmes dcrits dans les sections prcdentes ont t implants et forment une application complte
permettant de programmer les PIC de la srie PIC18 en Ob-

Les PIC programms en OCaml

197

jective Caml. Pour utiliser cette application, il faut prendre en


compte certains points. En particulier, la bibliothque standard
a t en partie modifie : certaines fonctionnalits ont t retires
et dautres ajoutes pour correspondre aux besoins spcifiques de
la programmation sur PIC. De plus, pour permettre le debogage
des programmes Objective Caml sur PIC, il a t cod une sorte
de simulateur. Enfin, les ressources dun PIC tant particulirement restreintes, il faut matriser les performances de la machine
virtuelle.
6.1. Une nouvelle bibliothque standard Objective Caml pour
PIC
Une partie de la bibliothque standard na pas t porte sur
PIC. Parmi les diffrents modules, certains ont t copis tels quels
et dautres ont t restreints, recods, ou supprims. En particulier, toutes les fonctions concernant les entres/sorties standards
ont t suprimes des modules Pervasives et Buffer car elles
nont pas vraiment de sens sur un PIC. Le tableau 3 indique ce qui
a t fait de chaque module de la bibliothque standard.
Modules copis
Array, ArrayLabels,
CamlinternalLazy,
CamlinternalMod,
Char, Hashtbl,
Int32, Int64, Lazy,
List, ListLabels,
MoreLabels, OO,
Queue, Set, Sort,
Stack, StdLabels,
String, StringLabels

Modules modifis

Modules non-ports

Buffer,
CamlinternalOO,
Gc, Map, Obj,
Pervasives,
Random,
Std_exit, Sys

Arg, Complex,
Callback, Digest,
Filename, Format,
Genlex, Marshal,
Nativeint,
Parsing, Printexc,
Printf, Scanf,
Stream, Weak

Tableau 3 Portage des modules de la bibliothque standard


De plus, comme cela avait t dit dans la section 2.2, lun des
problmes lors du portage dun langage de haut niveau sur PIC
est de permettre au programmeur daccder aux ressources bas
niveau, sans casser la scurit ni les principes de programmation
associs au langage haut niveau. Une bonne illustration de ce pro-

198

JFLA 2011

blme est la gestion des registres spciaux du PIC depuis le monde


Objective Caml. Les registres spciaux dun PIC dsignent les ports
et les registres de configuration des interfaces internes du PIC. Depuis lassembleur, on lit et on crit librement dans ces registres. La
question est de donner au programmeur Objective Caml le moyen
daccder ces registres aussi facilement quen assembleur. La solution qui a t adopte est dutiliser les types sommes dObjective Caml dont on matrise la reprsentation mmoire. Un type
somme reprsente lensemble des registres spciaux, et un autre
lensemble des bits des registres spciaux. La reprsentation mmoire des valeurs de ces types correspond dans un cas ladresse
des registres, et dans lautre ladresse des registres concatne
avec les masques daccs aux bits. La manipulation des registres
spciaux et de leurs bits est alors possible depuis le monde Objective Caml en passant par des fonctions externes.
La programmation sur PIC na pas les mmes domaines dapplication que la programmation sur ordinateur. Il est donc intressant de fournir au programmeur Objective Caml un ensemble de
bibliothques pour lui permettre de se rapprocher des domaines
dapplications standards des PIC. Par exemple, il est habituel dutiliser un PIC pour contrler un petit afficheur LCD. Le PIC doit
alors appliquer des protocoles assez bas niveau pour communiquer avec lafficheur. Il est intressant de fournir au programmeur
Objective Caml une interface haut niveau lui permettant dutiliser
facilement un afficheur LCD. De plus, on aimerait avoir une certaine gnricit vis--vis de lafficheur, ou plus simplement vis-vis de l o est branch lafficheur. Pour rsoudre ce problme, les
foncteurs sont une solution assez agrable. Nous avons donc cod
un module supplmentaire dans la bibliothque standard nomm
Lcd. Voici un exemple de programme utilisant ce module :
1
2
3
4
5
6
7
8
9

module Aff = Lcd. Connect ( struct


module Pic = Pic18f4620
let is_8_bits = true (* mode de comm. (bus de donnes ) *)
let e = Pic.RD0
(* df. des pattes de commandes *)
let rw = Pic.RD1
let rs = Pic.RD2
let port = Pic.PORTC (* port pour le bus de donnes *)
end)
open Aff

Les PIC programms en OCaml

10
11
12
13
14
15
16
17
18

199

let () = init ()
(* initialisation de l afficheur *)
let () = config
(* configuration de l afficheur *)
~mode: Cursor_right (* sens de dplacemt du curseur *)
~disp:On
(* affichage visible *)
~ cursor :Off
(* curseur invisible *)
~blink:Off
(* cuseur non clignotant *)
~lmode:Two
(* affichage sur 2 lignes *)
~font:F5x8
(* police de caractres 5x8 px *)
let () = write_string "Hello world" (* ^^ *)

6.2. Un simulateur de PIC pour les programmes Objective


Caml
Le dbogage dapplications pour PIC est un problme assez dlicat. En effet, lorsquun programme sexcute sur un PIC, moins
dutiliser des dbogueurs in-situ8 , il est impossible de suspendre
lexcution pour observer le contenu de la mmoire. De plus, un
PIC nest pas forcment connect une interface permettant de
communiquer facilement avec un humain (comme par exemple
un afficheur LCD). Il est alors impossible de tracer lexcution du
code en insrant des printf .
Il existe des mulateurs de PIC comme gpsim, et la plupart des
environnements de dveloppement intgrs comme MPASM ou
PIC simulator IDE en contiennent. Cependant, il nest pas trs pratique dutiliser de tels simultateurs pour dboguer les programmes
Objective Caml sur PIC. En effet, ces simulateurs parcourent le
code de la machine virtuelle, et il est difficile de faire le lien entre
les instructions simules par le dboguer et le code source Objective Caml.
Nous avons donc cod un outil premettant au programmeur
Objective Caml de simuler lexcution de ses programmes sur un
PIC. Comme on peut le voir sur la chane de production dcrite
dans la figure 1, le programme Objective Caml est dabord compil
en un excutable standard pour ordinateur. Cet excutable est en
8. Technique de mise au point pour des applications embarques sur microcontrleur
consistant le connecter un ordinateur et excuter le code dans le microcontrleur.
Lordinateur peut alors contrler partiellement le flux dexcution du programme dans
le microcontrleur et accder sa mmoire.

200

JFLA 2011

fait li une bibliothque dexcution particulire qui intercepte


les appels aux fonctions externes de lecture et dcriture dans les
registres spciaux du PIC. Lors de lexcution sur un ordinateur de
cet excutable, le processus lanc ouvre diffrentes fentres permettant de visualiser les actions du PIC. Il est alors possible de
simuler les interactions du PIC avec diffrents composants lectroniques. Par exemple, lorsque lon excute le programme correspondant au code Objective Caml de la section 6.1 grce la commande suivante, on peut visualiser une fentre reprsentant la raction dun afficheur LCD aux actions du PIC comme sur la figure
2. Comme le programme sexcute sur un ordinateur, on peut utiliser les outils standard de dbogage (par exemple ocamldebug)
pour tracer le code Objective Caml.
1

./ hw ocapic_lcd_simulator 16x2 e=RD0 rs=RD2 rw=RD1 bus=PORTC

Figure 2 Capture dcran de la simulation dun PIC connect


un afficheur LCD

7. tude de performances
7.1. Performances gnrales du systme
PIC18F4620

OCAPIC

sur le

La vitesse dexcution moyenne des programmes sur un PIC


excutant 10 000 000 instructions machine par seconde est de
400 000 instructions de code-octet par seconde. Autrement dit, il
faut en moyenne 25 cycles machine pour excuter une instruction
de code-octet. De plus, le PIC perd en moyenne 7,5 cycles machine
dans la gestion de chaque opcode. Ceci implique que la proportion
du temps dexcution des instructions utiles par rapport au temps
dexcution de la gestion du code-octet est de 70%.

Les PIC programms en OCaml

201

La taille de la mmoire programme du PIC18F4620 est de


64ko. La taille du binaire associ linterprte est de 4 954o.
La taille du binaire associ la bibliothque dexcution est de
4 254o. Par consquent, la taille maximale du code-octet que lon
peut mettre dans ce PIC est de 55ko, ce qui reprsente 86% de la
mmoire totale.
La mmoire vive du PIC18F4620 est de 3 968o. Elle est partage entre la pile dexcution, le tas, des registres rservs la
machine virtuelle (39o), et les registres spciaux (128o). La proportion entre la taille de la pile et la taille du tas est dfinie la
compilation. Par dfaut, la taille de la pile a t arbitrairement
fixe 174 niveaux. Comme lalgorithme de gestion mmoire est
un Stop & Copy, seule la moiti du tas est utilisable. La taille du
tas est donc ici de 1792o.
7.2. Calcul de nombres premiers avec allocations de listes
chanes
Nous proposons dobserver le temps dexcution dun programme calculant la liste chane des n premiers nombres premiers. Le principal site dallocation mmoire est situ dans la
dfinition de la seconde fonction (npremiers_aux), il sagit du
constructeur de listes (::). Nous pouvons ainsi prdire le nombre
dlments allous dans le tas. Ce nombre correspond en fait
lallocation du rsultat attendu : les n premiers nombres premiers dans une liste chane. La liste alloue occupe alors n
(2 + 2 + 2) = 6n octets, ce qui fait 1500o pour une liste 250 lments. tant donn que le tas du PIC18F4620 est limit 1792o,
n=250 est arbitrairement une bonne valeur.
1
2
3
4
5
6
7
8
9

let rec npremiers n =


if n = 0
then []
else npremiers_aux (n -1) [2]
and npremiers_aux n r =
if n = 0
then r
else npremiers_aux (n -1) ( premier_suivant (List.hd r+1) r :: r)
and premier_suivant n l =

202
10
11
12
13
14
15
16
17
18
19

JFLA 2011

if est_premier n l
then n
else premier_suivant (n+1) l
and est_premier n = function
| [] ->
true
| e::tl ->
if n mod e = 0
then false
else est_premier n tl

20
21
22
23
24

let () =
for i = 1 to 80 do
ignore ( npremiers 250)
done

Nous comparons titre indicatif les temps dexcutions obtenus sur un ordinateur moderne (Linux 2.6.32 32 bits, processeur
Intel Atom Z520 1,33GHz et mmoire vive 1Go DDR2 667MHz)
et un PIC18F4620 cadenc 10MHz, en moyenne sur 5 excutions. Dans les deux cas, le mme compilateur ocamlc est utilis
(distribution Objective Caml 3.12.0).
Nous obtenons alors 3,74 secondes pour lordinateur
1,33GHz et 472 secondes sur le PIC18F4620 10MHz. On observe un facteur 126 entre les deux temps dexcution.
7.3. Jeu du solitaire
Le test classique de performances du jeu du solitaire a t effectu dans les mmes conditions que celles prsentes dans la
section prcdente. Nous avons mesur les temps dexcutions sur
ordinateur moderne grand public et sur le PIC18F4620.
Nous obtenons cette fois-ci 7,2 secondes pour lordinateur
1,33GHz et 812 secondes sur le PIC18F4620 10MHz. On observe un facteur 113 entre les deux temps dexcution.

Les PIC programms en OCaml

203

7.4. Implantation dun jeu de stratgie, algorithme minimax


Pour valider notre approche, nous avons implant un jeu de
plateau deux joueurs. Le premier joueur est un humain utilisant
une interface compos de boutons poussoir. Le second joueur est
artificiel ( incarn par un programme excut sur le PIC). Le
programme indique au joueur les actions et lavancement du jeu
par lintermdiaire dun afficheur LCD.
La ractivit du PIC est satisfaisante malgr les multiples dclenchements du ramasse-miette lors de lexcution de lalgorithme de rflexion. En effet, le temps de calcul est en moyenne
dune demie seconde et toujours infrieur deux secondes. Un humain expriment a une certaine difficult gagner, ce qui laisse
penser que les algorithmes implants sont satisfaisants.
Le jeu a t implant en 667 lignes de code Objective Caml.
Une implantation de ce jeu en assembleur PIC ou dans un langage
de bas niveau obligeant grer manuellement le peu de mmoire
disponible sur un PIC aurait t trs ardue voire quasi impossible.
8. Travaux connexes
Lenvironnement de dveloppement MPLAB fourni avec les microcontrleurs PIC propose un assembleur (MPASM), un diteur
de liens (MPLINK) et un simulateur pour tester et mettre au point
un excutable. Il est possible de programmer dans des langages de
plus haut niveau. On trouve principalement des sous-ensembles
de C et de Basic interfacs avec MPLAB ou autonomes.
Il y a trois dmarches dans les autres langages proposs : compilateur natif (comme pour C), interprte (comme pour Basic),
compilation vers une machine abstraite puis interprtation du
code-octet comme prsent dans cet article.
Pour les compilateurs natifs, on trouve des variations autour
du langage Pascal comme Pic micro Pascal [11] qui sintgre aux
outils de MPASM/MPLINK de MPLAB tout en proposant un IDE
propre. Un autre langage plus loign de Pascal, Jal [14] a pro-

204

JFLA 2011

pos ds 2004 un compilateur libre. Une nouvelle version, Jal2, a


t dvelope par une communaut toujours active.
Pour les interprtes, on rencontre principalement des implantations du langage Forth qui ont lavantage dtre petites et donc
de pouvoir tenir sur un microcontrleur. FlashForth [9] est un
systme Forth autonome implant sur PIC18F qui apporte un interprte et un compilateur/chargeur, les deux embarqus sur le
microcontrleur. Il existe par ailleurs des compilateurs Forth qui
permettent de charger le code comme PicForth [13]. La gestion
des ports et des interruptions est en rgle gnrale assez facile
manipuler en Forth comme le montre lexemple de compilation
sur le site de PicForth.
Nous ne sommes pas les premiers utiliser lapproche machine
abstraite pour cibler larchitecture PIC. En effet, la conception
dune machine virtuelle Scheme pour PIC a dj t entreprise
au sein des projets PICBIT [4] et PICOBIT [12] pour un sousensemble du R4RS. PICBIT adapte aux contrleurs PIC un environnement Scheme trs compact. La machine abstraite crite en C
est traduite par un compilateur C pour PIC. PICOBIT tend cette
dmarche en y adjoignant un compilateur C, appel SIXPIC, spcifique aux PIC et permettant dobtenir un meilleur code en particulier pour la machine abstraite. Comme indiqu lors de lanalyse
des performances, lcriture directe de linterprte ZAM et de la
bibliothque dexcution en assembleur PIC, combine la compaction du code, donne de trs bonnes performances. En cela les
dmarches PICOBIT et OCAPIC divergent, la premire privilgiant
la portabilit sur dautres architectures et la deuxime lefficacit
sur PIC.
On retrouve cette approche machine abstraite pour le langage
Java avec la Plateforme Java Card [10]. Nanmoins mme en limitant fortement le langage Java (en particulier la gestion automatique de la mmoire, labsence de certains types (entiers 64
bits) et de contrle comme les threads), et en crivant dans un
style impratif, on obtient toujours un code important qui ne peut
tenir sur des microcontrleurs actuels.

Les PIC programms en OCaml

205

9. Conclusion
Cette ralisation permet de programmer des microcontrleurs
PIC en Objective Caml. Elle est prte lutilisation et distribue9
sous la licence libre CeCILL-B. Limplantation dans un langage de
trs bas niveau de la machine virtuelle Objective Caml sur PIC
permet dobtenir de trs bonnes performances. Le ct paradoxal
de notre dmarche est quen simplifiant la programmation pour
PIC en utilisant Objective Caml, on arrive faire excuter des
programmes plus importants, qui peuvent donc contenir une part
algorithmique non ngligeable, de manire plus sre grce au typage statique et la gestion automatique de la mmoire tout en
restant trs efficace. Cette dmarche ouvre des perspectives intressantes pour le portage dun langage de haut niveau comme
Objective Caml sur des appareillages ayant de faible ressources,
tant en mmoire quen capacit de calcul.
Il reste alors enrichir la bibliothque pour PIC, afin de pouvoir tirer davantage profit de ces microcontrleurs ainsi que des
priphriques usuellement associs ces derniers. Ces enrichissements pourront intgrer aussi des extensions sur les modles de
concurrence lis au dveloppement dapplications interactives et
ractives pour PIC, bases sur lenvironnement Objective Caml.
Un autre avantage de cette dmarche machine abstraite est
de pouvoir raisonner sur du code-octet plutt que sur lassembleur PIC, soit pour prouver des proprits par analyse statique,
soit pour vrifier base de tests dautres proprits du programme
comme lexprience du projet Couverture10 la montr dans le
cadre du dveloppement certifi.
La machine virtuelle Objective Caml qui a t code dans ce
projet fonctionne pour les microcontrleurs de la srie PIC18. Le
portage de cette machine virtuelle sur les sries antrieurs des
PIC (PIC10 PIC16) semble difficile voire impossible. En effet, la
quantit de registre et de mmoire programme risquerait dtre
insuffisante. Sur les sries de PIC plus avances (PIC24 PIC32),
9. http://www.algo-prog.info/ocaml_for_pic/
10. http://www.projet-couverture.com/

206

JFLA 2011

le portage de cette machine virtuelle est trs rapide car les assembleurs des sries rcentes sont presque compatibles avec celui
de la srie PIC18. Il faut nanmoins remarquer que le code de la
machine virtuelle pourrait alors tre optimis pour tirer parti des
fonctionnalits apportes par les nouvelles sries de PIC. Enfin, le
portage sur dautres types de microcontrleurs (e.g., AVR, Atmel,
Philips) demanderait un travail consquent car les architectures
internes et les assembleurs sont diffrents.
Enfin, cette exprience de portage dObjective Caml sur PIC
prouve quil est possible dutiliser des langages de haut niveau
pour programmer des architectures exotiques ayant de trs faibles
ressources.
Rfrences
[1] Bigonoff. La programmation des PIC par Bigonoff, cinquime partie. Migration vers 18F : mode demploi, 2010.
http://www.abcelectronique.com/bigonoff/.
[2] Emmanuel Chailloux, Pascal Manoury, and Bruno Pagano.
Dveloppement dApplications avec Objective Caml. OReilly,
2000. http://www.pps.jussieu.fr/Livres/ora/DA-OCAML.
[3] Xavier Clerc. Cadmium, February 2010. http://cadmium.
x9c.fr/distrib/cadmium.pdf.
[4] Marc Feeley and Danny Dub. Picbit : a Scheme system for
the PIC microcontroller. In Scheme Workshop, pages 715,
November 2003.
[5] Richard E. Jones. Garbage Collection : Algorithms for Automatic Dynamic Memory Management. John Wiley and Sons,
July 1996.
[6] Xavier Leroy. The ZINC experiment : an economical implementation of the ML language. Technical Report RT-0117,
INRIA, February 1990.

Les PIC programms en OCaml

207

[7] Xavier Leroy, Damien Doligez, Jacques Garrigue, Didier


Rmy, and Jrme Vouillon. The Objective Caml system (release 3.11) : Documentation and users manual. INRIA, November 2008.
[8] Microchip.
PIC18F2525/2620/4525/4620 Data Sheet,
2008. http://ww1.microchip.com/downloads/en/devicedoc/
39626b.pdf.
[9] Mikael Nordman.
sourceforge.net/.

Flashforth.

http://flashforth.

[10] Oracle.
Java Card 3.0.1 Platform Specification, May
2009. http://www.oracle.com/technetwork/java/javacard/
specs-jsp-136430.html.
[11] Philippe Paternotte. Pic Micro Pascal V1.4 : User Manual,
July 2010. http://www.pmpcomp.fr.
[12] Vincent St-Amour and Marc Feeley. Picobit : A Compact
Scheme System for Microcontrollers. In International Symposium on Implementation and Application of Functional Languages (IFL09), pages 111, September 2009.
[13] Samuel Tardieu. Picforth programmer manual. http://www.
rfc1149.net/devel/picforth.
[14] Wouter van Ooijen et al. Jal (not ?) Just Another Language,
May 2004. http://jal.sourceforge.net/manual.

208

JFLA 2011