PIC Microchip – Application du 16F88 – Le Bootloader
Cet article s’inscrit dans le droit fil des précédents, l’utilisation et la programmation des microcontrôleurs. Le 16F88 à un avantage sur les microcontrôleurs que j’ai utilisés jusqu’ à présent, il dispose de la possibilité d’écriture de son propre programme (self-programming). Ce programme est chargé dans le PIC au moyen de deux autres programmes, l’un situé sur le PC, l’autre résident sur le PIC appelé Bootloader qui communiquent entre-eux. Le programme résident nécessite d’être chargé une première fois, au moyen d’un programmateur.
1. Cahier des charges
1.1. Contraintes techniques
Si l’avantage de ce dispositif est de faciliter la mise au point des programmes en évitant de remettre sans cesse le microcontrôleur sur le banc du programmateur, il y a aussi des inconvénients.
Le premier tient au Bootloader lui-même. Le programme résident consomme un peu de l’espace mémoire du PIC et réduit d’autant l’espace disponible pour l’application. Les suivants sont inhérents à la technologie et au fonctionnement du PIC.
La configuration du microcontrôleur ne peut pas être changée dynamiquement ce qui implique de recharger le programme résident au moyen du programmateur lorsque la configuration ne correspond plus à l’usage.
La technique d’écriture en mémoire programme peut varier d’un microcontrôleur à l’autre. L’écriture en mémoire programme du 16F88 nécessite une phase d’effacement préalable (Erase). L’effacement est réalisé par bloc de 32 mots. Les 11 bits les plus forts de l’adresse pointent sur le bloc à effacer, les bits de poids faibles 4:0 sont ignorés. Quant à l’écriture, elle est réalisée en bloc de 4 mots. Un bloc à écrire consiste en 4 mots consécutifs dont les 2 bits 1:0 de poids faibles de l’adresse s’étendent de 00 à 11. Les mots sont placés en buffer d’écriture et l’opération d’écriture n’est effective qu’à l’application du mot 11. Cette séquence est réalisée automatiquement par le processeur. L’écriture en EEPROM se fait mot par mot de 8 bits sans effacement préalable. Tout ceci est fort bien expliqué dans la documentation technique du 16F88 de MICROCHIP au chapitre 3 « DATA EEPROM AND FLASH PROGRAM MEMORY ».
1.2. Solution
Le travail est réparti sur 2 programmes l’un sur le PIC, le Bootloader, appelé chargePIC16F88, l’autre sur le PC, appelé chargePIC.
1.2.1. Le Bootloader chargePIC16F88
Son rôle sera simplifié au maximum. Bien que son nom porte le suffixe 16F88, j’espère le généraliser à d’autres PIC du même type, mais c’est une autre histoire et je ne peux le vérifier sans faire de tests. A dessein, pour le rendre générique, il ne traite qu’une opération élémentaire à la fois envoyée par le PC :
- connexion (login),
- lecture d’un mot en mémoire programme,
- lecture d’un mot en EEPROM,
- effacement d’un bloc en mémoire (ici le terme bloc peut signifier 1 ou n mots selon le microcontrôleur),
- écriture d’un mot en mémoire programme,
- écriture d’un mot en EEPROM,
- déconnexion (logout) et exécution de l’application.
Calcul
CRC (contrôle de redondance cyclique ou checksum) qui se résume à une addition et une opération logique. En cas d’erreur, l’opération est rejetée et un code est retourné au PC qui s’en arrange.
Configuration
La version proposée ici est une version basique avec oscillateur interne à 4MHz. qui utilise pour mes tests un minimum de composants. D’autres variantes avec oscillateurs externes seront disponibles en téléchargement.
Plan mémoire
Le Bootloader est réparti sur 2 segments mémoire :
l’un en tête, servant au reset et la redéfinition du plan mémoire pour l’application utilisateur (re-mapping),
l’autre, en fin de mémoire, le Bootloader proprement-dit.
Le Bootloader doit rester à l’abri de l’écriture. Pour les 16F88 ces segments sont calés sur des blocs de 32 mots au prix de la perte d’un peu de place.
Le plan mémoire ainsi défini pour le 16F88 et sa famille n’est pas figé pour s’adapter à d’autres microcontrôleurs et ne pas gaspiller la place mémoire. Au login, le PIC transmet au PC les propriétés du Bootloader. Avec ces propriétés, le PC se construit une image du plan mémoire.
Déclenchement
Au reset, à la mise sous tension, chargePIC16F88 attend un code de LOGIN. Au bout d’un temps réglable (login timeout), en l’absence de réception de ce code, LOGOUT/RUN est exécuté et l’application utilisateur est lancée. A réception du LOGIN le Bootloader retourne le code de LOGIN et les propriétés du Bootloader. L’application hôte chargePIC est maintenant maître du PIC. Le Bootloader chargePIC16F88 se met en attente d’une commande de l’hôte.
1.2.2. L’application hôte chargePIC
Son rôle premier est de charger un fichier HEX (Intel) contenant les instructions de l’application utilisateur dans l’espace mémoire du PIC qui lui est réservée. Au prix d’un peu de code supplémentaire, je l’ai doté de fonctions de lecture pour faciliter le débogage et l’écriture séparée de l’EEPROM pour la mise à jour de paramètres. Pour atteindre ces buts, l’application dispose des fonctions suivantes :
- Se connecter au PIC et obtenir les propriétés du Bootloader
- Choisir dans une liste le µcontrôleur et ses propriétés,
- Charger le fichier HEX contenant l’application utilisateur, le traduire en liste d’instructions et en afficher le résultat
- Afficher le plan mémoire programme utilisateur et EEPROM
- Effacer écrire l’application utilisateur
- Relire vérifier l’écriture du programme utilisateur
- Lire la mémoire programme ou l’EEPROM
- Enregistrer l’historique du traitement dans un fichier journal (log)
- Calculer SPBRG
- Calculer le délai de connexion
Le logiciel dispose d’un catalogue des microcontrôleurs et de leurs propriétés qui pourra être enrichi.
L’application fonctionne sous Windows, testée sous Windows7 64 bits.
2. Choix des outils de développement
En tant qu’amateur j’utilise uniquement des outils gratuits ou des Open source.
2.1. Bootloader chargePIC16F88
Environnement de développement MICROCHIP: MPLAB IDE v8.92.
Langage de programmation: assembleur MPASMWIN v5.51 . Je reste fidèle à l’assembleur qui, pour moi, reste le moyen le plus simple et le plus clair d’obtenir la meilleure solution à ce type de problème.
2.2. Application hôte chargePIC
Environnement de développement MICROSOFT: IDE Microsoft Visual Studio 2015 pour Windows Desktop.
Langage de programmation: Microsoft Visual C# 2015 .
3. Choix du dispositif de communication
PC : Lignes de communication Emission/Réception : port série RS232.
Interface : Liaison série: asynchrone, convertisseur RS232 TTL MAX3232.
PIC : Lignes de communication Emission/Réception UART: bornes TX et RX du PIC.
La trame UART est constituée des bits suivants :
- un bit de start servant à la synchronisation du récepteur,
- 8 bits de données,
- pas de bit de parité,
- un bit de stop.
4. Mise en oeuvre du Bootloader chargePIC16F88
La figure 1, ci-contre, montre le diagramme fonctionnel du dispositif. Comme vous pouvez le constater, il est le fils de usartELOADER décrit dans l’article précédent, implémenté de nouvelles fonctions. Le protocole de transmission a été revisité.
4.1. Initialisation
Le programme doit être chargé une première fois au moyen d’un programmateur. J’ai utilisé mon programmateur et l’excellent PICpgm. L’opération est sans souci. Le 16F88 s’insère sur le support ZIF de la même manière que le 16F84.
4.2. Test de bon fonctionnement
Le bootloader est fourni préchargé dans l’espace utilisateur avec un petit programme qui fait simplement clignoter une LED. Pour le faire fonctionner, connecter en série sur la broche 1 du PIC (port RA2) une résistance de 470 Ω et une LED. Sur le PC, activer chargePIC (qui sera décrit ci-après), cliquer sur Connecter (Login) puis sur Exécuter (Run). La LED doit clignoter, signe que tout va bien ! Ce petit programme sera naturellement détruit ensuite par le chargement de votre propre application.
4.3. Application utilisateur
Un exemple d’application est donné ci-dessous. Il faut veiller à rester dans les limites de la mémoire dédiée à l’application. Le logiciel chargePIC prévient tout effacement du Bootloader et signale les débordements.
__CONFIG _CONFIG1, _INTRC_IO & _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;------------------------- ; Programm Vector Address RESET_VECTOR EQU 0x0000 ; Address of RESET Vector ISR_VECTOR EQU 0x0004 ; Address of Interrupt Vector BANK0_RAM_DATA EQU 0x0020 ; 16 General Purpose registers (SRAM) COMMON_RAM_DATA EQU 0x0070 ; 16 General Purpose registers (SRAM) EEPROM_DATA EQU 0x2100 ; EEPROM address ;---------------------------------------------------------------------- ; BOOTLOADER RESET SEGMENT RESERVED 32 WORDS ;---------------------------------------------------------------------- BLOADER_OFFSET EQU 0x20 ORG RESET_VECTOR goto RESET_VECTOR+BLOADER_OFFSET ; interrupt vector ORG ISR_VECTOR goto RESET_VECTOR+BLOADER_OFFSET+4 ;---------------------------------------------------------------------- ; END BOOTLOADER RESET SEGMENT RESERVED 32 WORDS ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- ; USER APPLICATION SEGMENT ;---------------------------------------------------------------------- ; Re-mapped Reset Vector ORG RESET_VECTOR+BLOADER_OFFSET UserReset goto UserStart ; Re-mapped Interrupt Vector ORG RESET_VECTOR+BLOADER_OFFSET+4 UserISR ;retfie goto UserInterrupt ;---------------------------------------------------------------------- ; USER PROGRAM STARTS HERE ;---------------------------------------------------------------------- UserStart Main #DEFINE LED PORTA,2 ; LED banksel PORTA clrf PORTA clrf PORTB ; set up option register bsf STATUS,RP0 ; Bank1 movlw B'00001000' ; 0------- NOT RBPU: 0 = PORTB pull-ups are enabled by individual port latch values ; -0------ INTEDG: 0 = Interrupt on rising edge of RB0/INT pin ; --0----- T0CS: 1 = Transition on GP2/T0CKI pin0=output ; ---0---- T0SE: 1 = Increment on high-to-low transition on /T0CKI pin not used, MCLR and reset ; ----1--- PSA: 1 = Prescaler is assigned to the WDT ; -----000 PS2:PS0: 111= 1:128 prescaler movwf OPTION_REG bcf LED ; TRISA output bcf STATUS, RP0 ; Bank0 MainLoop bsf LED ; LED on call delay bcf LED ; LED off call delay nop nop goto MainLoop ; For Ever Loop------> ;------------------------- ; USER PROGRAM SUBROUTINES ;------------------------- delay movlw 2 movwf cmpt3 delay3 clrf cmpt2 delay2 clrf cmpt1 delay1 nop decfsz cmpt1, f goto delay1 decfsz cmpt2, f goto delay2 decfsz cmpt3, f goto delay3 return ;------------------ ; INTERRUPT MANAGER ;------------------ UserInterrupt ;save register movwf ISRwreg ; WREG swapf STATUS,w ; STATUS without change Z movwf ISRstatus ; ;restore register UserInterrupt_end swapf ISRstatus,w ; STATUS without change Z movwf STATUS swapf ISRwreg,f ; WREG without change Z swapf ISRwreg,w retfie ; return from interrupt set GIE ;---------------------------------------------------------------------- ; EEPROM ;---------------------------------------------------------------------- org EEPROM_DATA ;---------------------------------------- ; Month Day Year Vnum EE_VERSION DE D'11',D'20',D'15',1,0,0 EE_SETTING DE "chargePIC_led: TEST ONE BLINK LED ON RA2 PORT" ;---------------------------------------------------------------------- ; END USER APPLICATION SEGMENT ;----------------------------------------------------------------------
Télécharger le programme source, le fichier .hex et tous les schémas.
5. L’application chargePIC
Comme indiqué dans le cahier des charges, c’est à chargePIC que revient le plus gros du travail.
Un mot sur la régionalisation. Visual studio offre une excellente prise en charge de la régionalisation. Le logiciel a été écrit pour être traduit. Il est fourni en 2 langues, français et anglais qu’il est possible de choisir dans l’onglet Setting, mais il est prévu pour supporter d’autres langues. Tous les textes sont mémorisés en anglais dans le fichier par défaut LocalStrings.resx et traduit en français dans LocalStrings.fr-FR.resx. Comme d’habitude tous les sources seront disponibles en téléchargement. Pour les utilisateurs d’une autre langue, il suffit de créer son fichier LocalStrings.de-DE.resx (Allemand par exemple) et de traduire les textes des boutons, labels, onglets, etc, de la fenêtre. Il faut aussi modifier le constructeur de la classe HomeForm en y indiquant sa culture.
// Default language
if (settings.LanguageFrench)
Thread.CurrentThread.CurrentUICulture = FrenchCulture;
else
Thread.CurrentThread.CurrentUICulture = EnglishCulture;
5.1. Fenêtre principale MainForm
A l’ouverture, la première fenêtre, figure 2, affiche les éléments suivants:
- Le menu,
- La barre d’outils,
- Les propriétés du PIC en cours de programmation en hexadécimal et décimal,
- Les propriétés du Bootloader en hexadécimal et décimal,
- L’onglet Fichier Hex,
- Le journal (fichier log).
Le port par défaut est COM1, chez moi je n’ai que celui-là. Si vous en avez d’autres à vous de choisir dans la liste. Vérifier sur le journal que le port est bien ouvert.
Cliquer sur le bouton Login. Ceci a pour effet de charger les propriétés du Bootloader et de créer l’image mémoire.
Vérifier sur le journal que l’opération s’est bien passée.
Pour importer le fichier hex cliquer sur le bouton Importer fichier hex. L’onglet Fichier Hex se divise en 3 parties:
- à gauche la liste brute des articles du fichier hex,
- au centre la liste des instructions après analyse du fichier hex,
- à droite les valeurs de config1 et config2 et la plus haute adresse utilisée par le programme.
En cas de débordement sur le Bootloader un message erreur est écrit sur le Log.
5.2. Mémoire image
A ce stade du travail, les onglets Mémoire programme et EEPROM montrent l’état de la mémoire qui sera chargée dans le PIC. En rouge, l’espace protégé du Bootloader qui ne sera pas changé, en bleu, l’espace réservé à l’application utilisateur qui pourra être réécrit. La figure 3 ci-contre, montre en rouge, le segment que j’ai appelé offset qui contient le vecteur de reset et de logout du Bootloader ainsi que les adresses qui redéfinissent le vecteur d’interruption et le vecteur de reset de l’application utilisateur. La figure 4 ci -dessous, montre la partie haute de la mémoire contenant le Bootloader proprement dit. La figure 5, montre l’EEPROM qui est exclusivement utilisée par l’application utilisateur. Cet espace étant en général utilisé pour conserver des paramètres de fonctionnements ou des résultats, cette fenêtre nous offrira un moyen de tracer nos programmes puisque chargePIC nous permet de le relire.
Télécharger tous les programmes sources, hex, exe, et fichiers: Bootloader chargePIC16F88: avec petit programme démo. chargePIC16F88_led + chargePIC VISUAL C# 2010 projet complet avec sources et exe+Schémas Inkscape.
6. Utilisation de HI-TECH C Compiler
La version picc_9_83 est disponible gratuitement sur le site de MICROCHIP (choisir l’onglet Downloads Archive). L’installation est simple et rapide. Cocher la case version Lite pour une utilisation non professionnelle gratuite. Lorsque vous créez un projet qui utilise HI-TECH C et le Bootloader chargePIC16F88, il faut indiquer la taille de l’offset. Pour ce faire, quand le projet est créé, cliquer dans le menu sur Project>Build Options>Project. Choisir l’onglet Linker. Dans Linker options Codeoffset entrer 0×20 qui est la taille du premier bloc du Bootloader, voir Figure 6 ci-dessous. Cliquer sur OK pour terminer. Ci-dessous, le même programme écrit et compilé avec HI-TECH C. Un petit coup d’oeil sur la map, figure 7 ci-dessous, pour voir que le vecteur de Reset et d’interruption ont été décalés de 0×20.
/******************************************************************************* ; File Name : led16F88_test1.c ; Version : 1.0 ; Title: : BLINK LED TEST and USART Bootloader ; Author : F8EOZ Bernard DECAESTECKER http://f8eoz.com ; MCU : Written and Tested on Microchip PIC 16F88 Microcontroller ; Compiler : HI_TECH ANSI C Compiler V9.83 ; IDE : Microchip MPLAB IDE v8.92 ; Programmer : Home made ; Last Updated : 17 December 2015 ; ******************************************************************* ; Hardware: ; Tested with PIC16F88 at 4Mhz internal oscillator. ; USART use pin 8 as RX (RB2) ; USART use pin 11 as TX (RB5) ; ******************************************************************* */ #include <pic.h> #include <htc.h> // __CONFIG _CONFIG1, _INTRC_IO & _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO // __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF #if defined(_16F88) || defined(_16F87) //1st: CONFIG1 __CONFIG (FOSC_INTOSCCLK & CP_OFF & CCPMX_RB0 & DEBUG_OFF & WRT_OFF & CPD_OFF & LVP_OFF & BOREN_ON & MCLRE_ON & PWRTE_ON & WDTE_OFF & FOSC_INTOSCIO & IESO_OFF & FCMEN_OFF); //next: CONFIG2 __CONFIG (IESO_OFF & FCMEN_OFF); #else #error Must be compiled for 16F88, or 16F87 #endif #ifndef _XTAL_FREQ // Unless already defined assume 4MHz system frequency // This definition is required to calibrate __delay_us() and __delay_ms() #define _XTAL_FREQ 4000000 #endif #define LED RA2 //bit 2 of PORTA #define TRISLED TRISA2 //bit 2 of PORTA void interrupt tc_int(void) { return; } void main() { TRISLED = 0; //Output PORTA = 0b00000000; // clrf PORTA PORTB = 0b00000000; // clrf PORTB OPTION_REG = 0b00001000; // 0------- NOT RBPU: 0 = PORTB pull-ups are enabled by individual port latch values // -0------ INTEDG: 0 = Interrupt on rising edge of RB0/INT pin // --0----- T0CS: 1 = Transition on GP2/T0CKI pin0=output, // ---0---- T0SE: 1 = Increment on high-to-low transition on /T0CKI pin not used, MCLR and reset // ----1--- PSA: 1 = Prescaler is assigned to the WDT // -----000 PS2:PS0: 111= 1:128 prescaler LED = 0; while(1) { LED = 1; // LED ON __delay_ms(100);// delay for 100 milliseconds CLRWDT(); LED = 0; // LED OFF __delay_ms(100);// delay for 100 milliseconds } }
Télécharger tous les programmes sources, hex, exe, et fichiers: Bootloader chargePIC16F88: avec petit programme démo. chargePIC16F88_led + led16F88_test1.c HI-TECH C + chargePIC VISUAL C# 2010 projet complet avec sources et exe + Schémas Inkscape.
A suivre…
Index des articles de la catégorie microcontroleur