Vous êtes sur la page 1sur 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.

net

Noyau temps rel pour PIC18

PICos18 v 2.01

Pragmatec
Produits et services ddis aux systmes embarqus temps-rel

PICos18
Noyau temps rel pour PIC18

Tutorial & Manuel du Dveloppeur

12 Mars 2004 Rev 2.00 1 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Page laisse intentionnellement blanche.

2 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

TO ANY PICos18 USER

Distribution: PICos18 is free software; you can redistribute it and/or modify it under the terms of the GNU General License as published by the Free Software Foundation; either version 2, or (at your option) any later version. PICos18 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PICOS18; see the file COPYING.txt. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 021111307, USA.

PICos18 est un produit de la socit PRAGMATEC S.A.R.L. distribu gratuitement sous licence GPL. Celle-ci garantie la libre circulation des sources de PICos18. PICos18 est un noyau temps rel bas sur la norme automobile OSEK/VDX et destin aux microcontrleurs PIC18 de la socit Microchip Technology Inc.

Ce tutorial est la proprit de PRAGMATEC S.A.R.L. Il est destin la comprhension et la prise en main du logiciel PICos18. Pour des raisons pratiques et techniques, il a t ralis sous MPLAB et compil avec le compilateur C18 pour cible PIC18F452.

3 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

TABLE DES MATIERES

1.

PREAMBULE ......................................................................................................................................................................5 UN NOYAU MULTI- TACHES TEMPS REEL .....................................................................................................................................5 PICOS18 : UN NOYAU MULTI- TACHES TEMPS REEL POUR PIC18 ..............................................................................................6 LA NORME OSEK/VDX...........................................................................................................................................................6 LES CARACTERISTIQUES DE PICOS18 .........................................................................................................................................7 LA LICENCE GPL .........................................................................................................................................................................8 LA CHAINE DE COMPILATION MICROCHIP ..................................................................................................................................9 LA SOCIETE PRAGMATEC ...........................................................................................................................................................10

2.

PICOS18 : TUTORIAL ....................................................................................................................................................11 L'ENVIRONNEMENT DE DEVELOPPEMENT .................................................................................................................................11 CREATION D'UNE PREMIERE TACHE ..........................................................................................................................................11 LA PREEMPTION .........................................................................................................................................................................11 LE MULTI- TACHES......................................................................................................................................................................11 LES INTERRUPTIONS ...................................................................................................................................................................11 UTILISATION DES DRIVERS ........................................................................................................................................................12 EXEMPLE D'APPLICATION ..........................................................................................................................................................12

3. 4. 5. 6. 7. 8. 9. 10. 11.

L'ENVIRONNEMENT DE DEVELOPPEMENT .......................................................................................................13 CREATION DUNE PREMIERE TACHE ...................................................................................................................18 LA PREEMPTION ............................................................................................................................................................24 LE MULTI-TACHES........................................................................................................................................................31 LES INTERRUPTIONS ...................................................................................................................................................35 UTILISATION DES DRIVERS ......................................................................................................................................42 EXEMPLE DAPPLICATION........................................................................................................................................47 BIBLIOGRAPHIE ET REFERENCES....................................................................................................................52 GLOSSAIRE..................................................................................................................................................................53

4 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

1. Prambule
Un noyau multi-tches temps rel
On entend trop souvent parler de noyau temps rel dans le monde de l'embarqu sans trop savoir pour autant de quoi il en retourne. En fait pour comprendre ce qu'apporte un noyau multi-tches temps-rel, il faut dfinir 3 aspects : Un noyau... C'est en fait un ensemble de fonctionnalits, regroupes sous le terme de SERVICES pour la plupart, qui forment le noyau. Dans le cas de Linux, par exemple, le noyau est constitu de la gestion des diffrents programmes, de l'accs au hardware, de la gestion des systmes de fichiers... Le shell, quant lui, est un programme, et n'est donc pas inclu dans le noyau. La fonction malloc, qui alloue dynamiquement de la mmoire un programme, fait appel un service du noyau, car c'est bel et bien le noyau qui est responsable de la gestion des ressources. Une des fonctionnali les plus connue des noyaux (sans tre pour autant un service) est le SCHEDULER, responsable de la cohabitation des diffrents programmes pendant leur excution. ... multi-tches ... C'est donc le noyau qui contrle les ressources et permet leur utilisation de faon sre et efficace au travers de SERVICES. Puisque le noyau garantit la stabilit du systme, plusieurs programmes indpendants peuvent se tenir prts fonctionner, au bon vouloir du noyau. Cette MULTIPROGRAMMATION permet aux dveloppeurs de crer des programmes sans se soucier de savoir s'il existe d'autres programmes dans le systme. Chacun a l'impression que le systme lui est ddi. Si le noyau le permet, il est mme possible de faire fonctionner ces programmes en parallle tout en donnant l'impression chacun d'tre seul fonctionner (au prix d'une perte de vitesse bien entendu). Lorsque le noyau joue parfaitement son rle de chef d'orchestre (le fonctionnement en parallle des tches incombent au noyau seul) on dit que le noyau est MULTI-TACHES PREEMPTIF. Si le noyau n'est pas capable de faire une telle chose, alors c'est aux tches de "rendre la main" au noyau de temps en temps. On dit que le noyau est MULTI-TACHES COOPERATIF. PICos18 est un noyau temps rel premptif.

... temps rel Le noyau multi-tche peut simplement grer le paralllisme en dcoupant le temps en parts gales pour chaque tche en mmoire. Le problme, c'est que les tches en fonctionnement ont rarement les mmes besoins, et certaines, rarement actives, requirent toute la puissance du systme lorsqu'elles se rveillent. Les tches ont donc des PRIORITES diffrentes, et doivent pouvoir rpondre un vnement dans un temps le plus court possible. Plutt que d'assurer un temps de ractivit quasi-nul (ce qui est impossible), le noyau se doit de garantir un TEMPS DE LATENCE constant : c'est le DETERMINISME. Le temps de latence de PICos18 est de 50 us.

5 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

PICos18 : un noyau multi-tches temps rel pour PIC18


Avant l'arrive des PIC18, il n'tait pas possible de dvelopper un tel noyau sur les PICmicro. En effet la caractristique premire d'un noyau multi-tches est de faire cohabiter des tches ensemble, ce qui implique de contrler la pile des appels de fonctions [cf datasheet du PIC18F452 DS39564A, page 37, chapitre 4.2 Return Address Stack ]. Imaginez ce qui se passerait si toutes les tches en fonctionnement partageaient la mme pile : le noyau interromprait le fonctionnement d'une tche pour activer une autre tche, et la prochaine instruction RETURN rencontre, le retour se ferait dans la premire tche, au niveau du dernier appel de fonction ! Les PIC18 permettent la manipulation de la pile des appels de fonctions (instructions PUSH et POP ajoute au jeu d'instructions, et dplacement du pointeur de pile), si bien qu'il est dsormais possible de mettre la pile dans un tat correct avant l'activation de la prochaine tche. Il restait alors dfinir la liste des services du noyau dvelopper et sa gestion interne des tches et des ressources. Plutt que de partir dans une solution propritaire, la socit Pragmatec, lorigine de PICos18, a choisi de se baser sur une norme : la norme OSEK/VDX.

La norme OSEK/VDX
La norme retenue est la norme OSEK-VDX (www.osek-vdx.org). OSEK-VDX est un vaste projet de lindustrie automobile, commun aux plus grands constructeurs et quipementiers allemands et franais. Lobjectif de ce projet est de dfinir un standard pour le contrle et la supervision des architectures distribues embarques dans les vhicules. En effet, les vhicules actuels peuvent embarquer jusqu 30 calculateurs (contrle moteur, habitacle, blocs de portire, ABS, ESP) qui communiquent entre eux, par liaisons filaires ou multiplexes (bus CAN, VAN, LIN, MOST). Normaliser les relations entre ces calculateurs, cest : homogniser les spcifications des dveloppements, les dveloppements euxmmes, les validations systmes ; avoir un langage commun entre constructeurs, quipementiers et fournisseurs doutils de dveloppement ; fournir une base commune pour tous pour le dveloppement, les validations et intgrations. Le terme OSEK signifie Offene Systeme und deren Schnittstellen fr die Elektronik im Kraftfahrzeug (Systmes ouverts et les interfaces correspondantes pour llectronique automobile ). Le terme VDX signifie Vehicle Distributed eXecutive . La fonctionnalit de lOS OSEK a t combin avec VDX. Aujourdhui utilise dans l'automobile et la robotique, cette norme dfinie le rle du noyau autour de 3 axes : Operating System (OS), Communication (COM) et Network Management (NM). Pour l'instant seule la partie OS a t implmente dans PICos18.

6 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

La norme OSEK-VDX est une norme parfaitement adapte aux PIC18. Une application sous PICos18 se compose dun ensemble de tches symbolises par des cercles sur le schma cidessous. Le principe de fonctionnement veut quune seule tche la fois peut avoir accs au PIC18 (plus exactement au processeur, la mmoire RAM et la pile matrielle). Afin de dterminer quelle tche mrite dtre excute un instant T, le noyau PICos18 examine lensemble des tches de lapplication et choisi la tche prte la plus prioritaire. Lors de son excution celle-ci peut se mettre en attente dun vnement et ainsi sendormir, laissant la place une autre tche moins prioritaire. Lorsque lvnement attendue sera dtect par le noyau, ce dernier sempressera de rveiller la tche prcdemment endormie. Les diffrents tats dune tche de PICos18 peuvent tre : READY, SUSPENDED, WAITING et RUNNING.

Les caractristiques de PICos18


Le noyau PICos18 possde les caractristiques suivantes :

Le cur du noyau (Init + Scheduler + Task Manager) qui a la responsabilit de grer les tches de l'application et donc de dterminer la prochaine tche active en fonction de l'tat et la priorit de chaque tche. Le gestionnaire d'alarmes et de compteurs (Alarm Manager). Proche du cur du noyau, il rpond l'interruption du TIMER0 afin de mettre jour priodiquement les alarmes et compteurs associes aux tches. Les Hook routines sont proches du coeur du noyau et permettent l'utilisateur de drouter le droulement normal du noyau de faon prendre temporairement le contrle du systme. Le gestionnaire de tches (Process Manager) est un service du noyau, dont le rle est d'offrir l'application les fonctions ncessaires la gestion des tats (changer l'tat d'une tche, chaner des tches, activer une tche...). Le gestionnaire d'vnement (Event Manager) est un service du noyau dont le rle est d'offrir l'application les fonctions ncessaires la gestion des vnements d'une tche (mise en attente sur un vnement, effacer un vnement...). Le gestionnaire d'interruption (INT Manager) offre l'application les fonctions ncessaires l'activation et la dsactivation des interruptions du systme.

7 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

PICos18 est un noyau modulaire dans le sens o les accs spcifiques aux ressources (drivers, file system manager, etc.) peuvent tre raliss par des tches dissocies du noyau. De cette faon PICos18 offre la possibilit dintgrer des modules sous forme de briques logicielles afin de constituer un projet, telles que les extensions proposes par la socit PRAGMATEC.

La licence GPL
Le noyau PICos18 est en open-source et est distribu sous licence GPL (General Public Licence). Cela signifie que toutes les sources du noyau en C et en assembleur sont disponibles. Cela signifie galement quil est totalement gratuit et nimplique le paiement daucune royaltie ses auteurs. En en-tte de chaque fichier source de PICos18, vous retrouverez donc le mme texte, conserver dans les fichiers quelque soit votre utilisation ou votre projet avec PICos18 :
/**********************************************************************/ /* */ /* File name: le nom du fichier source */ /* */ /* Since: date de cration */ /* */ /* Version: 2.xx (version courante du noyau PICos18) */ /* */ /* Author: Designed by Pragmatec S.A.R.L. www.pragmatec.net */ /* MONTAGNE Xavier [XM] xavier.montagne@pragmatec.net */ /* FAMILLE Prenom [xx] */ /* */ /* Purpose: une explication sur le rle du fichier */ /* */ /* Et enfin, lenregistrement de PICos18 auprs de la fondation */ /* du logiciel libre Boston aux Etats Unis, la Free Software */ /* Foundation */ /* Distribution: This file is part of PICos18. */ /* PICos18 is free software; you can redistribute it */ /* and/or modify it under the terms of the GNU General */ /* Public License as published by the Free Software */ /* Foundation; either version 2, or (at your option) */ /* any later version. */ /* */ /* PICos18 is distributed in the hope that it will be */ /* useful, but WITHOUT ANY WARRANTY; without even the */ /* implied warranty of MERCHANTABILITY or FITNESS FOR A */ /* PARTICULAR PURPOSE. See the GNU General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU General */ /* Public License along with gpsim; see the file */ /* COPYING.txt. If not, write to the Free Software */ /* Foundation, 59 Temple Place - Suite 330, */ /* Boston, MA 02111-1307, USA. */ /* */ /* > A special exception to the GPL can be applied should */ /* you wish to distribute a combined work that includes */ /* PICos18, without being obliged to provide the source */ /* code for any proprietary components. */ /* */ /* History: Les modifications successives apportes ce fichier */ /* 2004/09/20 [XM] Create this file. */ /* */ /**********************************************************************/

8 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

La licence GPL garantie la libre circulation des sources de PICos18, sans restrictions ou protections imposes par une quelconque socit ou organisation En revanche, la socit PRAGMATEC, lorigine de PICos18, sengage maintenir le noyau et le faire voluer, tout en respectant les rgles de la licence GPL. Bien entendu, quiconque souhaite apporter sa contribution ldifice peut le faire. Son nom apparatra alors au ct de celui des auteurs dans len-tte des fichiers. Une mention spciale a t rajout la licence GPL et ceci dans chaque entte de fichier. Cette mention crite en anglais prcise quil est possible dassocier PICos18 une application sans pour autant tre tenu de respecter la licence GPL sur cette partie, cest--dire sans devoir fournir le code source de lapplication. Par contre vous devrez tre en mesure de fournir quiconque le code source du noyau PICos18.

La chane de compilation Microchip


Vous allez programmer votre application en C sous PICos18. Toutefois le noyau lui-mme est compos de fichiers en C pour les services par exemple et de fichiers crits en assembleur comme le fichier kernel.asm. Ces diffrents fichiers devront tre compils ou assembls puis lis afin dobtenir un seul fichier au final : le fichier HEX qui pourra tre charg dans le PIC18.

9 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

La chane de compilation Microchip se dcompose en 3 lments : lassembleur MPASM qui permet de transformer un fichier ASM en fichier O le compilateur MCC18 qui permet de transformer un fichier C en un fichier O le linkeur MPLINK qui permet de fusionner tous les fichiers O en un unique fichier HEX Le fichier dit script du linkeur (File.lkr sur le schma ci-dessus) est essentiel pour permettre de gnrer le fichier HEX. En effet le contenu des fichiers O ne permet pas encore de savoir o va tre log le code en mmoire. Par exemple la fonction main() a t traduite en un langage comprhensible par le PIC18 mais pas encore positionn un endroit prcis de la mmoire. Cest le rle du script du linkeur que de prciser les emplacements de chaque portion de code en ROM et chaque portion de variable en RAM. PICos18 est fourni avec des scripts de linker pr-tabli pour les PIC les plus utiliss de la famille PICos18. Vous pouvez vous en inspirer pour raliser votre propre script ou bien pour ladapter un nouveau PIC18. Il existe dautres types de fichiers gnrs pendant la compilation et lassemblage des fichiers du projet (*.map, *.lst, *.cod). Rfrez vous aux documents Microchip pour de plus amples informations. Ce tutorial est destin la comprhension et la prise en main du logiciel PICos18. Pour des raisons techniques, il a t ralis sous MPLAB et compil avec le compilateur C18 pour cible PIC18F452. Nous tenons prciser que ce tutorial a t entirement ralis et test sous le systme dexploitation Microsoft Windows 98/NT/2K/XP, ainsi quavec lenvironnement de dveloppement MPLAB v7.00 et le compilateur C18 v2.40 de Microchip (version gratuite). Ces diffrents logiciels peuvent tre tlchargs depuis le site web de Microchip Technology Inc. : www.microchip.com.

La socit Pragmatec
Ce tutorial est la proprit de PRAGMATEC S.A.R.L. PICos18 est un produit de la socit PRAGMATEC distribu gratuitement sous licence GPL. La socit PRAGMATEC dveloppe et distribue des extensions de PICos18 afin de permettre aux dveloppeurs de raliser leurs applications laide briques logicielles (driver RS232, driver bus CAN pour utiliser le contrleur de protocole CAN du PIC18F458, USB, I2C, etc). PRAGMATEC propose aussi un ensemble de logiciels de plus haut niveau pour la mise en uvre de PICos18, permettant par exemple le contrle et le debug des tches distance, via RS232 ou CAN

10 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

2. PICOS18 : Tutorial
L'objectif de ce tutorial est de montrer comment simplement programmer avec PICos18. La norme OSEK dfinit non seulement les fonctionnalits du noyau, mais aussi la faon dont il doit tre interfac; avec les programmes utilisateurs. Suivez ce tutorial pour apprendre configurer MPLAB utiliser PICos18 et programmer des applications multi-tches sur PIC18.

L'environnement de dveloppement
Dans ce premier chapitre vous mettrez au point un projet bas sur PICos18. Pour cela vous manipulerez l'environnement de dveloppement MPLAB de Microchip ainsi que le compilateur C18.

Cration d'une premire tche


Maintenant que le dcor est plant il est temps de crer et de simuler une premire tche. Vous apprendrez comment l'crire et comment la dclarer au noyau. De plus vous dcouvrirez les alarmes et le tick systme 1ms.

La premption
L'application mono-tche que vous venez de raliser n'a que trs peu de raison d'tre... En ajoutant votre application une seconde tche vous dcouvrirez les mcanismes de premption d'une tche sur l'autre.

Le multi-tches
Ce chapitre prsente les mcanismes de synchronisation entre tches de PICos18. Une troisime tche viendra complter l'application et postera un vnement une autre tche afin de l'activer. Vous apprendrez utiliser les vènements et à partager les ressources.

Les interruptions
Afin de pouvoir tirer parti du microcontrleur PIC18, il est important de pouvoir utiliser les priphriques. De ce point de vue, les interruptions sont essentielles. Vous verrez comment les interruptions du PIC18 sont mises en uvre sous PICos18 et comment crire simplement vos propres routines d'interruption.

11 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Utilisation des drivers


Vous souhaitez faire communiquer votre application au travers du port série ou bien du port CAN ? A présent que vous savez écrire des interruptions et des tâches, et que vous maîtrisez la gestion des évènements et des alarmes, il vous sera facile d'utiliser ou d'écrire un véritable driver pour PICos18.

Exemple d'application
Le tutorial se termine ici par un exemple complet d'application. Les sources de cet exemple sont fournis dans le répertoire /Project/Tutorial de PICos18, ceci vous permettant d'apprécier à quel point il est aisé d'écrire une application pour PIC18 avec PICos18.

12 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

3. L'environnement de dveloppement
Dans ce premier chapitre vous mettrez au point un projet bas sur PICos18. Pour cela vous manipulerez l'environnement de dveloppement MPLAB de Microchip ainsi que le compilateur C18.

> Les sources du projet


Avant de lancer MPLAB tlchargez les sources du tutorial depuis www.picos18.com (section DOWNLOAD), comprenant les fichiers sources du noyau et de l'application. Voici quoi correspond chacun de ces fichiers :

13 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Include

Comme son nom l'indique ce rpertoire contient l'ensemble des headers du noyau PICos18. Les headers propres l'application et aux drivers se trouveront dans les rpertoires propres aux applications (sous Project). Il existe un header spcifique pour chaque sous-ensemble du noyau : alarmes, vnements, interruption et processus. Le fichier device.h contient les dfinitions gnriques du noyau comme les dfinitions des valeurs de retour des fonctions du noyau. Vous trouverez sous ce rpertoire toutes les sources du noyau. Les fichiers C correspondent aux services du noyau (l'API), et le fichier kernel.asm, seul fichier assembleur de PICos18, runit l'ensemble des fonctions propres au noyau, c'est-dire les algorithmes de scheduler, l'ordonnancement des tches et le gestionnaire d'erreurs. Les sources sont fournies titre d'information ou si vous souhaitez les modifier pour vos besoins propres. Pour vous permettre d'utiliser PICos18 plus facilement, nous y avons ajouter le noyau sous forme de librairie : picos18.lib. De plus les codes d'amorce du compilateur (runtime) fournis par Microchip ne sont pas adapts PICos18, nous avons donc choisi de les adapter en consquence. Ils sont fournis sous forme de fichier .o (comme PICos18iz.o). Vous n'avez pas vous souciez de la librairie picos18.lib et des fichiers d'amorce, ils sont automatiquement associs votre projet par PICos18 ! Lorsque vous construisez votre application avec PICos18, vous crivez votre code en langage C. Par la suite il convient de compiler votre application avec C18 (crer chaque fichier .o correspondant chaque fichier .c) puis de les lier entre eux l'aide du linker. La faon de lier les fichiers .o est paramtrable, et elle est dcrite dans les fichiers .lkr de ce rpertoire. Pour chaque type de processeurs remarquables dans la famille PIC18, il est fourni un fichier lkr pour vous viter de grer cette partie dlicate de l'tape de compilation. Pour chaque nouveau PIC18 gr par un PICos18, un nouveau script de linker se verra ajouter ce rpertoire au fil du temps. Ce rpertoire contient les fichiers ncessaires la cration de tout projet avec PICos18. Comme vous pouvez le constater il n'y a que trs peu de fichiers : le main.c qui est le premier fichier applicatif excut par PICos18, le fichier int.c qui rassemble les routines d'interruptions et d'interruptions rapides, le fichier taskdesc.c qui dcrit prcisment tous les lments de votre application (alarmes, compteurs, caractristiques de vos tches, ...), et un fichier C par tche de l'application. Le tutorial s'appuie sur la ralisation d'une application type sous PICos18. Tout au long des diffrents chapitres vous allez dcouvrir comment programmer sous PICos18 et comment construire vos applications. Les fichiers prsents sous ce rpertoire sont ceux de l'application finale, une fois termine. Ceci apporte un support concret ce tutorial en vous fournissant le code source de l'application de test.

Kernel

Linker

Project/MyApp

Project/Tutorial

D zippez l'ensemble des sources directement sous C:\. Le reste du tutorial supposes que le rpertoire PICos18 se trouve bel et bien sous C:\. Dans le cas contraire, effectuez par vous mme les rectifications qui s'imposent.

14 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Ce tutorial est pour le moment destin un dveloppement sous MPLAB / Windows et a t valid sous MPLAB v6.62 et v7.00, et le compilateur C de Microchip en version 2.40. Vous pouvez tlchargez les versions gratuites de ces outils depuis le site de Microchip. La version gratuite de C18 correspond une version sans gestion des optimisation par le compilateur, or il ne faut surtout pas utiliser les optimisations de C18 avec PICos18, certaines n'tant pas adapts dans le cadre d'une utilisation multi-tches. C18 en version gratuite est donc un compilateur qui convient parfaitement pour PICos18 et les PIC18, le code assembleur gnr tant parfaitement optimis pour les composants PIC18. Le composant cible est un PIC18F452 (n'oubliez pas de slectionner le composant sous MPLAB).

> Compilateur C18

Commencez par installer MPLAB et le compilateur Microchip pour PIC18 en version gratuite. Par dfaut nous supposons que le chemin d'installation est "C:\mcc18\".

Sous MPLAB, cliquez sur "Project / Set Language Tool Location..." et paramtrez MPASM, MPLAB C18 et

MPLINK.

> Cration de projet


Puis crer un nouveau projet toujours sous MPLAB. Cliquez sur "Project / New..." et nommez votre projet avec un nom de moins de 8 caractres. Attention le chemin du rpertoire du projet ne doit pas contenir d'espace !! Puis cliquez sur "Project / Toolsuite..." et slectionnez Toolsuite". Select Language "Microchip C18

15 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Les options du projet


Cliquez sur "Project / Build Options..." et prcisez les chemins d'inclusion et celui des librairies du compilateur comme du noyau. Attention ne pas mettre d'espace entre chaque chemin ! Ensuite slectionnez l'onglet "MPLAB C18" et cochez l'option "Use alternate settings" et ajouter l'option "-On-" dans la ligne de commande. Ceci pour effet d'viter l'optimisation des slections de bank, non fonctionnelle dans le cas de PICos18.

> Complter le projet


Puis l'aide du bouton droit de la sourie, ajoutez les fichiers suivants : - int.c, main.c, tascdesc.c et tsk_task0.c prsents sous MyApp - define.h prsent sous MyApp - 18f452.lkr prsent sous le rpertoire Linker Les fichiers picos18.lib et PICos18iz.o seront trouvs par la chane de compilation automatiquement.

> Compilation du projet


Compiler le projet en appuyant sur F10. Le compilateur va compiler un un les fichiers C de votre application. Il ne compilera pas les fichiers du noyau PICos18, la librairie tant fournie. Enfin le linker associ tous les fichiers .o du projet pour crer les fichiers ncessaires la simulation et la programmation.

16 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Dvalider le Watchdog


La simulation sous MPLAB est base sur les paramtres des bits de configuration du PIC18. Paramtrez votre simulation comme indiqu sur la capture d'cran. Le watchdog doit tre obligatoirement dvalid.

> Simulation du projet


Finalement lancez la simulation en cliquant sur "Debugger / Select Tool / MPLAB SIM", puis F9 (Run). Attendez quelques secondes avant d'appuyez sur F5 (Stop). La simulation a du s'arrter sur l'instruction "while(1)" de la tche 1 comme le montre l'image de droite. Pour autant cette instruction ne bloque pas le PIC18 dans une boucle infinie, car si besoin le noyau peut fonctionner, celui-ci ayant toujours la main sur l'application : essayez plusieurs tentatives pour vous arrter dans une partie du noyau. Le fichier source du noyau dans lequel vous tes arrt va apparatre l'cran. Pourtant les sources de PICos18 n'ont jamais t ajoutes au projet MyApp ! En ralit, ceci est du au fait que vous avez positionnez PICos18 sous C:\ et que la librairie a t compile selon ce chemin prcis...

17 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

4. Cration dune premire tche


Maintenant que le dcor est plant il est temps de crer et de simuler une premire tche. Vous apprendrez comment l'crire et comment la dclarer au noyau. De plus vous dcouvrirez les alarmes et le tick systme 1ms.

> Pr-requis
Tout d'abord il est ncessaire d'avoir cr un projet sous MPLAB, projet qui contient les sources de PICos18. Ensuite il faudra avoir install le compilateur C18 de Microchip, ainsi que l'avoir paramtr (chapitre prcdent).

> Etat d'une tche


Dans l'tat actuel notre projet ne comporte qu'une seule tche dfinie dans le fichier "tsk_led.c" :
TASK(TASK0) { while(1); }

On comprend facilement que le rle de la tche est de crer une boucle infinie. Sous MPLAB, placer un point d'arrt (breakpoint) sur la ligne en face de l'instruction "while(1);", puis lancer la simulation (F9). Vous constaterez que la simulation s'arrte sur votre breakpoint. Mais comment fait le noyau pour connatre l'existence de votre tche, excuter son code, s'arrter sur la boucle infinie ... et pour autant ne pas tre bloque par cette instruction ? En fait la tche a t dclare auprs du noyau dans le fichier "tascdesc.c".
/********************************************************************** * ----------------------------- task 0 -----------------------------**********************************************************************/ rom_desc_tsk rom_desc_task0 = { TASK0_PRIO, /* prioinit from 0 to 15 */ stack0, /* stack address (16 bits) */ TASK0, /* start address (16 bits) */ READY, /* state at init phase */ TASK0_ID, /* id_tsk from 1 to 15 */ sizeof(stack0) /* stack size (16 bits) */ };

18 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Sur la ligne en gras vous pouvez indiquer l'tat de la tche lors de son initialisation. En effet mme si une tche existe dans le projet (elle a t compile par le compilateur), elle n'est pas forcment active. Dans PICos18, au respect de la norme OSEK, une tche possde 4 tats possibles : SUSPENDED : la tche est prsente dans le projet, mais n'est pas prise en compte par le noyau. READY : la tche est prte tre active par le noyau, qui dsormais la prend en compte. WAITING : la tche est en sommeil, elle est temporairement SUSPENDED et sera READY ds qu'un vnement viendra la rveiller. RUNNING : parmi toutes les tches prtes, c'est celle-ci qui occupe la processeur pendant un temps T. En ce qui concerne votre tche, elle se trouve en fait dans l'tat READY. Tant qu'elle y restera, le noyau pourra y accder... Remplacer READY par SUSPENDED dans le fichier tascdesc.c, recompilez et relancez la simulation: vous constaterez que la simulation ne s'arrte plus sur le breakpoint.

> Description des tches


Tout comme l'tat de la tche, de nombreuses choses sont dcrites dans le fichier tascdesc.c. En fait tout ce qui concerne votre application se trouve dans ce fichier, comme par exemple : l'identifiant de la tche, sa priorit, sa pile logicielle, les alarmes ncessaires au projet, ... On trouve tout d'abord la liste des alarmes de l'application:
AlarmObject Alarm_list[] = { /******************************************************************* * -------------------------- First task --------------------------*******************************************************************/ { OFF, /* State */ 0, /* AlarmValue */ 0, /* Cycle */ &Counter_kernel, /* ptrCounter */ TASK0_ID, /* TaskID2Activate */ ALARM_EVENT, /* EventToPost */ 0 /* CallBack */ }, };

19 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Ce tableau constitue la liste des alarmes, chaque alarme tant reprsente par une structure. Une alarme est une sorte d'objet TIMER gr de faon logicielle par le noyau. En fait PICos18 possde une rfrence de temps de 1ms, gnre de faon hardware et logicielle. De cette faon il est possible de crer une alarme logicielle base sur cette base de temps de 1ms : les alarmes. Une alarme est associ un compteur (ici Counter_kernel qui est la rfrence de 1ms) et une tche (dont l'identifiant est TASK0_ID). Lorsque l'alarme atteint une valeur de seuil elle peut poster un vnement cette tche (ALARM_EVENT dans cet exemple) ou bien appeler une fonction en C (mcanisme de CallBack). On trouve ensuite la liste des ressources de l'application:
/********************************************************************** * --------------------- COUNTER & ALARM DEFINITION ------------------**********************************************************************/ Resource Resource_list[] = { { 10, /* priority */ 0, /* Task prio */ 0, /* lock */ } };

Une ressource est un autre objet gr par le noyau. Une ressource est gnralement un priphrique partag par plusieurs tches, par exemple un port 8 bits du PIC18. Elle possde une priorit (priority) et peut tre verrouille (lock) par une tche (Task prio). Ainsi lorsqu'une tche veut avoir accs au port 8 bits, elle y accde via la ressource dfinie et empche ainsi pendant un cours instant toute autre tche d'y avoir accs. Les ressources seront vu dans le chapitre li au multi-tches.

On trouve ensuite la liste des piles logicielles de l'application: Il existe 2 types de variables : les variables statiques et les variables automatiques...de faon plus comprhensible nous parlerons de variables globales et de variables locales, mme si la correspondance n'est pas tout fait exacte. Les variables globales (c'est--dire places en dehors de toutes fonctions C) sont places en RAM une adresse absolue, adresse qui ne change jamais. Les variables locales (dclares au sein de fonctions C) sont elles compiles par C18 de sorte de se retrouver stocker dans une zone mmoire dite pile logicielle. Une pile logicielle est une zone mmoire dynamique, vivante en quelques sortes. Lorsque l'on rentre dans une fonction C, on commence par empiler sur cette zone les variables locales, et lorsque l'on quitte la fonction C, on dpile l'espace rserv aux variables locales librant ainsi de la mmoire. Ce type de fonctionnement permet de gagner beaucoup de place mmoire lorsqu'il existe de nombreuses fonctions crites en C, au prix d'un surplus de code minimal.

PICos18 est compatible avec la gestion de la pile logicielle faite par C18. Chaque tche possde alors sa propre pile logicielle, si bien que chacune des tches de l'applicaiton peut travailler de faon autonome dans son propre espace de travail, sans perturber les autres tches. De plus PICos18 possde un mcanisme de dtection de dbrodement mmoire, ce qui arrive lorsqu'une pile logicielle commence dborder sur celle d'une autre tche (kernelpanic).

20 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

/********************************************************************** * ----------------------- TASK & STACK DEFINITION -------------------**********************************************************************/ #define DEFAULT_STACK_SIZE 128 DeclareTask(TASK0); volatile unsigned char stack0[DEFAULT_STACK_SIZE];

Chaque fois que vous ajoutez une tche votre application, pensez ajouter une pile en copiant la ligne ci-dessus en en changeant le nom de la nouvelle pile (par stack1 par exemple).

Une taille de pile minimale sous PICos18 est 64. Une taille de pile maximale est 256. Une taille de pile raisonnable est 128.

Seules ces 3 valeurs sont possibles, n'essayez pas d'utiliser une taille de valeur intermdiaire, la compilateur C18 ne pourrait pas la grer. De plus une pile doit toujours se trouver sur une mme bank, et pas cheval sur 2 banks. En cas de doutes, laissez toutes vos tailles de pile 128. On trouve ensuite la liste des tches de l'application:
/********************************************************************** * ----------------------------- task 0 -----------------------------**********************************************************************/ rom_desc_tsk rom_desc_task0 = { TASK0_PRIO, /* prioinit from 0 to 15 */ stack0, /* stack address (16 bits) */ TASK0, /* start address (16 bits) */ READY, /* state at init phase */ TASK0_ID, /* id_tsk from 1 to 15 */ sizeof(stack0) /* stack size (16 bits) */ };

Nous avons dj abord le descripteur de tche, voici plus en dtail le sens de chaque champ :

prioinit : c'est la priorit de la tche comprise entre 1 et 15 inclus. 1 est la priorit la plus faible et 15 la plus forte. La priorit 0 est rserve au noyau lui-mme. stack address : c'est la la pile logicielle de la tche. Chaque tche possde une pile logicielle sur laquelle seront stocke les variables locales au cours de l'excution, mais aussi tout le contexte du PIC18 (registres, pile hardware) lorsque la tche n'est pas en cours d'excution. start address : c'est le nom de votre tche, ou encore le nom de la fonction d'entre de votre tche. Le compilateur le traduit en une adresse, utilise par le noyau pour accder la premire fois votre tche. state init : c'est l'tat initial de votre tche. Dans notre cas il vaut READY ce qui signifie que la tche est oprationnelle au dmarrage de l'application. stack size : c'est la taille de la pile logicielle attribue. Cela sert au noyau afin de vrifier tout moment qu'il n'y a aucun dbordement mmoire d'une pile sur l'autre.

21 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Interruptions 1ms


Mme si votre application ne ncessite pas le besoin de grer des interruptions, vous aurez certainement besoin de l'horloge logicielle interne de 1 ms. Pour cela le fichier "int.c" contient un certains nombres de dfinition, y compris la routine de gestion d'interruption. Elle est en fait trs simple et vous dispense de toute la gestion dlicate des ITs sur PIC18 :
#pragma code _INTERRUPT_VECTORL = 0x003000 #pragma interruptlow InterruptVectorL save=section(".tmpdata"), PROD void InterruptVectorL(void) { EnterISR(); if (INTCONbits.TMR0IF == 1) AddOneTick(); /*Here is the next interrupts you want to manage */ /*if (INTCONbits.RBIF == 1) */ /* MyOwnISR(); */ LeaveISR(); } #pragma code

Comme vous pouvez le comprendre aisment, lorsque l'interruption du TIMER0 se lve (flag TMR0IF) on appelle la fonction AddOneTick qui ajouter 1 ms toutes les alarmes de l'application. Lorsque certaines ont atteint leur seuil critique, elle dclenche des actions auprs des tches associes en transitant par le noyau, seule entit du systme tre autorise dclenche des tches. Vous voyez donc que le noyau est toujours actif et qu'aucune tche ne peut le stopper, mme avec une boucle infinie du type "while(1)".

Pour le vrifier, paramtrez votre simulation 40MHZ (Debugger/Settings..), placez un breakpoint en face de l'instruction AddOneTick(), et affichez la stopwatch de MPLAB (Debbuger/Stopwatch) :

22 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Dmarrage de l'application


Enfin votre application possde aussi un fichier "main.c" ncessaire au compilateur. Selon la norme OSEK ce fichier main ne fait pas parti de l'OS mais bel et bien de la partie applicative, et c'est lui que revient le rle de lancer le noyau (car il est en effet possible de stopper et de lancer le noyau depuis le fichier main). Dans le fichier main vous trouverez une fonction Init() qui va vous permettre de paramtrer votre frquence de fonctionnement sans avoir besoin d'ouvrir la datasheet du PIC18 :
void Init(void) { FSR0H = 0; FSR0L = 0; /* User setting : actual PIC frequency */ Tmr0.lt = _40MHZ; /* Timer OFF - Enabled by Kernel */ T0CON = 0x08; TMR0H = Tmr0.bt[1]; TMR0L = Tmr0.bt[0]; }

La ligne en gras vous permet de rgler la frquence INTERNE du PIC18. En effet celui-ci possde une PLL par 4, que vous pouvez activer ou non. Une utilisation classique des PIC18 consiste les quiper d'un quartz externe de 10 MHz et de 2 capacits de 15 pF, puis d'activer la PLL interne afin d'obtenir une frquence interne de 40 MHz. Le pipeline interne du processeur tant de niveau 4, le pire cas de fonctionnement du PIC18 est de 10 MIPS, soit 10 millions d'instructions par secondes (voir la datasheet du composant). Cela en fait un microcontrleur 8 bits faible cout puissant et bien arm en priphrique. Si vous souhaitez utiliser une frquence diffrente, consulter les frquences disponibles dans le fichier "define.h".

23 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

5. La premption
L'application mono-tche que vous venez de raliser n'a que trs peu de raison d'tre... En ajoutant votre application une seconde tche vous dcouvrirez les mcanismes de premption d'une tche sur l'autre.

> Rveil priodique d'une tche


Il est encore difficile de se rendre compte de l'intrt d'un noyau lorsqu'on utilise qu'une seule tche pour... boucler l'infini ! Nous allons donc commencer rendre un peu plus intressante notre tche en lui faisant clignoter une LED une certaine frquence. Modifier le code de la tche comme suit :
TASK(TASK0) { TRISBbits.TRISB4 = 0; LATBbits.LATB4 = 0; SetRelAlarm(ALARM_TSK0, 1000, 200); while(1) { WaitEvent(ALARM_EVENT); ClearEvent(ALARM_EVENT); LATBbits.LATB4 = ~LATBbits.LATB4; } }

Notre tche est ici compose de 2 squences : une qui prcde le "while(1)" qui correspond la phase d'initialisation de la tche, et une autre qui se trouve dans le corps du while. Les 2 premires instructions vous permettent de manipuler les ports d'entres/sorties du PIC18. Le mot clef "TRISx" permet de mettre un port en entre ou en sortie, alors que le mot clef "TRISxbits" qui est une structure permet de modifier l'tat d'un bit de port. Ici nous avons donc mis le port RB4 en sortie (d'o le "0", un "1" signifiant "entre") et sa valeur de sortie "0" (mot clef LATxbits).

Ensuite la fonction SetRelAlarm est utilise pour programmer l'alarme de la tche. Dans le chapitre prcdent, nous avons vu ce qu'tait une alarme : un objet TIMER bas sur une horloge logicielle 1ms.

24 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Dans le fichier "tascdesc.c" nous avons vu que l'alarme dont l'ID vaut 0 (ALARM_TSK0) a t associe la tche TASK0 :
AlarmObject Alarm_list[] = { /******************************************************************* * -------------------------- First task --------------------------*******************************************************************/ { OFF, /* State */ 0, /* AlarmValue */ 0, /* Cycle */ &Counter_kernel, /* ptrCounter */ TASK0_ID, /* TaskID2Activate */ ALARM_EVENT, /* EventToPost */ 0 /* CallBack */ }, };

La fonction SetRelAlarm possde 3 champs :


Alarm ID : indice de l'alarme dans le tableau Alarm_list TIMER 1: nombre de millisecondes avant le premier vnement post TIMER 2: nombre de millisecondes entre 2 vnements successifs

Dans notre cas cela signifie que l'alarme 0 va attendre 1000ms avant de poster l'vnement ALARM_EVENT, puis le postera priodiquement toutes les 200 ms. Une fois l'alarme programme, le code de la tche peut continuer s'excuter. Dans le "while(1)", la premire fonction appele est la fonction WaitEvent, qui permet de mettre en sommeil la tche jusqu' l'arrive de l'vnement attendu, ici ALARM_EVENT. Vous pouvez mettre votre tche en attente sur n'importe quel vnement, l'important tant de le dfinir comme une puissance de 2 dans le fichier "define.h". Les valeurs autorises sont donc : 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02 et 0x01.

> Simulation de la tche 0


Pour vrifier que nous avons bel et bien ralis une tche de clignotement une priode de 200ms, il est possible de simuler l'application en plaant un breakpoint en face de la ligne de pilotage du port RB4:

25 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

De plus vous pouvez espionner les priphriques du PIC18 ou bien les variables globales de PICos18, en particulier "global_counter" qui est un compteur dcimal du nombre de millisecondes coules. Pour obtenir une affichage en dcimal de la valeur cliquer l'aide du bouton droit de la souris sur la variable de votre choix et choisissez un affichage "Dec". En faisant des RUN successif (F9), vous verrez le PORTB passer de 0x00 0x10, et la valeur de global_counter s'incrmenter de 200 en 200, en commenant par la valeur 1001 (le noyau met 1ms booter, d'o la valeur de 1001 au lieu de 1000 attendue au premier abord). Cela signifie que le port RB4 passe 1 au bout de 1 seconde puis oscille priodiquement toutes les 200ms. Modifiez prsent les valeurs des paramtres de temps de la fonction SetRelAlarm pour connatre leur effet. Mettez par exemple 0 dans le dernier champ, vous verrez alors que le port RB4 reste 1 et qu'on ne rentre plus jamais dans la tche. Consultez le PDF relatif l'API du noyau PICos18 pour tout connatre des fonctions utilises par la tche.

> Cration d'une seconde tche


Maintenant que nous avons ralis une tche priodique, nous allons crer une seconde tche et les synchroniser. 1) Sous MPLAB, enregistrez le fichier "tsk_task0.c" sous le nom "tsk_task1.c" 2) Modifiez les rfrences la nouvelle tche dans le fichier taskdesc.c, comme suit :
#define DEFAULT_STACK_SIZE DeclareTask(TASK0); DeclareTask(TASK1); 128

volatile unsigned char stack0[DEFAULT_STACK_SIZE]; volatile unsigned char stack1[DEFAULT_STACK_SIZE]; /********************************************************************** * ---------------------- TASK DESCRIPTOR SECTION --------------------**********************************************************************/ #pragma romdata DESC_ROM const rom unsigned int descromarea; /********************************************************************** * ----------------------------- task 0 -----------------------------**********************************************************************/ rom_desc_tsk rom_desc_task0 = { TASK0_PRIO, /* prioinit from 0 to 15 */ stack0, /* stack address (16 bits) */ TASK0, /* start address (16 bits) */ READY, /* state at init phase */ TASK0_ID, /* id_tsk from 1 to 15 */ sizeof(stack0) /* stack size (16 bits) */ }; /********************************************************************** * ----------------------------- task 1 -----------------------------**********************************************************************/ rom_desc_tsk rom_desc_task1 = { TASK1_PRIO, /* prioinit from 0 to 15 */ stack1, /* stack address (16 bits) */ TASK1, /* start address (16 bits) */ READY, /* state at init phase */ TASK1_ID, /* id_tsk from 1 to 15 */ sizeof(stack1) /* stack size (16 bits) */ };

26 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

3) Puis changez le corps de la fonction de la tche 1 par le code suivant :


unsigned char hour, min, sec; /********************************************************************** * ------------------------------ TASK1 ------------------------------* * Second task of the tutorial. * **********************************************************************/ TASK(TASK1) { hour = min = sec = 0; while(1) { WaitEvent(TASK1_EVENT); ClearEvent(TASK1_EVENT); sec++; if (sec == 60) { sec = 0; min++; if (min == 60) { min = 0; hour++; } } } }

Comme vous l'avez trs certainement compris cette tche permet de crer un chronomtre en heure/minute/seconde : chaque fois que la tche est rveille, la variable des secondes est incrmente de 1, et les variables min et hour sont mises jour en consquence.

4) Il parat donc vident que la tche doit tre appele toutes les 1000ms. Modifiez la tche 0 pour quelle poste un vnement toutes les secondes notre nouvelle tche :

SetRelAlarm(ALARM_TSK0, 1000, 1000); while(1) { WaitEvent(ALARM_EVENT); ClearEvent(ALARM_EVENT); LATBbits.LATB4 = ~LATBbits.LATB4; SetEvent(TASK1_ID, TASK1_EVENT); }

27 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

5) Il faut renseigner le compilateur sur les nouveau symboles que nous avons ajouts l'aide du fichier "define.h".
/*********************************************************************** * ----------------------------- Events -------------------------------**********************************************************************/ #define ALARM_EVENT 0x80 #define TASK1_EVENT 0x10 /*********************************************************************** * ----------------------------- Task ID ------------------------------**********************************************************************/ #define TASK0_ID 1 #define TASK1_ID 2 #define TASK0_PRIO #define TASK1_PRIO 7 6

6) Enfin il faut ajouter la nouvelle tche au projet ("Project/Add files to Project..."). Vous pouvez dsormais recompiler le projet (F10).

> Simulation de la tche 1


Afin de vrifier que les variables hour, min et sec sont bien mise jour sur une base de 1 seconde, lancez la simulation avec les breakpoints suivants :

simulation de 1 seconde demande beaucoup de temps MPLAB donc si vous souhaitez tester les variables min et hour lorsqu'elles atteignent 60, il vous faudrait modifier l'ALARM_TASK0 pour qu'elle soir plus rapide, au m

28 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

oins pour le temps de la simulation.

> La premption
Votre application est dsormais compose de 2 tches, elle est donc proprement parler multitches. Pourtant cela ne veut pas dire que les 2 tches fonctionnent en mme temps, c'est parfaitement impossible pour le processeur du PIC18 qui ne peut excuter qu'un seul code la fois. Tout au plus les tches fonctionnent en parallle, c'est--dire l'une aprs l'autre en fonction d'un certain nombre de rgles dfinis par le noyau, notamment les priorits. Pour bien comprendre les notions de premption, de multi-tches et de temps-rel, placez des breakpoints comme ci-dessous et lancer la simulation :

Le pointeur parcourt les breakpoints dans l'ordre suivant :


WaitEvent dans la tche 0 SetEvent dans la tche 0 WaitEvent dans la tche 0 ClearEvent dans la tche 1

En fait cela s'explique par le fait que la tche 0 est plus prioritaire que la tche 1, donc lorsqu'elle aura post un vnement la tche 1, elle continuera s'excuter jusqu' ce qu'elle soit mise en sommeil par le WaitEvent. Du coup la tche 1 le champ libre pour pouvoir s'excuter et le pointeur s'arrte sur le breakpoint du ClearEvent. Maintenant modifiez la priorit de la tche 1 dans le fichier "define.h" pour qu'elle soit la plus prioritaire :
/*********************************************************************** * ----------------------------- Task ID ------------------------------**********************************************************************/ #define TASK0_ID 1 #define TASK1_ID 2 #define TASK0_PRIO #define TASK1_PRIO 7 10

29 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Recompilez et relancez la simulation, dsormais l'ordre de passage des breakpoints sera le suivant :

WaitEvent dans la tche 0 SetEvent dans la tche 0 ClearEvent dans la tche 1 WaitEvent dans la tche 0

Comme la tche 1 est dsormais plus prioritaire, lorsqu'un vnement lui est assign, la tche en cours est immdiatement suspendue pour permettre la tche de plus forte priorit de s'excuter : on dit qu'il y a eu premption (qui signifie prendre la main). La premption est une des caractristiques fondamentales des systmes multi-tches temps rels. En effet dans un systme non premptif, la tche 0 aurait continu de s'excuter jusqu' se mettre en sommeil pour permettre la tche 1 de fonctionner. On dit alors qu'un tel systme est coopratif, c'est--dire que c'est la tche en cours de fonctionnement de dcider quand rendre la main au reste de l'application. Le systme SALVO qui existe pour PIC18 est un bon exemple de systme coopratif. Certes dans notre cas, cel n'a pas trop de consquence, l'application semble fonctionner de faon identique. Toutefois lorsqu'il s'agit de grer des protocoles de communication complexes ou bien lorsque l'application comporte de nombreuses tches, un systme premptif garantit le bon fonctionnement de l'application, quelque soit la taille du code. Pourtant la premption n'est un critre suffisant pour qualifier un systme temps rel. Il est ncessaire d'y ajouter le dterminisme, c'est--dire la capacit garantir que le temps ncessaire pour passer d'une tche l'autre est une constante. Dans PICos18 elle vaut 50 s, ce qui veut dire qu'une fois que la tche 0 poste l'vnement la tche 1, le passage de la tche 0 la tche 1 prend 50 s. PICos18 est donc un systme premptif, multi-tches et temps rel qui garantit qu'une tche de plus forte priorit s'excutera immdiatement si un vnement lui est associ, et ceci dans un dlai de 50 s quelque soit l'application. Vous comprendrez donc qu'une boucle infinie "while(1);" dans la tche la plus prioritaire de votre application blockera toute votre application. Essayez en simulation !

30 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

6. Le multi-tches
Ce chapitre prsente les mcanismes de synchronisation entre tches de PICos18. Une troisime tche viendra complter l'application et postera un vnement une autre tche afin de l'activer. Vous apprendrez utiliser les vnements et partager les ressources.

> Crations d'une tche de fond


Dans les chpitres prcdents nous avons cr un systme compos de 2 tches en charge de la gestion d'une horloge au travers des variables hour, min et sec. Le multi-tches de PICos18 ne permet pas seulement de dcouper un projet en plusieurs tches distinctes afin d'en rduire la complexit mais aussi de coder des sous-ensembles compltement indpendant. Nous allons par exemple crer 2 nouvelles tches qui auront pour fonction d'inspecter en permanence les ports RB0 et RB1, correspondant 2 boutons poussoirs. Un bouton poussoir n'est pas un signal numrique qui passe de l'tat 0 l'tat 1 et y reste jusqu'au prochain changement d'tat. Lorsqu'on appuie sur un bouton poussoir (lment mcanique) il se produit des micro-rebonds, de quelques millisecondes, avant de stabiliser le signal 1. Il importe donc de raliser un code qui dcle l'tat haut stable pour pouvoir vraiment dterminer si le bouton est press ou non.

Nous allons donc commencer par crer une premire tche qui va servir inspecter le port RB0 sur lequel doit se trouver le bouton BTN0. 1) Sous MPLAB, enregistrez le fichier "tsk_task0.c" sous le nom "tsk_task2.c" 2) Modifiez les rfrences la nouvelle tche dans le fichier taskdesc.c, comme suit :
#define DEFAULT_STACK_SIZE DeclareTask(TASK0); DeclareTask(TASK1); DeclareTask(TASK2); 128

volatile unsigned char stack0[DEFAULT_STACK_SIZE]; volatile unsigned char stack1[DEFAULT_STACK_SIZE]; volatile unsigned char stack2[DEFAULT_STACK_SIZE]; /********************************************************************** * ---------------------- TASK DESCRIPTOR SECTION --------------------**********************************************************************/ #pragma romdata DESC_ROM

...

31 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

/********************************************************************** * ----------------------------- task 1 -----------------------------**********************************************************************/ rom_desc_tsk rom_desc_task2 = { TASK2_PRIO, /* prioinit from 0 to 15 */ stack2, /* stack address (16 bits) */ TASK2, /* start address (16 bits) */ READY, /* state at init phase */ TASK2_ID, /* id_tsk from 1 to 15 */ sizeof(stack2) /* stack size (16 bits) */ };

3) Puis changez le corps de la fonction de la tche 2 par le code suivant :


extern unsigned char hour; /********************************************************************** * ------------------------------ TASK2 ------------------------------* * Third task of the tutorial. * **********************************************************************/ TASK(TASK2) { unsigned int i; while(1) { while(PORTBbits.RB0 == 0); for (i = 0; i < 10000; i++) Nop(); if (PORTBbits.RB0 == 1) hour++; } }

La tche possde une boucle infinie sans aucune attente l'aide d'une fonction WaitEvent. Une telle tche risque donc de bloquer le mcanisme de multi-tches pour les tches moins prioritaire... Elle doit donc possder la priorit la plus faible : on dit que c'est la tche de fond. Elle commence par inspecter le port RB0 et reste dans une boucle infinie tant que la bouton BTN0 n'est pas enfonc. Ds que le bouton est enfonc la tche attend l'aide d'une boucle FOR de faon viter la phase de rebond. Ensuite si il s'avre que le port RB0 vaut bien 1 alors on incrmente de 1 la variable "hour". Ceci permet par exemple de venir paramtrer l'horloge.

4) Il faut renseigner le compilateur sur les nouveau symboles que nous avons ajouts l'aide du fichier "define.h".
/*********************************************************************** * ----------------------------- Task ID ------------------------------**********************************************************************/ #define TASK0_ID 1 #define TASK1_ID 2 #define TASK2_ID 3 #define TASK0_PRIO #define TASK1_PRIO #define TASK2_PRIO 7 10 1

32 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

5) Enfin il faut ajouter la nouvelle tche au projet ("Project/Add files to Project..."). Vous pouvez dsormais recompiler le projet (F10).

> Round robin


Nous allons maintenant crer une seconde tche de fond. En effet PICos18 permet de crer plusieurs tches possdant le mme niveau de priorit. Dans ce cas on peut bien se demander laquelle des 2 peut bien prendre la main sur la seconde pour s'excuter. En fait dans ce cas prcis, le scheduler de PICos18 utilise un algorithme spcifique dit 'Round Robin". Avec un tel algorithme, les tches de fond vont se partager le processeur du PIC18 durant une tranche de temps de 1ms dans notre cas. Comme ces tches sont de faibles priorits, elles s'excuteront uniquement si aucune autre tche n'a besoin de fonctionner et pendant un temps maximum de 1 ms. Ensuite ce sera une autre tche de mme priorit de s'excuter. Crez donc une tche 3 qui possde le mme code ( l'exception prt qu'il s'agit d'inspecter le port RB1) et possdant la mme priorit :
/*********************************************************************** * ----------------------------- Task ID ------------------------------**********************************************************************/ #define TASK0_ID 1 #define TASK1_ID 2 #define TASK2_ID 3 #define TASK3_ID 4 #define #define #define #define TASK0_PRIO TASK1_PRIO TASK2_PRIO TASK3_PRIO 7 10 1 1

33 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

N'oubliez pas d'ajouter le nouveau fichier au projet, puis recompilez (F10).

Placez des breakpoints devant chaque instruction "while(PORTBbits.RBx == 0);", puis lancez la simulation. Vous verrez tout d'abord le pointeur s'arrtez dans la tche 2. Dvalidez alors le breakpoint et poursuivez la simulation, le pointeur s'arrtera alors dans la tche 3 exactement 1ms plus tard... Si maintenant vous mettez des breakpoints dans les tches 0 et 1, vous verrez qu'au bout de 1 seconde, le pointeur s'arrtera dans une de ces 2 tches, il y a eu premption du fait des priorits de ces 2 tches.

> Simulation
Pour simuler l'appuie sur le bouton BTN0, vous pouvez utiliser la fentre de Watch :

Lancez la simulation jusqu'au premier breakpoint de la tche 2. Cliquez dans la fentre de Watch pour passer la valeur du PORTB 0x01. Puis lancez la simulation en vrifiant que le breakpoint de la tche 3 est toujours actif. Vous verrez alors le pointeur s'arrter d'abord dans la tche 3 avant d'atteindre le second breakpoint de la tche 2. En effet au del de 1ms, le scheduler a jug bon de donner la main l'autre tche...

34 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

7. Les interruptions
Afin de pouvoir tirer parti du microcontrleur PIC18, il est important de pouvoir utiliser les priphriques. De ce point de vue, les interruptions sont essentielles. Vous verrez comment les interruptions du PIC18 sont mises en uvre sous PICos18 et comment crire simplement vos propres routines d'interruption.

> Prsentation du fichier int.c


Nous allons prsent brancher nos 2 boutons sur les broches d'interruptions externes du PIC18, ce qui nous permettra de ne traiter les boutons que lorsqu'ils sont utiliss. Tout d'abord nous allons voir de quoi est constitu le fichier "int.c", fichier qui prend en charge la gestion de la totalit des interruptions. Il faut savoir que le PIC18 gre 2 types d'interruptions : les interruptions de basses priorits (IT_vector_low) et celles de hautes priorits (IT_vector_high). A quoi cela peut-il bien servir....?! En fait il faut considrer que le noyau PICos18 effectue parfois des oprations dlicates sur les tches et qu'il n'est pas souhaitable qu'il soit interrompu par un IT pendant son traitement (par exemple pendant la premption d'une nouvelle tche sur la tche courant). Du coup pour faire simple on a choisi de rendre le noyau non-interruptible. Or on a vu que le dterminisme de PICos18 tait de 50s (ce qu'on appelle le temps de latence), donc il exite une zone d'ombre, un black-out de 50 s pendant laquelle une IT ne sera pas dtecte.

Pour viter cela on utilise les interruptions rapides ("fast interrupts") du PIC18, qui utilise un mcanisme hardware pour la sauvegarde des registres lmentaires (comme WREG, STATUS, ...). Hlas pour utiliser les interruptions rapides du PIC18, il faut crire un code C extrmement lger, presque trivial. Si l'on a besoin d'un code plus complexe, qui appelle par exemple d'autres fonctions C, il faut imprativement utiliser les interruptions lentes... avec toutefois le risque d'tre mis en attente pendant 50S !

35 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

/********************************************************************** * Function you want to call when an IT occurs. **********************************************************************/ extern void AddOneTick(void); /*extern void MyOwnISR(void); */ void InterruptVectorL(void); void InterruptVectorH(void); /********************************************************************** * General interrupt vector. Do not modify. **********************************************************************/ #pragma code IT_vector_low=0x18 void Interrupt_low_vec(void) { _asm goto InterruptVectorL _endasm } #pragma code #pragma code IT_vector_high=0x08 void Interrupt_high_vec(void) { _asm goto InterruptVectorH _endasm } #pragma code /********************************************************************** * General ISR router. Complete the function core with the if or switch * case you need to jump to the function dedicated to the occuring IT. **********************************************************************/ #pragma code _INTERRUPT_VECTORL = 0x003000 #pragma interruptlow InterruptVectorL save=section(".tmpdata"), PROD void InterruptVectorL(void) { EnterISR(); if (INTCONbits.TMR0IF == 1) AddOneTick(); /*Here is the next interrupts you want to manage */ /*if (INTCONbits.RBIF == 1) */ /* MyOwnISR(); */ LeaveISR(); } #pragma code /* BE CARREFULL : ONLY BSR, WREG AND STATUS REGISTERS ARE SAVED /* DO NOT CALL ANY FUNCTION AND USE PLEASE VERY SIMPLE CODE LIKE /* VARIABLE OR FLAG SETTINGS. CHECK THE ASM CODE PRODUCED BY C18 /* IN THE LST FILE. #pragma code _INTERRUPT_VECTORH = 0x003300 #pragma interrupt InterruptVectorH void InterruptVectorH(void) { if (INTCONbits.INT0IF == 1) INTCONbits.INT0IF = 0; } #pragma code */ */ */ */

Au premier abord le fichier "int.c" peut paratre bien compliqu, mais il est en fait fort simple. Les 2 seules zones qui peuvent tre soumises modifications sont les fonctions InterruptVectorL() et InterruptVectorH(). Comme dans 99% des cas l'interruption lente sera suffisante pour vos applications, vous n'aurez qu' intervenir dans la fonction InterruptVectorL().

36 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Le mode "fast interrupt"


La fonction du mode "fast interrupt" se prsente comme suit :
/* BE CARREFULL : ONLY BSR, WREG AND STATUS REGISTERS ARE SAVED /* DO NOT CALL ANY FUNCTION AND USE PLEASE VERY SIMPLE CODE LIKE /* VARIABLE OR FLAG SETTINGS. CHECK THE ASM CODE PRODUCED BY C18 /* IN THE LST FILE. #pragma code _INTERRUPT_VECTORH = 0x003300 #pragma interrupt InterruptVectorH void InterruptVectorH(void) { if (INTCONbits.INT0IF == 1) INTCONbits.INT0IF = 0; } #pragma code */ */ */ */

Les interruptions externes INT0 (broche RB0), INT1 (broche RB1) et INT2 (broche RB2) sont par dfaut en mode fast interrupt, c'est--dire que lorsque l'une de ces IT se produit, elle interrompe le code et excute la fonction InterruptVectorH().

L'interruption INT0 n'est pas paramtrable, c'est--dire qu'elle appelle toujours la fonction InterruptVectorH(). Par contre INT1 et INT2 peuvent tre utilises pour appeler la fonction InterruptVectorL(). Pour cela il faut modifier le registre INTCON3 qui permet ce paramtrage au travers des bits INT2IP et INT1IP.

Si nous souhaitons prsent brancher nos 2 boutons sur INT1 et INT2, nous allons devoir traiter le mcanisme d'anti-rebond au sein de la fonction InterruptVectorH(). Or nous avons vu que nous avons pas droit un code trop compliqu, comme l'utilisation de pointeur, aux appels de fonctions, aux boucles FOR et WHILE,... Bref, tout au plus nous avons droit d'incrmenter ou dcrmenter des variables globales...! La raison en est simple : il ne faut pas modifier d'autres registres du PIC18 que les registres WREG, STATUS et BSR. Si vous hsitez entre "low interrupt" et "fast interrupt", inspecter le code gnr par le compilateur pour vrifier qu'il ne modifie pas d'autres registres. Comme nous n'avons pas besoin de traiter l'appuie de nos boutons avec une prcision meilleure que 50s, nous allons donc utiliser le mode "slow interrupt".

37 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Le mode "slow interrupt"


Dans la plupart des traitements d'interruption, le mode "slow interrupt" est largement suffisant. Les 3 seules interruptions qui sont par dfaut en mode "fast interrupt" sont INT0, INT1 et INT2. Comme INT0 ne peut tre dvalid, nous allons utiliser INT1 et INT2 en les reprogrammant en mode "slow interrupt" :

Pour utiliser INT1 et INT2 en mode "slow interrupt", modifiez le registre INTCON3 comme indiqu cidessus dans la phase d'init du main. Puis compltez le fichier int.c pour intercepter les interruptions INT1 et INT2 :
/********************************************************************** * Function you want to call when an IT occurs. **********************************************************************/ extern void AddOneTick(void); extern void MyOwnISR(void); void InterruptVectorL(void); void InterruptVectorH(void); ... /********************************************************************** * General ISR router. Complete the function core with the if or switch * case you need to jump to the function dedicated to the occuring IT. **********************************************************************/ #pragma code _INTERRUPT_VECTORL = 0x003000 #pragma interruptlow InterruptVectorL save=section(".tmpdata"), PROD void InterruptVectorL(void) { EnterISR(); if (INTCONbits.TMR0IF == 1) AddOneTick();

38 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

/*Here is the next interrupts you want to manage */ if (INTCON3bits.INT1IF || INTCON3bits.INT2IF) MyOwnISR(); LeaveISR(); } #pragma code

Il suffit prsent d'ajouter la fonction "MyOwnISR" dans n'importe quel fichier C, de prfrence une des 2 tches de fond qui sont associs aux boutons. Par exemple nous ajoutons la fonction dans le fichier "tsk_task2.c" :
void MyOwnISR(void) { if (INTCON3bits.INT1IF) { INTCON3bits.INT1IF = 0; /* ... */ } if (INTCON3bits.INT2IF) { INTCON3bits.INT2IF = 0; /* ... */ } }

Et n'oubliez pas de dclarer la fonction au dbut du fichier :


#include "define.h" void MyOwnISR(void); /********************************************************************** * Definition dedicated to the local functions. **********************************************************************/ #define ALARM_TSK0 0

Vous pouvez prsent recompiler le projet (F10).

> Association aux tches de fond


Pour le moment la fonction "MyOwnISR" ne permet de faire passer l'information aux tches de fond qu'un des boutons a t enfonc. De plus les tches de fond continuent fonctionner en permanence au travers d'une boucle infinie. Il faudrait pouvoir mettre en sommeil les 2 tches de fond et les rveiller sur interruptions. Pour cela nous allons modifier les 2 tches de fond pour qu'elles soient des tches BASICs. Modifier "tsk-task2.c comme suit :
TASK(TASK2) { unsigned int i; for (i = 0; i < 10000; i++) Nop(); if (PORTBbits.RB1 == 1) hour++; TerminateTask(); }

39 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Comme vous pouvez le constater la tche 2 ne possde plus de "while(1)" et de plus elle se termine par la fonction "TerminateTask()". C'est ce qui caractrise une tche BASIC :

pas d'utilisation de la fonction "WaitEvent()", pas de boucle "while(1)" et l'appel la fonction "TerminateTask()" imprativement la fin.

L'objectif est que la tche soit l'tat SUSPENDED par dfaut puis active l'aide de la fonction "ActivateTask()".

Modifiez donc le fichier "tascdesc.c" pour mettre les tches 2 et 3 SUSPENDED par dfaut :
/********************************************************************** * ----------------------------- task 2 -----------------------------**********************************************************************/ rom_desc_tsk rom_desc_task2 = { TASK2_PRIO, /* prioinit from 0 to 15 */ stack2, /* stack address (16 bits) */ TASK2, /* start address (16 bits) */ SUSPENDED, /* state at init phase */ TASK2_ID, /* id_tsk from 1 to 15 */ sizeof(stack2) /* stack size (16 bits) */ }; /********************************************************************** * ----------------------------- task 3 -----------------------------**********************************************************************/ rom_desc_tsk rom_desc_task3 = { TASK3_PRIO, /* prioinit from 0 to 15 */ stack3, /* stack address (16 bits) */ TASK3, /* start address (16 bits) */ SUSPENDED, /* state at init phase */ TASK3_ID, /* id_tsk from 1 to 15 */ sizeof(stack2) /* stack size (16 bits) */ };

Modifiez le code de la tche 3 pour qu'elle soit aussi une tche BASIC :
TASK(TASK3) { unsigned int i; for (i = 0; i < 10000; i++) Nop(); if (PORTBbits.RB2 == 1) min++; TerminateTask(); }

40 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Et enfin modifiez la fonction "MyOwnISR" pour activer la tche ncessaire au traitement du bouton :
void MyOwnISR(void) { TaskStateType State; if (INTCON3bits.INT1IF) { INTCON3bits.INT1IF = 0; GetTaskState(TASK2_ID, &State); if (State == SUSPENDED) ActivateTask(TASK2_ID); } if (INTCON3bits.INT2IF) { INTCON3bits.INT2IF = 0; GetTaskState(TASK3_ID, &State); if (State == SUSPENDED) ActivateTask(TASK3_ID); } }

Recompilez (F10) et relancez la simulation (F9)

Placez un breakpoint dans la tche 3 et un dans la fonction "MyOwnISR". Lancez la simulation puis stoppez l n'importe quel moment (F5). Modifiez INTCON3 pour activez une interruption (par exemple mettre 0x1A pour l'INT2) : vous verrez que le pointeur passe par "MyOwnISR" puis par la tche 3. Si vous poursuivez la simulation vous verrez que le pointeur ne passe plus par la tche 3 avant la prochaine interruption : la tche a t suspendue.

41 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

8. Utilisation des drivers


Vous souhaitez faire communiquer votre application au travers du port srie ou bien du port CAN ? A prsent que vous savez crire des interruptions et des tches, et que vous matrisez la gestion des vnements et des alarmes, il vous sera facile d'utiliser ou d'crire un vritable driver pour PICos18.

> Principe d'un driver


Un driver est souvent compar une librairie, ce sont pourtant 2 choses bien distinctes. Une librairie est un ensemble de fonctions crites dans un langage (comme le langage C par exemple) et destin simplifier la vie du dveloppeur. Dans le cas d'une communication RS232, une librairie proposerait par exemple des fonctions d'ouverture et de fermeture du port srie, de rception et de transmission de donnes Un driver est une couche logicielle destine la prise en charge complte d'un priphrique. Son but n'est donc pas d'offrir une srie de fonctions propres utiliser ce priphrique puisque c'est le driver lui seul qui peut manipuler le priphrique...

Un driver est en fait constitu d'une ISR (Interrupt Service Routine) et d'une tche. Nous avons vu les ISR dans le chapitre prcdent, c'est--dire les fonctions ajoutes la fonction InterruptVectorL() ou InterruptVectorH(). L'ISR est en charge d'intercepter les interruptions (IT) et d'informer la tche du driver que cette interruption vient de se produire. C'est donc la tche que revient d'effectuer les traitements ncessaire la gestion de l'IT.

42 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Utilsation des briques logicielles


PICos18 est livr avec le noyau seul ainsi que ce tutorial. Toutefois sur la page DOWNLOAD du site web vous trouverez aussi des drivers ou des librairies disponibles gratuitement. Le but est de permettre un dveloppement modulaire avec lequel il suffirait d'intgrer des briques logicielles pour raliser une application. Nous allons voir ici comment utiliser une brique logicielle. Plus prcisment nous allons utiliser le driver RS232 de PICos18 pour pouvoir afficher notre horloge avec les variables "hour", "min", et "sec".

Tlcharger le driver RS232 sur la page DOWNLOAD de PICos18 :

Le package possde un fichier texte (lien TXT) qui indique comment inclure le driver dans votre application, comment paramtrer le driver (baudrate dans le cas d'un driver RS232) et aussi comment le mettre en oeuvre.

43 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

______________________________________________________________________ > < > RS232 driver v1.02 < > for < > PICos18 release 2.00 (beta 10 or upper) < > < > PICos18 - Real-time kernel for PIC18 family < > < > < > www.picos18.com www.pragmatec.net < >______________________________________________________________________

...

Maintenant que vous savez insrer des tches au projet, que vous savez crire des ISR, paramtrer votre application dans le fichier "tascdesc.c", suivez pas pas les indications du fichier texte pour insrer le driver dans votre application. Vous n'avez pas besoin d'ajouter les rfrences la tche "Example" comme l'alarme de la structure Alarm_list (paragraphe IV du fichier texte) ou encore EXAMPLE_ID du fichier define.h. Ne dpassez pas le paragraphe VI, celui-ci est abord spcifiquement ci-aprs.

> Utilisation du driver


Afin d'utiliser le driver crez une nouvelle tche "TASK4" en lieu et place de la tche "Example" du fichier texte du driver RS232. N'oubliez pas d'ajouter l'alarme ALARM_TASK4 dans le fichier "tascdesc.c".

Voici quoi doit ressembler la nouvelle tche :


#include #include #include #include "define.h" "drv_rs.h" <stdio.h> <string.h> 1

#define ALARM_TSK4

int Printf (const rom char *fmt, ...); extern unsigned char hour; extern unsigned char min; extern unsigned char sec; /********************************************************************** * Definition dedicated to the local functions. **********************************************************************/ RS_message_t RS_msg; unsigned char buffer[80]; /********************************************************************** * ------------------------------ TASK4 ------------------------------* * Fifth task of the tutorial. * **********************************************************************/ TASK(TASK4) { SetRelAlarm(ALARM_TSK4, 1000, 1000);

44 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Printf(" ______________________________________________________________________ \r\n"); Printf("> <\r\n"); Printf("> PICos18 Tutorial <\r\n"); Printf("> <\r\n"); Printf("> <\r\n"); Printf("> PICos18 - Real-time kernel for PIC18 family <\r\n"); Printf("> <\r\n"); Printf("> <\r\n"); Printf("> www.picos18.com www.pragmatec.net <\r\n"); Printf(">______________________________________________________________________<\r\n"); Printf(" \r\n"); Printf(" \r\n"); while(1) { WaitEvent(ALARM_EVENT); ClearEvent(ALARM_EVENT); Printf("%02d : %02d : %02d\r", (int)hour, (int)min, (int)sec); } } /********************************************************************** * Function in charge of structure registration and buffer transmission. * * @param string IN const string send to the USART port * @return void **********************************************************************/ int Printf (const rom char *fmt, ...) { va_list ap; int n; RS_enqMsg(&RS_msg, buffer, 50); va_start (ap, fmt); n = vfprintf (_H_USER, fmt, ap); va_end (ap); SetEvent(RS_DRV_ID, RS_NEW_MSG); WaitEvent(RS_QUEUE_EMPTY);ClearEvent(RS_QUEUE_EMPTY); return n; }

La premire partie du code correspond aux inclusions des headers propres l'utilisation du driver RS232 et aux fonctions "printf". Ensuite il faut dclarer ALARM_TASK4 et aussi dclarer comme "extern" les variables externes "hour", "min" et "sec" pour signifier au compiler C18 que les dfinitions de ces variables ne se trouvent pas dans ce fichier. En RAM on dclare 2 types de variables :

RS_message_t RS_msg : cette structure est obligatoire pour mettre un buffer avec le driver RS232 unsigned char buffer[80] : il s'agit justement du buffer transmettre.

Enfin vous dcouvrez le coeur de la tche TASK4, qui arme une alarme qui ragit toutes les 1000ms soit toutes les secondes. La fonction "Printf" est appele pour pouvoir poster des chanes constantes, convertir des variables,... Tous les formats de variables sont grs par C18 sauf les floatants...! La fonction "Printf" ncessite "\r\n" en fin de chane si vous souhaitez un retour chariot (chargement d'une nouvelle ligne), le "\r" servant au retour en dbut de ligne, et le "\n" au chargement d'une nouvelle ligne proprement parler. Pour afficher le banner nous utilisons donc "\r\n" et pour afficher l'heure en surimpression, nous utilisons juste "\r".

45 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Au final vous devez obtenir l'affichage suivant sous HyperTerminal :

> Paramtrage d'HyperTeminal


Attention au paramtrage de la COM srie sous HyperTerminal, elle doit tre 11500 bits/sec et sans contrle de flux :

46 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

9. Exemple dapplication
Le tutorial se termine ici par un exemple complet d'application. Les sources de cet exemple sont fournis dans le rpertoire /Project/Tutorial de PICos18, ceci vous permettant d'apprcier quel point il est ais d'crire une application pour PIC18 avec PICos18.

> Interruptions multiples


Lorsqu'on excute l'application du tutorial et qu'on appuie sur les boutons on s'aperoit vite qu'il existe un problme : le PIC18 semble ne plus bien fonctionner aprs un instant, surtout si l'on appuie "sauvagement" sur les boutons ! Stopper alors l'application en mode debug si vous utilisez un ICD2 de Microchip ou bien votre simulation si vous travailler sous le simulateur de MPLAB, et inspectez les variables suivantes :

Comme vous pouvez le constater la variable "kernelPanic" n'est pas nulle. Dans notre cas elle vaut 0x53. En fait cette variable nous renseigne sur d'ventuel dbordement de pile logicielle. Lorsqu'une pile dborde sur une autre, le noyau dtecte automatiquement le problme et stoppe l'hmorragie en suspendant la tche en cause. Ceci permet de limiter la casse, mais surtout de dbuguer alors que PICos18 fonctionne toujours.

kernelPanic vaut 0x53. La partie de droite ("3") signifie que la tche dont l'identifiant est 3 a vu sa pile dborder. La partie de gauche ("5") signifie que la tche dont l'identifiant est 5 a vu sa pile se faire craser par une autre. Le noyau a donc dcid de geler les 2 tches car leur fonctionnement n'est plus assur. Ceci permet au PIC18 de rester fonctionnel malgr le bug, et donc vous autorise trouver l'origine du bug. La tche 2 en charge de l'appuie d'un bouton a fonctionn de faon anormale et sa pile logicielle a dbord sur la pile suivante, celle de la tche 4.

47 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Mais comment cela se peut-il ? Et bien 2 cas sont possibles :


votre code est important et vous avez sous-dimensionn vos besoins en terme de pile logiciel => augmentez la taille de la pile l'origine du problme et recommencez une interruption sans fin force une tche sauvegarder son contexte (l'ensemble des registres du PIC18 ainsi que sa pile hardware) en boucle ce qui provoque le dbordement.

Or nous utilisons des boutons poussoirs, et nous avons vu prcdemment que ceux-ci rebondissaient lorsqu'ils taient presss. Du coup plusieurs IT en chane se produisent et saturent inutilement le PIC18. A chaque IT, on sauvegarde le contexte de la tche courante, mais les interruptions sont si proches qu'on tourne en boucle dans InterruptVectorL() jusqu' faire exploser la pile logicielle courante.... Ce phnomne est courant, qu'on utilise ou pas un noyau temps-rel. La seule diffrence ici, c'est que PICos18 a surveill l'application en "temps-rel" l'affut de ce genre de problme et prserve ainsi le reste de l'application. Sans OS, le PIC18 se serait plant... En fait il ne s'agit pas d'un problme d'architecture mais bel et bien d'un problme de code, que nous allons aussitt corriger.

> Correction de l'application


Le problme vient du fait que nous autorisons toujours les interruptions sur les ports RB1 et RB2 alors qu'on a pas encore commenc traiter la premire interruption. Aprs tout il ne sert rien de savoir que le bouton a gnr 50 rebonds avant de se stabiliser : il faut juste mmoriser le fait qu'il ait t enfonc. Modifier les tches TASK2 et TASK3 comme suit :
TASK(TASK2) { unsigned int i; hour++; if (hour == 24) hour = 0; INTCON3bits.INT1IF = 0; INTCON3bits.INT1IE = 1; TerminateTask(); } ... TASK(TASK3) { unsigned int i; min++; if (min == 60) min = 0; INTCON3bits.INT2IF = 0; INTCON3bits.INT2IE = 1; TerminateTask(); }

48 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

Et surtout il faut modifier la gestion des interruptions :


void MyOwnISR(void) { TaskStateType State; if (INTCON3bits.INT1IF) { INTCON3bits.INT1IE = 0; GetTaskState(TASK2_ID, &State); if (State == SUSPENDED) ActivateTask(TASK2_ID); } if (INTCON3bits.INT2IF) { INTCON3bits.INT2IE = 0; GetTaskState(TASK3_ID, &State); if (State == SUSPENDED) ActivateTask(TASK3_ID); } } ... void InterruptVectorL(void) { EnterISR(); if (INTCONbits.TMR0IF == 1) AddOneTick(); /*Here is the next interrupts you want to manage */ if ((INTCON3bits.INT1IF & INTCON3bits.INT1IE)|| (INTCON3bits.INT2IF & INTCON3bits.INT2IE)) MyOwnISR(); if ((PIR1bits.RCIF)&(PIE1bits.RCIE)) RS_RX_INT(); if ((PIR1bits.TXIF)&(PIE1bits.TXIE)) RS_TX_INT(); LeaveISR();

Comme vous pouvez le constater, MyOwnISR() dvalide les interruptions (INTxIE = 0 ce qui signifie Interrupt Enable 0) et c'est aux tches de grer l'autorisation, une fois seulement que le traitement est ralis. Vous pouvez maintenant programmer votre PIC18 et tester le programme en rel, vous verrez qu'en appuyant sur les boutons vous pouvez mettre jour l'horloge. Toutefois il apparat un problme : vous avez beau appuyer plusieurs fois de suite sur un bouton, la nouvelle valeur n'est prise en compte que toutes les secondes, au moment ou l'affichage est rafrachi. Pour corriger a nous allons utiliser les capacits temps-rel de PICos18 !

49 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

> Modification en temps rel


Pour pouvoir modifier l'affichage chaque appuie de bouton il faudrait pouvoir informer la tche d'affichage qu'il est ncessaire de rafrachir l'affichage avec les nouvelles valeurs.... mais ceci sans perturber l'affichage dj existant chaque seconde, c'est--dire sans perturber la bon fonctionnement de l'horloge. Pour cela nous allons poster un vnement la tche TASK4 :
TASK(TASK2) { unsigned int i; hour++; if (hour == 24) hour = 0; SetEvent(TASK4_ID, UPDATE_EVENT); INTCON3bits.INT1IF = 0; INTCON3bits.INT1IE = 1; TerminateTask(); } ... TASK(TASK3) { unsigned int i; min++; if (min == 60) min = 0; SetEvent(TASK4_ID, UPDATE_EVENT); INTCON3bits.INT2IF = 0; INTCON3bits.INT2IE = 1; TerminateTask(); }

Et dans la tche TASK4 nous allons nous mettre en attente aussi sur ce type d'vnements :
...

while(1) { WaitEvent(ALARM_EVENT | UPDATE_EVENT); GetEvent(id_tsk_run, &Time_event); if (Time_event & ALARM_EVENT) ClearEvent(ALARM_EVENT); if (Time_event & UPDATE_EVENT) ClearEvent(UPDATE_EVENT); Printf("%02d : %02d : %02d\r", (int)hour, (int)min, (int)sec); } ...

Aussi n'oubliez pas de rajouter la variable "EventMaskType Time_event" en tant que variable globale ou variable locale la tche.

50 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

La dfinition de UPDATE_EVENT n'est pas connu de l'application aussi rajoutez l dans le fichier

define.h :
...
/*********************************************************************** * ----------------------------- Events -------------------------------**********************************************************************/ #define ALARM_EVENT 0x80 #define TASK1_EVENT 0x10 #define UPDATE_EVENT 0x02 #define #define #define #define ... RS_NEW_MSG RS_RCV_MSG RS_QUEUE_EMPTY RS_QUEUE_FULL 0x10 0x20 0x10 0x20

> L'application finale


Voil, vous pouvez dsormais recompilez votre application, la charger dans un PIC18F452 et la tester, vous verrez alors votre horloge s'afficher sous HyperTerminal et vous russirez la modifier en temps-rel l'aide vos boutons poussoirs.

Bien entendu vous pouvez largement simplifier cette application. Ceci n'a pas t fait pour permettre une meilleure comprhension de PICos18. Vous pouvez aussi la complter, avec votre propre code ou bien en rajouter des drivers de PICos18 : vous pourriez par exemple utiliser un RTC (Real Time Clock) sur bus I2C et la mettre l'heure directement depuis PICos18 et HyperTerminal...

51 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

10. Bibliographie et rfrences


Pour en savoir un peu plus sur la norme OSEK ainsi que sur lemploi des PIC18 au travers de PIC18, nous vous prsentons ici quelques rfrences explorer.

Bibliographie

Le livre de Joseph LEMIEUX des ditions CMPbooks. Ce livre dtaille la ralisation d'un jeux de cartes sur le noyau OsekWorks de la socit WindRiver.

Liens Internet utiles


www.osek-vdx.org : www.picos18.com : www.pragmatec.net : www.microchip.com : pour obtenir les normes OSEK/VDX au format PDF. pour obtenir les dernires versions du noyau PICos18. pour obtenir des renseignements concernant les produits dvelopps autour de PICos18. le site officiel de MICROCHIP, indispensable pour obtenir : - les data sheets des microcontrleurs PIC18xxx - la dernire version de MPLAB - la dernire version du compilateur C18 en commande pour obtenir des renseignements la licence GPL.

www.fsf.org :

52 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

11. Glossaire
Banner : Commentaires situs en tte de fichiers destins renseigner tout utilisateur sur la nature du fichier, les fonctionnalits codes, le ou les auteurs, les dates de modifications ainsi quune rfrence la licence GPL Point darrt en franais. Il sagit dune fonctionnalit offerte par le simulateur MPLAB : lorsque le programme atteint le point darrt la simulation stoppe immdiatement. Placer des points darrt dans les diffrentes tches de votre application permet de suivre lvolution de votre programme. Programme destin convertir un code source (par exemple file.c) en un fichier objet (par exemple file.o). Le compilateur C18 de Microchip permet de convertir le code de votre application en une srie dinstructions comprhensibles par le PIC18. Le code gnr nest pourtant pas le code final car il contient encore de nombreux symboles (noms de variables, noms de fonctions, ). Programme dont la fonction est de rsoudre les symboles contenus dans les diffrents fichiers objets (par exemple file.o). Dans le cas dune tche faisant appel un service du noyau, le linker va pouvoir dterminer quelle adresse faire le saut dappel de fonction, connaissant la position en mmoire des services du noyau. Pour dterminer la position du code en mmoire le linker sappuie sur le script du linker (par exemple pic18f452.lkr). Le fichier de mapping (par exemple projet.map) est un fichier cr par le linker. Son but est de renseigner le dveloppeur sur la position des variables et des fonctions en mmoire, aprs que le linker est dlibrment choisi des emplacements. Dsigne la General Public License , une licence libre dite publique opposer une licence prive. Cette licence empche toute personne physique ou morale de sapproprier le code protg par la licence GPL, en dposant un brevet par exemple. La licence GPL garantit la disponibilit du code source originale ainsi que ces diverses volutions. Un projet est dit open-source lorsque celui-ci fait lobjet dune libre divulgation de son code source. Cette divulgation est spcifie par la licence GPL qui prcise que le ou les responsables doivent pouvoir fournir les sources sous une quelconque forme en cas de demande. Concernant PICos18, les sources sont mises disposition sur le site www.picos18.com.

Breakpoint :

Compilateur :

Linker :

Mapping :

GPL :

Open source :

53 / 54

Btiment EARHART ZAC Grenoble Air Parc 38590 St Etienne de St Geoirs France www.pragmatec.net

Noyau temps rel pour PIC18

PICos18 v 2.01

OSEK/VDX :

Cest la norme sur laquelle repose PICos18. Cre lorigine pour le milieu automobile, elle est de plus en plus utilise en robotique et en automatisme. Elle convient en effet parfaitement aux systmes base de microcontrleurs 8 bits bnficiant de peu de mmoire. Lorsque lon crit un code en langage C on cherche factoriser le code le plus possible sous forme de fonction. A chaque appel de fonction, le microcontrleur PIC18 mmorise ladresse du code appelant dans une zone appele la pile des appels de fonctions ou pile hardware . Lorsque la fonction en C se terminera par linstruction return , le PIC18 utilisera ladresse mmorise dans la pile pour revenir au code prcdent. Plus exactement cest ladresse suivante qui est mmorise pour permettre la bonne continuation du programme. Le scheduler est la partie essentielle dun noyau. En franais on le trouve parfois sous le terme moniteur . Le scheduler a pour fonction de dterminer la prochaine tche active. Dans le cas de PICos18 le scheduler choisit dactiver la tche ltat READY la plus prioritaire. Si aucune tche nest prte le noyau entre dans un tat idle qui lui permet dattendre larrive dun nouvel vnement. Le scheduler est cod en assembleur dans le fichier kernel.asm de PICos18. Nom anglais dsignant la pile des appels de fonctions. Dans le cas de PICos18 cette stack est sauvegarde chaque fois quil y a premption, cest--dire passage dune tche une autre. En effet lappel des fonctions en C peut corrompre le contenu de la stack si bien quil est ncessaire de la sauvegarder. Un tick est une unit de temps. Avec un microcontrleur PIC18xxx cadenc 40 MHz (quartz 10 MHz et PLLx4 active) la valeur dun tick est calibr 1 ms. La mise jour des alarmes se fait sur cette base. Consulter le paragraphe recommandations si vous souhaiter modifier cette valeur. Le Watchdog est un dispositif lectronique intgr aux PIC18xxx qui permet de redmarrer le microcontrleur lorsque celui-ci ne rpond plus. Pour viter ce redmarrage intempestif, il est ncessaire de mettre le Watchdog a zro frquemment. Consulter la documentation Microchip pour de plus amples informations.

Pile des appels de fonctions :

Scheduler :

Stack :

Tick :

Watchdog :

54 / 54