Construire une plaquette de développement pour PIC 8 bits 18F2550

Dans une série d’articles précédents [1], nous avons construit une plaquette de développement Pinguino pour le microcontrôleur PIC18F2550.

Aujourd’hui nous allons construire une plaquette indépendante pour PIC18F2550. Par indépendante j’entends par là que le développement se fera désormais à l’aide de l’IDE MPLAB X de MICROCHIP, du compilateur C18 et de l’outil de chargement microchip.

Le plus gros changement par rapport au projet Pinguino concerne le bootloader. Exit donc le bootloader du Pinguino. Il faudra charger un bootloader adapté. Nous allons voir comment le générer à partir des ressources fournies par MICROCHIP. Puis nous adapterons légèrement la plaquette du projet Pinguino pour la rendre compatible avec le nouveau bootloader. Enfin nous ferons un petit Hello World qui servira de validation et de Template pour les futures applications.

Bootloader

Heureusement il ne s’agit pas de partir d’une page blanche et MICROCHIP fournit de nombreuses ressources pour notre projet.

Le principe du bootloader dans ce projet est le suivant. Il s’agit d’un logiciel placé en mémoire programme dans la section 0 – 0xFFF. A l’aide d’une entrée digitale on peut sélectionner 2 modes :

  • Le mode bootloader (état 0), qui attend des données envoyées depuis le port USB et met à jour la section 0x1000- 0x7FFF réservée au logiciel applicatif. Visuellement, une led de vie clignote pour indiquer que l’on est dans ce mode.
  • Le mode application (état 1) qui vérifie qu’un logiciel applicatif est présent avant de le lancer.

Installation de microchip solutions

Commençons par nous rendre sur le site officiel [2] Microchip libraries for application.

En bas de la page télécharger puis lancer l’installeur qui correspond à votre système d’exploitation (dans mon cas, Windows).

Dans l’assistant qui s’ouvre (Figure 1), faire Next :

Figure 1 Assitant Microchip

Tout décocher à l’exception de :

C’est parti, allez prendre un café cafe ou faites un tour sur Hacker News :

Pour notre application le JRE n’est pas nécessaire, j’ai mis Non.

Par défaut les ressources sont installées sur C:\microchip_solutions_vYYYY-MM-DD avec YYYY l’année, MM le mois et DD le jour (format de date ISO cerveau sol).

Au moment où j’écris ces lignes c’est la version du 15 Juin 2013.

Le sous dossier \USB\Device – Bootloaders\HID\ contient les fichiers sources, fichiers projets, linker et binaires des bootloaders proposés pour un certain nombre de microcontrôleurs.

Malheureusement le PIC18F2550 ne figure pas dans la liste …


Mais qu’est-ce que tu me racontes là ?

Pas de panique il suffit de partir du projet de bootloader intitulé Firmware – PIC18 Non-J et d’y apporter quelques modifications.

Si cette partie du projet ne vous intéresse pas vous pouvez sauter le paragraphe suivant et récupérer directement le fichier hex que j’ai généré : [6] Binaires bootloader et Hello World.

Modifier le bootloader du PIC18 Non-J

Pour cela vous aurez besoin de :

Dans le dossier d’installation aller dans le sous dossier \USB\Device – Bootloaders\HID\Firmware – PIC18 Non-J

Copier l’ensemble sur votre dossier de travail (workspace).

Lancer MPLAB X. Dans le menu File, cliquer sur Open Project…

Dans le dossier de votre workspace cliquer sur MPLAB.X (Figure 2) :

Figure 2 Ouverture du projet

Une fois le projet ouvert, la première chose à faire c’est de modifier le device. Pour cela faire un clic droit sur le projet puis Properties.

Dans la liste déroulante du Device, sélectionner le PIC18F2550 (Figure 3) :

Figure 3 Propriétés du projet

Il faut maintenant remplacer le fichier de linker.

Dans la vue projet, dérouler la catégorie Linker Files.

Supprimer le ou les fichiers associés au projet.

Faire clic droit puis Add existing Item …

Ajouter le fichier BootModified.18f2550_g.lkr

A présent il y a quelques modifications à apporter à 2 fichiers sources : main.c et io_cfg.h.

Le fichier main.c contient beaucoup de commentaires concernant les modifications à apporter pour adapter le bootloader à son besoin.

IMPORTANT NOTES: This code can be readily adapted for use with both the F and LF versions of the following devices:

PIC18F4553/4458/2553/2458

PIC18F4550/4455/2550/2455

PIC18F4450/2450

PIC18F14K50/13K50

PIC18F45K50/25K50/24K50

Voilà qui est encourageant kukron

La première chose à ajouter dans le fichier ce sont les bits de configuration. Les bits de configurations (ou fusibles) permettent de configurer le device, comme par exemple le watchdog ou la vitesse de la clock.

Je ferai probablement un billet là-dessus car ce n’est pas très intuitif de mon point de vue. Les bits de configurations sont nombreux, variables selon les cibles et il y a plusieurs façons de les programmer. J’ai quelques trucs à dire sur le sujet qui pourront peut être aider ceux qui débutent sur du PIC.

En attendant … suri_2002 … c’est parti !

Au dessus de la ligne 219 :

 #endif    //18F4550 and 18F4553

Ajouter :

#elif defined(__18F2550)
        #pragma config PLLDIV   = 5         // (20 MHz crystal on PICDEM FS USB board)
        #pragma config CPUDIV   = OSC1_PLL2
        #pragma config USBDIV   = 2         // Clock source from 96MHz PLL/2
        #pragma config FOSC        = HS // CPU osc = 20MHz
        #pragma config FCMEN    = OFF
        #pragma config IESO         = OFF
        #pragma config PWRT       = OFF
        #pragma config BOR         = ON
        #pragma config BORV      = 3
        #pragma config VREGEN = ON        //USB Voltage Regulator
        #pragma config WDT        = OFF
        #pragma config WDTPS    = 32768
        #pragma config MCLRE   = ON
        #pragma config LPT1OSC= OFF
        #pragma config PBADEN  = OFF
        #pragma config STVREN   = ON
        #pragma config LVP      = OFF
        #pragma config XINST    = OFF       // Extended Instruction Set
        #pragma config CP0      = OFF
        #pragma config CP1      = OFF
        #pragma config CPB      = OFF
        #pragma config WRT0     = OFF
        #pragma config WRT1     = OFF
        #pragma config WRTB     = OFF       // Boot Block Write Protection
        #pragma config WRTC     = OFF
        #pragma config EBTR0    = OFF
        #pragma config EBTR1    = OFF
        #pragma config EBTRB    = OFF

Dans le fichier io_cfg.h

Il va falloir modifier les macros suivantes :


    #define mInitAllLEDs()      LATD &= 0xFE; TRISD &= 0xFE;

    #define mLED_1              LATDbits.LATD0

Pourquoi ?

Tout simplement parce qu’il n’y a pas de PORTD sur 18F2550 (Figure 4) :

Figure 4 PIC 18F2550 pin diagram

Il faut donc modifier le registre de direction et de donnée.

Puisque la plaquette Pinguino possède une led de vie sur RA4, on obtient :


    #define mInitAllLEDs()      TRISAbits.RA4 = 0;

    #define mLED_1              LATAbits.LATA4

Ensuite il faut choisir l’entrée digitale qui va servir à basculer entre le mode application et le mode bootloader.

Le choix est libre. Par défaut c’est RB4 qui est configuré via la macro sw2 :


#define sw2                 PORTBbits.RB4

De mon côté j’ai choisi RA5 :


#define mInitSwitch2()      {ADCON1 = 0x0F; TRISAbits.TRISA5=1;}

#define sw2                 PORTAbits.RA5

  C’est tout pour les modifications, facile non ? Maintenant il faut générer le binaire du bootloader et le charger.

Compiler le projet à l’aide de l’icône.

Brancher le programmateur de pic (USB côté PC, ICSP côté cible, voir ci-contre).

Programmer la cible avec le bootloader.

Compiler à l’aide de l’icône

 

 

 

Si tout se passe bien vous devriez avoir un log similaire :

Connecting to MPLAB ICD 3…

Firmware Suite Version…..01.28.18

Firmware type…………..PIC18F

Target detected

Device ID Revision = 7

The following memory area(s) will be programmed:

program memory: start address = 0x0, end address = 0x107f

configuration memory

Programming…

Programming/Verify complete

Le plus dur est fait !

Reste à modifier la plaquette Pinguino.

Modifier la plaquette Pinguino

La seule modification à apporter par rapport à la plaquette Pinguino concerne l’entrée digitale de sélection du mode configuré plus haut. Dans mon cas il s’agit de RA5. L’entrée digitale pouvant prendre 2 états (1 ou 0), on va ajouter un interrupteur permettant de commuter entre VCC et la masse (GND) (Figure 5) :

Figure 5 Schéma de la plaquette

Notez le Hello World sur le schéma qui est notre prochaine étape, car après tout il faut bien tester tout ça ! Pour ceux qui sont pressés, vous pouvez télécharger le hex : [6] Binaires bootloader et Hello World.

Hello World

Le but du logiciel sera d’allumer la led reliée à la pin 12 du micro, c’est-à-dire RC1.

Rien de bien difficile en somme. Il va falloir pourtant respecter un certain nombre de points pour rendre notre application compatible avec le bootloader précédemment chargé.

Premier point, on conserve les bits de configuration du bootloader.

Deuxième point, il faut adapter le linker en prenant en compte l’offset mémoire lié au bootloader :


FILES c018i.o

FILES clib.lib

FILES p18f2550.lib

// Définition de la mémoire programme :

CODEPAGE   NAME=bootloader START=0x0                 END=0xFFF          PROTECTED

CODEPAGE   NAME=vectors    START=0x1000              END=0x1029            PROTECTED

CODEPAGE   NAME=page       START=0x102A            END=0x7FFF

CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED

CODEPAGE   NAME=config     START=0x300000          END=0x30000D      PROTECTED

CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF    PROTECTED

CODEPAGE   NAME=eedata     START=0xF00000          END=0xF000FF      PROTECTED

Traditionnellement, le vecteur reset contenant l’amorce du programme est situé à l’adresse 0x0, les vecteurs d’interruptions aux adresses 0x8, 0x18 et le programme en lui-même à l’adresse 0x2A.

Sauf que dans cette section il y a désormais le bootloader. Il va falloir donc rediriger les vecteurs à partir de l’adresse à 0X1000 et protéger la section du bootloader (0 – 0xFFF) à l’aide du mot clef PROTECTED.

Troisième point, dans le main.c de votre programme, il faut rediriger les interruptions et le vecteur reset, à l’aide de pragmas :


//remap reset and interrupt vector

//=================================

extern void _startup (void);        // See c018i.c in your C18 compiler dir

#pragma code REMAPPED_RESET_VECTOR = 0x1000                //remap reset vector to 0x1000

void _reset (void)

{

    _asm goto _startup _endasm

}

#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = 0x1008    //remap High Interrupt vector to 0x1008

void Remapped_High_ISR (void)

{

    _asm goto HighPriorityISRCode _endasm

}

#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = 0x1018        //remap Low Interrupt vector to 0x1018

void Remapped_Low_ISR (void)

{

     _asm goto LowPriorityISRCode _endasm

}

#pragma code // redonne toute liberté au compilateur

Le zip du projet se trouve ici : [7] Workspaces bootloader et Hello World.

Une fois le projet compilé, il faut le charger sur le pic. Pour cela, si vous avez suivi, on va se passer du programmateur de PIC puisque le bootloader va s’en charger. Il suffit d’envoyer les octets constituants le binaire par USB. Et pour cela Microchip fournit un outil : le HIDBootloader.

HID Bootloader

Lancer HIDBootloader.exe dans le dossier d’installation microchip_solutions dans le sous dossier \USB\Device – Bootloaders\HID\Software Windows Executable:

Positionner l’interrupteur sur le 0V et relier la plaquette au PC à l’aide du câble USB.

La led de vie RA4 doit clignoter et le device doit être détecté (Figure 7).

Figure 7 HID Bootloader, device detected

A ce moment là ouvrir le fichier (File > Import) et cliquer sur l’icône Erase/Program/Verify Device

Starting Erase/Program/Verify Sequence.

Do not unplug device or disconnect power until the operation is fully complete.

Erasing Device… (no status update until complete, may take several seconds)

Erase Complete (1.36s)

Writing Device…

Write Complete (0.031s)

Verifying Device…

Verify Complete (2s)

Erase/Program/Verify sequence completed successfully.

You may now unplug or reset the device.

Lorsque le logiciel a été chargé, basculer l’interrupteur dans l’autre position et faire un reset à l’aide du bouton de la plaquette ou directement depuis HID Bootloader avec l’icône .

Votre Hello World démarre.

  

lilyrose

Légende :

  • Fil rouge : +5V ;
  • Fil noir : masse ;
  • Fil blanc : Sortie digitale RC1 (Hello World) ;
  • Fil orange : entrée digitale de sélection du mode (bootloader) ;
  • Plaquette d’essai jaune : contient tous les ajouts par rapport au projet Pinguino (une résistance, une led et un interrupteur).

Quelques remarques sur le bootloader

Selection du mode

La position de l’interrupteur, nous l’avons vu, permet de switcher entre le mode bootloader et le mode application.

Que se passe t’il lorsque aucun logiciel applicatif n’a été chargé précédemment (vous venez de charger le bootloader dans le PIC) et que l’interrupteur est positionné pour lancer l’application ?

On pourrait se dire que le bootloader va faire un jump mémoire dans la zone du logiciel applicatif et que celle-ci étant vide, rien ne va se passer.

Oui mais, par soucis de robustesse, les développeurs du bootloader ont prévu un mécanisme afin de rester en mode bootloader si l’application est manquante ou corrompue. Regardons cela plus en détail.

Dans le main.c lorsque l’entrée digitale est positionnée sur 1 pour lancer l’application :

  //Before going to application image however, make sure the image

  //is properly signed and is intact.

  goto DoFlashSignatureCheck;

On fait un jump vers une section du bootloader qui va vérifier une signature (en fait une constante identifiée par un define APP_SIGNATURE_VALUE) à une adresse absolue en mémoire programme, identifiée par un define APP_SIGNATURE_ADDRESS :

DoFlashSignatureCheck:

    //Check if the application region flash signature is valid

    #ifdef ENABLE_FLASH_SIGNATURE_VERIFICATION

        if(*(rom unsigned int*)APP_SIGNATURE_ADDRESS == APP_SIGNATURE_VALUE)

        {

            //The flash signature was valid, implying the previous

            //erase/program/verify operation was a success.

            //Go ahead and jump out of bootloader mode into the application run mode

            _asm goto REMAPPED_APPLICATION_RESET_VECTOR _endasm

        }

        //else the application image is missing or corrupt.  In this case, we

        //need to stay in the bootloader mode, so the user has the ability to

        //try (again) to re-program a valid application image into the device.

        //We should stay in bootloader mode

        _asm goto BootMain _endasm

Les commentaires sont assez parlant, si la signature n’est pas reconnue on reste dans le bootloader (_asm goto BootMain _endasm).

Les define sont dans BootPIC18NonJ.h :

#define APP_SIGNATURE_ADDRESS            0x1006  //0x1006 and 0x1007 contains the "signature" WORD, indicating successful erase/program/verify operation

#define APP_SIGNATURE_VALUE              0x600D  //leet "GOOD", implying that the erase/program was a success and the bootloader intentionally programmed the APP_SIGNATURE_ADDRESS with this value

La signature est générée lors du chargement du logiciel applicatif par le HID Bootloader lors de l’opération erase/program/verify.

En conclusion, lors du premier chargement du logiciel applicatif, via le HID bootloader ce n’est pas nécessaire de se soucier de la position de l’interrupteur! Le bootloader est forcément en mode bootloader.

Rupture de compatibilité

Ce mécanisme de vérification de signature n’est pas présent sur des anciennes versions du HID Bootloader. Je n’ai pas l’historique des évolutions mais je peux affirmer que c’est au moins vrai pour les versions 2.2 et 2.6b. Pour s’en convaincre il suffit de charger le Hello World avec l’une de ces deux versions. Le HID bootloader va charger l’application sans écrire la signature à l’adresse 0x1006 et lors du prochain reset, le bootloader ne rendra jamais la main car il ne reconnaitra pas la signature.

En conclusion, chargez vos applications avec la version 2.9j ou ultérieures. Si vous tenez absolument à utiliser des versions antérieures, régénérez un bootloader en commentant la ligne suivante dans main.c :

#define ENABLE_FLASH_SIGNATURE_VERIFICATION

C’est tout pour cette fois-ci !

Références :

[1] Construire une plaquette de développement ;

[2] Microchip libraries for application ;

[3] Download MPLAB X ;

[4] Download C18 ;

[5] Achat programmateurs de PIC ;

[6] Binaires bootloader et Hello World ;

[7] Workspaces bootloader et Hello World.

Publicités