USB-Bootloader

mit PIC18F2550

zurück zu 18F-Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage

Derjenige, dem es weniger auf die Details ankommt, sondern der den Bootloader einfach nur anwenden möchte, der schaue bitte auf diese Seite.


Bootloader - Allgemeines
Ein fertiger Bootloader
Grundlagen
Limits
USB-Bootloader von Microchip
Anpassen des USB-Bootloaders an eigene Bedürfnisse

Projektpfade
Anpassen der Konfiguration
Der Bootloader-Schalter

LEDs
Bus Powered
Taktquelle
Konfiguration-Taktquelle
C18-Einstellungen
Schrumpfkur
Linker Script für die Anwendersoftware

zurück


Bootloader - Allgemeines

Die PIC18F-Typen mit USB-Interface, sind in der Lage,in den eigenen Flash-Speicher zu schreiben. Damit besteht die Möglichkeit, dem PIC ein neues Programm über die USB-Schnittstelle zuzuspielen, das der PIC dann selber in den Flash brennt und anschließend startet. Dafür muss im PIC natürlich schon vorher eine Software stehen, die den neuen Code über die Schnittstelle entgegennimmt, und in den Flash brennt.

Diese Software nennt man den Bootloader. Sie muss vorab auf konventionellem Wege in den PIC gebrannt werden, also in einem Brenner.

Der Bootloader wird  aber nur ein Mal in den PIC gebrannt, danach steht er für viele USB-Brennvorgänge zur Verfügung. Das bringt deutliche Vorteile, wenn die Software in einem PIC häufig modifiziert werden muss, insbesondere dann, wenn der Nutzer des PIC-gesteuerten Gerätes gar keinen eigenen Brenner besitzt. Man könnte damit also Firmwareupdates mit Hilfe eines einfachen  PCs durchführen.

nach oben

Ein fertiger USB-Bootloader

Zunächst erst einmal ein fertiger Bootloader (mein Bootloader Nr.2)  zum Ausprobieren. Alle Details folgen darunter.
Das ist ein USB-Bootloader, der auf dem Bootloader von Miocrochip basiert. Er ist in C geschrieben, und kann mit der Student-Edition des C18-Compilers compiliert werden, nachdem die Projekt-Pfade an den eigenen PC angepasst wurden. Er passt in den Bootblock des PIC18F2550.

Der PIC arbeitet mit einem 8 MHz-Quarz oder einem 8 MHz Keramikresonator.
Der Bootloader wird aktiviert, indem man zuerst den Jumper JP1 (an RE3 bzw. MCLR/Vpp) steckt, und dann das Gerät an den USB-Bus anschließt. Mit dem aufleuchten der LED (an RB7) zeigt der Bootloader an, dass er gestartet ist.

Mit Hilfe des Windowsprogramms USBoot kann dann eine beliebige Software via USB in den PIC gebrannt werden, deren Startadresse 0x800 sein muss (siehe unten). Da ich meine eigene VID_PID verwende, kann das PICDEM FS USB Demo Tool nicht anstelle von USBooot verwendet werden.

anklicken zum Vergrößern
Prgrammfenster Vor der Benutzung des Bootloaders muss der USB-Treiber (von Microchip) installiert werden. Er liegt im Zip-File von USBoot. Dieser Treiber enthält eine Anpassung an meine VID_PID, er sollte also auch installiert werden, falls der Microchip-USB-Treiber bereits einmal (z.B. für ein PICDEM FS USB DEMONSTRATION BOARD) installiert wurde.

Nach dem Anstecken des USB-Gerätes mit dem Bootloader und gestecktem Jumper JP1, fordert Windows zur Installation auf. (Der Jumper muss während des Ansteckens gesteckt sein. Ein nachträgliches Jumpersetzen funktioniert nicht!)
Die Testplatine findet man jetzt im Gerätemanager als sprut-device (eventuell auch als Brenner8, falls der Treiber schon installiert war.) Im Gerätemanager muss man unter Eigenschafen unbedingt Windows verbieten, das Gerät zum Energiesparen abzuschalten. Andernfalls wird das Brennen mit dem Bootloader extrem langsam.

Danach kann USBoot aufgerufen werden. Findet es den Bootloader am USB-Bus, dann kann mit dem Button 1 (Upload new Firmware) ein HEX-File ausgewählt und in den PIC geladen werden. 

Der Jumper ist zu entfernen, und der Button 2 (Reset) zu drücken. Die in den PIC geladene Software startet.

USBoot beschreibt nur den Flash-Speicher ab der Adresse 0x800. Der Boot-Block (mit dem Bootloader), der EEPROM und die Config werden nicht verändert.

Damit man auch etwas hat, das man mit dem Bootloader laden kann, hier eine abgewandelte Version des einfachen LED-Blinkprogramms. Es schaltet abwechselnd die Pins RB0 und RB7 ein und aus. Zwei dort angeschlossenen LEDs blinken abwechselnd mit ca. 0,6 Hz.

  

Nicht jeder wird den Jumper an RE3 (MCLR/Vpp) und die LED an RB7 anschließen wollen. Vielleicht will man auch einen anderen Quarz/Resonator einsetzen. Wie man den Bootloader an die eigenen Bedürfnisse anpasst, das kann man im Folgenden erfahren.

nach oben

Grundlagen

Ich beziehe mich auf den Typ PIC18F2550, prinzipiell gelten die Aussagen aber für alle PIC18F mit USB-Interface.

Der Bootloader muss sich mit dem in den PIC zu brennenden Anwendungsprogramm gut vertragen. Darum sollte der Bootloader in einem Flash-Speicherbereich stehen, der vom Anwendungsprogramm nicht verwendet wird.
Beim PIC18F2550 ist dafür der Boot-Block vorgesehen. Er ist 1024 Worte groß, und liegt am Anfang des Flash-Speichers (0x0000 ... 0x07FF). Ist der Bootloader in diesen Bereich gebrannt, dann lässt sich dieser Bootblock mit einem Schreibschutz versehen. Dadurch ist er davor geschützt, durch versehentliche falsche Schreibzugriffe beschädigt zu werden. Da der Bootloader immer wieder eingesetzt werden soll, darf er sich nicht versehentlich selbst überschreiben.

Im Bootblock liegt aber auch der Resetvektor (bei dem der PIC mit der Abarbeitung des Programms beginnt) und die beiden Interruptvektoren. Der Bootloader muss deshalb diese Vektoren "umbiegen".

Das Anwendungsprogramm, das vom Bootloader geladen wird, darf natürlich den Speicherbereich des Flash-Bootloaders nicht verwenden. Ein solches Programm beginnt also nicht an der Adresse 0x0000 sondern an 0x0800 (direkt hinter dem Bootblock). Die Interruptroutinen müssen über die "umgebogenen" Vektoren verwaltet werden. Folglich muss ein Programm, das vom Bootloader geladen werden soll, speziell angepasst werden.
 

Beim Reset des PIC muss zunächst der Bootloader gestartet werden. (Dafür steht an der Adresse0x0000 des Flash ein Sprung zum Bootloader.) Er überprüft, ob eine neue Software in den PIC gebrannt werden soll. Dazu ist z.B. ein an einem Pin angeschlossener Schalter bzw. Jumper abzufragen.

Wenn es nichts zu brennen gibt, muss der Bootloader das Anwendungsprogramm starten, das sich z.Z. neben dem Bootloader im Flash befindet. Dieses Programm muss den PIC so vorfinden, als wäre der Bootloader nach dem Reset nie gelaufen. Der Bootloader muss also alle relevanten Veränderungen, die er in den PIC-Registern vorgenommen hat wieder rückgängig machen, bevor er das Nutzprogramm startet.

nach oben


Limits

Der Bootloader darf bedenkenlos in den Flash-Programmspeicher (mit Ausnahme des Boot-Blocks) und den EEPROM-Datenspeicher schreiben.

Er kann auch die Konfiguration verändern. Hierbei ist aber Vorsicht geboten. Einige Konfigurationseinstellungen sind für die Funktion des USB-Interfaces von Bedeutung. Werden diese vom Bootloader verändert, dann kann der Bootloader von da an nicht mehr funktionieren. Das betrifft z.B. die Taktgeneratoreinstellung des PIC
 

nach oben

USB-Bootloader von Microchip

Ich beziehe mich im Weiteren auf das Microchip-USB-Framework in der Version 1.3 vom Anfang 2008. Bei Nachfolgeversionen kann es zu Änderungen kommen.

Von Microchip gibt es einen freien USB-Bootloader, den man sich als C-Projekt von der Microchip-Homepage laden kann. Er ist Bestandteil des Microchip-USB-Framework, das man als selbstenpackende EXE-Datei von der Microchip-Homepage herunterladen kann (MCHPFSUSB_Setup_v1.3.exe)
Er entpackt den Bootloader nach C:\MCHPFSUSB\fw\Boot. Das ist ein C-Projekt mit allen Quelltexten.

Er ist aber auf das PICDEM FS USB DEMONSTRATION BOARD von Microchip zugeschnitten. Diese Experimentierplatine ist mit einem PIC18F4550 bestückt.
Der Bootloader startet beim Anlegen der Betriebsspannung (oder Reset) und Testet einen Schalter ab, der am Pin RB4 entweder 0V oder 5V anlegt. Bei 5V wird das Nutzprogramm gestartet, bei 0V startet der Bootloader. Während der Arbeit zeigt der Bootloader seinen Status mit vier LEDs an, die an die Pins RD0..RD3 angeschlossen sind.

Für Anwendungen außerhalb des PICDEM FS USB DEMONSTRATION BOARD muss der Bootloader aus folgenden Gründen modifiziert werden:

Eine weitere Schwäche des  Microchip-Quellcodes ist, das er keine Konfigurationseinstellungen enthält.
nach oben

Anpassen des USB-Bootloaders an eigene Bedürfnisse

HINWEIS:
Seit Nutzung des Microchip-USB-Framework in der Version 1.3 vom Anfang 2008 kommt es vor, dass ein fertiger Bootloader von Windows nicht korrekt erkannt wird (Code 10). In diesem Fall empfehle ich das den Bootloader des Framework 1.0 zu verwenden.

Die Änderungen lassen sich recht einfach vornehmen. Danach compiliert man die modifizierten Quellen einfach mit dem C18-Compiler von Microchip.  Der erzeugte Bootloader passt geradeso in den Bootblock, aber nur, wenn man alle Optimierungsfunktionen des Compilers benutzt.

Die freie Student-Edition des C18-Compilers hat aber leider nicht alle diese Optimierung. Folglich erzeugt sie einen Code, der für den Boot Block etwas zu groß ist.
Entfernt man aus dem Bootloader-Code aber alles Überflüssige (insbesondere die Spielerei mit dem LEDs), dann erzeugt auch die Student-Edition des C18 einen Code, der in den Boot-Block passt.

nach oben

Projekt-Pfade

Im Verzeichnis C:\MCHPFSUSB\fw\Boot\ befindet sich das Projektfile MCHPUSB.mcp, das man mit MPLAB öffnen kann. Es enthält Pfadeinstellungen, die sich auf die Standardinstallationspfade von MPLAB und C18 (c:\mcc18\) beziehen. Hat man C18 in einem anderen als dem Standardverzeichnis installiert, dann ist in MPLAB unter "Project - Build options - Project" das Build-Options-Fenster zu öffnen, und dort unter Directories der Library search path anzupassen.
Ein Klick auf Make ergibt nun noch Fehlermeldungen, da die Konfiguration nicht richtig eingestellt ist.

Außerdem weist MPLAB eventuell noch daraufhin, dass Compiler und Linker nicht dort liegen, wo sie beim letzten Compilieren (also auf dem Computer auf dem bei Microchip das Projekt erstellt wurde) lagen. Mann wählt in den dabei erscheinenden Dialogboxen den aktuellen Pfad zu Compiler und Linker aus. MPLAB merkt sich das dann.

nach oben

Anpassen der Konfiguration

Frühere Versionen des USB-Framework enthielten gar keine Konfiguration. Nun ist sie im Projekt enthalten. Allerdings passt sie nicht perfekt auf alle USB-PICs. Um den PIC18F4550 oder PIC18F2550 nutzen zu können sind ein paar Konfigurationsoptionen in der Datei main.c durch Vorstellen eines "//" auszukommentieren (FCMEN,  BORV) bzw. zu ändern (PWRT, BOR, MCLRE, WRTB)

C:\MCHPFSUSB\fw\Boot\main.c

...
//#pragma config FCMEN    = OFF
...
#pragma config PWRT     = ON
#pragma config BOR      = OFF
//#pragma config BORV     = 3
...
#pragma config MCLRE    = OFF        //MCLR Disabled    RE3 enabled
...
#pragma config WRTB     = OFF       // Boot Block Write Protection
...

Ein Klick auf Make sollte nun  zu einer fehlerfreien Kompilierung führen. Das entstehende HEX-File entspricht aber noch nicht unseren Ansprüchen (ist auf das Demo-Board zugeschnitten). Außerdem ist es so groß, das es gar nicht in den Bootsektor eines PIC passt (mit der Student-Edition des C18 compiliert).
Ein Klick auf View  -  Program-Memory zeigt, dass der Bootloader momentan noch bis zur Adresse 0x878 geht, dabei ist 0x7FE das Limit für den Bootsektor.

nach oben

Der Bootloader-Schalter

Ein Schalter entscheidet beim Start des PIC, ob der Bootloader ausgeführt wird, oder ob zum Hauptprogramm gegangen wird. Die Abfrage des Schalters am Pin RB4 erfolgt in der Datei main.c in der procedur main, und sieht wie folgt aus:

C:\MCHPFSUSB\fw\Boot\main.c (original)
...
    temp = ADCON1;
    ADCON1 |= 0x0F;
    
    //TRISBbits.TRISB4 = 1;     // Reset value is already '1'
    
    //Check Bootload Mode Entry Condition
    if(PORTBbits.RB4 == 1)      // If not pressed, User Mode
    {
        ADCON1 = temp;          // Restore reset value
        _asm goto RM_RESET_VECTOR _endasm
    }//end if
    
    //Bootload Mode
...

Ich verwende aber einen Schalter am Pin RE3/MCLR. Deshalb muss diese Abfrage im Programm angepasst werden.
In der Zeile "if (PORTBbits.RB4 == 1)"  kann PORTBbits.RB4 durch die Beschreibung jedes anderen Pins ersetzt werden. Ist der Schalter an Pin RE3 angeschlossen, so lautet die Zeile "if (PORTEbits.RE3 == 1)" .
Weiter oben wurde in der Konfiguration bereits das MCLR-Pin zum RE3-Pin gemacht (#pragma config MCLRE    = OFF).

C:\MCHPFSUSB\fw\Boot\main.c  (angepasst)
...
    temp = ADCON1;
    ADCON1 |= 0x0F;
    
    //TRISBbits.TRISB4 = 1;     // Reset value is already '1'
    
    //Check Bootload Mode Entry Condition
//    if(PORTBbits.RB4 == 1)      // If not pressed, User Mode
    if(PORTEbits.RE3 == 1)      // If not pressed, User Mode
    {
        ADCON1 = temp;          // Restore reset value
        _asm goto RM_RESET_VECTOR _endasm
    }//end if
    
    //Bootload Mode
...

I

  nach oben

LEDs

Die Pins, an denen die LEDs angeschlossen sind, sind in der Datei io_cfg.h festgelegt.
Im Beispiel habe ich die Datei so geändert, dass anstelle der 4 LEDs an PortD nur 2 LEDs an den Pins RB0 und RC1 angeschlossen sind. 

C:\MCHPFSUSB\fw\Boot\io_cfg.h
...
/** L E D ***********************************************************/
// LEDs hängen an RB0 (LED1 grün) und RC1 (LED2 gelb)

#define mInitAllLEDs()      LATB &= 0xFE; TRISB &= 0xFE; LATC &= 0xFD; TRISC &= 0xFD;

#define mLED_1              LATBbits.LATB0
#define mLED_2              LATCbits.LATC1

#define mLED_1_On()         mLED_1 = 1;
#define mLED_2_On()         mLED_2 = 1;

#define mLED_1_Off()        mLED_1 = 0;
#define mLED_2_Off()        mLED_2 = 0;

#define mLED_1_Toggle()     mLED_1 = !mLED_1;
#define mLED_2_Toggle()     mLED_2 = !mLED_2;
...

Natürlich muss man alle Zugriffe auf LED_3 und LED_4 aus dem Bootloader entfernen, dafür verändert man zwei Zeilen in boot.c..

C:\MCHPFSUSB\fw\Boot\boot.c
...
            case UPDATE_LED:
                if(dataPacket.led_num == 3)
                {
//                    mLED_3 = dataPacket.led_status;
                    mLED_1 = dataPacket.led_status;
                    counter = 0x01;
                }//end if
                if(dataPacket.led_num == 4)
                {
//                    mLED_4 = dataPacket.led_status;
                    mLED_2 = dataPacket.led_status;
                    counter = 0x01;
                }//end if
                break;
...

Falls man völlig auf LEDs verzichten will, löscht man im Projekt alle Aufrufe der Makros  mInitAllLEDs, mLED_x_On und mLED_x_Off (x steht für 1 ... 4).
  nach oben

Bus-powered

Will man sein USB-Gerät nur aus dem USB-Bus mit Spannung versorgen lassen, müssen zwei Definitionen in der Datei usbcfg.h entfernt werden. Der modifizierte Abschnitt mit den auskommentierten Definitionen  USE_SELF_POWER_SENSE_IO  und USE_USB_BUS_SENSE_IO ist nachfolgend zu sehen. In der Version 1.3 des Framework ist das schon per Default so.

C:\MCHPFSUSB\fw\Boot\autofiles\usbcfg.h
...
/*
 * Both I/O sense pins below are not used in this application.
 * This helps to decrease the size of the firmware code.
 */
//#define USE_SELF_POWER_SENSE_IO
//#define USE_USB_BUS_SENSE_IO

/** D E V I C E  C L A S S  U S A G E *******************************/
...


  nach oben

Taktquelle

Der PIC mit dem Bootloader kann sowohl mit einem Keramikresonator wie auch mit einem Quarz betrieben werden. Wird ein Quarz verwendet, dann sind auch die beiden Lastkondensatoren für den Quarz (C2 & C3) einzusetzen. Wird dagegen ein Keramikresonator eingesetzt, dann entfallen die beiden Kondensatoren.

Als Frequenz für den Resonator/Quarz ist im Beispiel-Bootloader 8 MHz vorgesehen. Der Einsatz anderer Typen ist möglich, wenn folgendes beachtet wird:

Standardmäßig wird die Quarzfrequenz im PIC zunächst mit einem 2:1 Frequenzteiler auf 4 MHz heruntergeteilt. Aus diesen 4 MHz werden anschließend mit einer PLL 96 MHz erzeugt. Diese wiederum dient als Basis für den USB-Takt (2:1 Teilung) und den PIC-Takt (ebenfalls 2:1 Teilung). Die Grafik veranschaulicht das. Dort, wo ich blaue Pfeile verwendet habe, muss die jeweils angegebene Frequenz eingehalten werden.

Die 4 MHz für die PLL lassen sich natürlich nicht nur aus 8 MHz erzeugen. Da der PLL-Vorteiler neben dem Teilverhältnis 2:1 auch die Teilverhältnisse 12:1, 10:1, 6:1, 5:1, 4:1, 3:1 und 1:1 beherrscht, kommen auch Resonatoren/Quarze mit 48 MHz, 40 MHz, 24 MHz, 20 MHz, 16 MHz, 12 MHz und 4 MHz in Frage. Man muss nur die Vorteilereinstellung ändern. Das erfolgt in der Konfigurationseinstellung. mit dem Parameter PLLDIV.

Auch der CPU-Takt ist variabel. Der durch CPUDIV kontrollierte Teiler beherrscht die Teilerverhältnisse 2:1, 3:1, 4:1 und 6:1. Der CPU-Takt kann also durch Änderung von CPUDIV einfach auf bis zu 16 MHz herabgesenkt werden. Auch lassen sich für die CPU andere Taktquellen verwenden (der Quarz ohne PLL oder der interne Takt). Die Details stehen im Handbuch des PIC18F2550.

nach oben

Konfiguration-Taktquelle

Die Konfigurationseinstellungen stehen in der Datei main.c ein. Damit werden sie Bestandteil des HEX-Files. Die originalen Einstellungen in main.c sind für den Betrieb an einem 20 MHz-Quarz ausgelegt.(PLLDIV = 5)

Um den PIC mit einem 8 MHz-Quarz/Resonator zu betreiben muss PLLDIV auf den Wert 2 geändert werden.

Die Beschreibung der möglichen Config-Einstellungen steht im Dokument PIC18-Config-Settings-Addendum_51537d.pdf, das zur Dokumentation von C18 gehört.

C:\MCHPFSUSB\fw\Boot\system\usb\class\boot\main.c
...
//#pragma config PLLDIV   = 5       // (20 MHz input)
#pragma config PLLDIV   = 2       // (8 MHz input)
...



C18-Einstellungen

Damit der Bootloader in den Bootblock des PIC passt (0x0000 .. 0x0800), muss der C18-Compiler einen möglichst effektiven Code erzeugen. Die Optimierungsfunktion und der erweiterte Befehlssatz stehen in der Student-Edition des C18 leider nicht zu Verfügung. Es bleibt aber noch eines zu tun:

Man öffnet in MPLAB das Fenster für die Build Optionen des Projektes: Project - Build Options - Project
Dort wählt man die Karteikarte: MPLAB C18
Den Parameter Default storage class ändert man von Auto auf Static.
Das spart ein paar Byte Code ein, und die können entscheidend sein.
In neueren Versionen des Framework ist diese Einstellung bereits Standard.

nach oben

Schrumpfkur

Um auch mit der Student-Edition des C18 einen Bootloader zu erzeugen, der in den Boot-Block passt, muss der Code verkleinert werden. Alles Überflüssige muss über Bord. Am leichtesten verzichtet man auf die LED-Blinkerei. Deshalb wird in der Datei boot.c ausgemistet.

Zuerst wird am Ende der Datei die ganze BlinkUSBStatus-Funktion entfernt. Dazu muss dann auch der Eintrag von BlinkUSBStatus in PRIVATE PROTOTYPES entfernt werden, wie auch der Aufruf von BlinkUSBStatus in BootService.

C:\MCHPFSUSB\fw\Boot\system\usb\class\boot\boot.c
...
/** P R I V A T E  P R O T O T Y P E S ***************************************/
// DIE FOLGENDE ZEILE MUSS WEG
//void BlinkUSBStatus(void);
...
...
...
void BootService(void)
{
// DIE FOLGENDE ZEILE MUSS WEG
//    BlinkUSBStatus();
    if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;

...
...
...
/*  DIESE ROUTINE MUSS WEG
void BlinkUSBStatus(void)
{
    static word led_count=0;
   
    if(led_count == 0)led_count = 20000U;
    led_count--;

    #define mLED_Both_Off()         {mLED_1_Off();mLED_2_Off();}
    #define mLED_Both_On()          {mLED_1_On();mLED_2_On();}
    #define mLED_Only_1_On()        {mLED_1_On();mLED_2_Off();}
    #define mLED_Only_2_On()        {mLED_1_Off();mLED_2_On();}

    if(UCONbits.SUSPND == 1)
    {
        if(led_count==0)
        {
            mLED_1_Toggle();
            mLED_2 = mLED_1;        // Both blink at the same time
        }//end if
    }
    else
    {
        if(usb_device_state == DETACHED_STATE)
        {
            mLED_Both_Off();
        }
        else if(usb_device_state == ATTACHED_STATE)
        {
            mLED_Both_On();
        }
        else if(usb_device_state == POWERED_STATE)
        {
            mLED_Only_1_On();
        }
        else if(usb_device_state == DEFAULT_STATE)
        {
            mLED_Only_2_On();
        }
        else if(usb_device_state == ADDRESS_STATE)
        {
            if(led_count == 0)
            {
                mLED_1_Toggle();
                mLED_2_Off();
            }//end if
        }
        else if(usb_device_state == CONFIGURED_STATE)
        {
            if(led_count==0)
            {
                mLED_1_Toggle();
                mLED_2 = !mLED_1;       // Alternate blink               
            }//end if
        }//end if(...)
    }//end if(UCONbits.SUSPND...)

}//end BlinkUSBStatus
*/
...

So, das sollte fast schon reichen. Der Bootloader benimmt sich noch genau wie der originale Booloader, und mit Hilfe des PICDEM FS USB Demo Tool von Microchip kann man nun hex-Files via Bootloader in den PIC18F2550 laden.

Wer noch ein paar Bytes mehr einsparen will, der kann in boot.c aus der großen switch-Anweisung den UPDATE_LED-Teil entfernen

C:\MCHPFSUSB\fw\Boot\system\usb\class\boot\boot.c
...
        switch(dataPacket.CMD)
        {
...
...
...
               break;
/* 
            case UPDATE_LED:
                if(dataPacket.led_num == 3)
                {
                    mLED_1 = dataPacket.led_status;
                    counter = 0x01;
                }//end if
                if(dataPacket.led_num == 4)
                {
                    mLED_2 = dataPacket.led_status;
                    counter = 0x01;
                }//end if
                break;
*/ 
            default:
...

was aber zu einer Incompatibilität mit zukünftigen Versionen des PICDEM FS USB Demo Tool führen könnte. Sicherer ist eine Verkürzung des UPDATE_LED-Teils:

C:\MCHPFSUSB\fw\Boot\system\usb\class\boot\boot.c
...
        switch(dataPacket.CMD)
        {
...
...
...
                break;

            case UPDATE_LED:
                counter = 0x01;
                break;

            default:
...

Nun passt der reduzierte Code auch mit der Student-Edition in den Boot-Block  des PIC18F2550.
  nach oben

Linker Script für die Anwendersoftware

Programme, die mit dem Bootloader in den PIC gebrannt werden sollen, müssen dafürt etwas angepasst werden.
Ein angepasstes Linker Script für den C18-Compiler (eigentlich für den Linker) sorgt dafür, das der Code eines Anwenderprogrammes erst ab 0x0800 beginnt.


Wer Interrupts benutzen will, der muss beachten, dass die Interruptvektoren verbogen sind, der immer notwendige Reset-Vektor ist auch verbogen

Deshallb muss man im Programm einfügen: (auch wenn man keine Interrupts benutzt)
main.c

...

/** V E C T O R  R E M A P P I N G *******************************************/

extern void _startup (void);        // See c018i.c in your C18 compiler dir
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
void _reset (void)
{
    _asm goto _startup _endasm
}
#pragma code

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
    ;
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
void _low_ISR (void)
{
    ;
}
#pragma code

...

Das war's. Viel Spaß mit dem eigenen Bootloader.
  nach oben

Anpassen von VID_PID

Der Bootloader ist nun funktionstüchtig. Beim Anschluss an einen PC meldet sich ein mit dem Bootloader ausgestattetes Device mit derVendor-ID  VID=0x04D8 (Hersteller: Microchip)  und der Product-ID  PID0x000B (Microchip-Bootloader im PICDEM FS USB-Board) am USB-Bus an. Dadurch weiss Windows, welchen treiber es laden muss, und PICDEM FS USB Demo Tool das akzeptiert es als Bootloader.

Ich besitze aber für meine Geräte (sprut-Devices) eine eigene PID=0xFF0B, die ich auch für meine Bootloader einsetze. Mein Windows-Tool USBoot erwartet also auch diese PID, und wird Devices mit anderen PIDs nicht akzeptieren. Folglich muss ich für die Nutzung von USBoot noch die PID  des Bootloaders verändern.

Die PID wird im Device-Descriptor eingestellt, welcher wiederum im File usbdsc.c definiert wird. Hier wird nun einfach die Product-ID angepasst, und ab sofort ist ein mit diesem Bootloader ausgestattetets Device ein "sprut-device".

\autofiles\usbdsc.c

...
/* Device Descriptor */
rom USB_DEV_DSC device_dsc=
{    
    sizeof(USB_DEV_DSC),    // Size of this descriptor in bytes
    DSC_DEV,                // DEVICE descriptor type
    0x0200,                 // USB Spec Release Number in BCD format
    0x00,                   // Class Code
    0x00,                   // Subclass code
    0x00,                   // Protocol code
    EP0_BUFF_SIZE,          // Max packet size for EP0, see usbcfg.h
    0x04D8,                 // Vendor ID
//    0x000b,                 // Product ID: PICDEM FS USB (Boot Mode)
    0xFF0B,                 // Product ID: Sprut
    0x0000,                 // Device release number in BCD format
    0x00,                   // Manufacturer string index
    0x00,                   // Product string index
    0x00,                   // Device serial number string index
    0x01                    // Number of possible configurations
};

...

Wurde der in USBoot-ZIP-File enthaltene Treiber installiert, dann weiss windowsa auch, das für ein sprut-Device der Microchip-Treiber zu benutzen ist. Ab sofort kann USBoot mit diesem Bootloader verwendet werden


nach oben


zurück zu 18F-Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage
Autor: sprut
erstellt: 15.08.2006
letzte Änderung 27.02.2008