- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: PIC 18F Bootloader Problem

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    20.12.2005
    Beiträge
    11

    PIC 18F Bootloader Problem

    Anzeige

    Praxistest und DIY Projekte
    Hallo,
    ich habe ein Problem.
    Habe in C einen Bootloader geschrieben, und ihn auf die Adresse
    0x0000 bis 0x1FFF gelegt (gesichert).
    Meine zweite Applikation versuche ich ab Adresse 0x2000 bis 0x7FFF zu legen aber, wenn ich von meiner Bootloader Applikation mit "goto 0x2000"
    springe dann passiert garnichts.
    Jetzt weiß ich leider nicht ob ich das auch mit den zwei Applikationen richtig mache oder nicht?
    Ich Flashe erst die Hauptapplikation und dann Flashe ich den Bootloader über Microchip MPLAB ICD2.
    Wenn ich jetzt aber denn Bootloader auf den PIC geflasht habe,
    dann habe ich auch den _startup der Hauptapplokation überschrieben.
    Wie springe ich dann in dieses Programm?

    Danke im voraus.

  2. #2
    Hallo Thomas,
    wenn man einen Bootloader programmiert, dann kann man in drei Fallen tappen:

    1: Man hat eine Bautrate im PIC gewählt, die laut Datenblatt eine Abweichung von > 4,5 % von der Standart-Bautrate hat. Wenn man dann grosse Datenblöcke überträgt mit 8N1 und keine Prüfsumme bildet, kann es zu Übertragungfehlern kommen.

    2: Der Bootloader liegt im Bereich 0x00 - 0xXXX und man hat vergessen das im Bereich 0x0004 - 0x0008 die Adressen für die ISR gespeichert werden. Wird ein Programm geladen, das Interupts benutzt, dann wird der Bootloader beschädigt.

    3: Das C-Porgramm wurde den Adressbereich 0x0000 - 0xXXXX compiliert und an eine Adresse 0X0500 gespeichert, dann hat der Compiler die falschen absoluten Rücksprungadressen generiert

    Umgehen könnte man Problem 2 und 3, indem man den Bootloader nach oben schiebt und das eigentliche Programm im Bereich 0X0000 -0xXXXXX laufen lässt.
    Proglem 1 kann man nur durch probieren und Kontrollroutinen beheben

    Ich hoffe es hilft Dir ein wenig!
    GRUSS
    INGO

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    20.12.2005
    Beiträge
    11
    Hi,
    hier ein Auszug der Linker Datei:

    1. Hauptprogramm
    CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED
    CODEPAGE NAME=page START=0x2A END=0x5FFF

    2. Bootloader:
    CODEPAGE NAME=vectors START=0x0 END=0x6029 PROTECTED
    CODEPAGE NAME=page START=0x602A END=0x7FFF

    Der interruptvektor liegt bei 1. auf 0x08, der interruptvektor bei 2. liegt auf 0x6008.

    Auszug aus HEX-File:
    1. Hauptprogramm
    :02 0000 040000FA
    :06 0000 00F0EF10F0120009
    :06 002A 0001000E2200009F
    :08 0030 0091000000080000002F
    :04 00BC 008E0E286E0E
    :10 00C0 002E6A256A246A72EF00F08E0E286E27C011

    2. Bootloader:
    :02 0000 040000FA
    :06 0000 002BEF39F01200A5
    :06 6008 0024EF38F0120045
    :06 602A 000100727200008B
    :08 6030 007600000002000000F0

    Ist es möglich das das Programm beim Bootloader nicht bei
    0000 002BEF39F01200A5 anfängt sondarn erst ab der Adresse 0x6000,
    den sprung würde ich dann auf diese Adresse machen.
    Das Problem ist er hat ja immer seinen goto _startup auf 0x0000 liegen.
    Kann man dies manipulieren.

    Vielen Dank für deine Hilfe

  4. #4
    Hallo Thomas,

    ich habe gerade noch mal in das Datenblatt gesehen, die Interuptvectoren liegen bei 0x0008 bzw. 0x0018.

    Wenn ich das richtig interpretiere, dann liegen in Deiner HEX-Datei sowohl der Start-Vector für das Hauptprogramm als auch für das Bootloaderprogramm an der Stelle 0x0000.
    Das geht aber nicht!!!!!
    Du musst den C-Compiler so herrichten, dass er die Startadresse für das Hauptprogramm an eine Stelle legt, die ausserhalb des Bootloaders liegt!! Vom Bootloader aus springst Du dann an diese Stelle und erreichst so Dein eigentliches Programm!! (welchen C-Compiler nutzt Du?)

    GRUSS
    INGO

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    20.12.2005
    Beiträge
    11
    Hi,
    ich benutzte den mcc18 Compiler.
    Ich habe es auch schon mit | #pragma code | probiert.
    Er hat mir das Programm zwar auf eine bestimmte Adresse gelegt, nur ich wusste danach nicht wo der Bootloader endet, da er alles andere hinter den Bootloader gelegt hat.

    Kann man nicht über MPLAB IDE das irgendwie einstellen,
    dass nur ein Programm als _startup da ist und das andere Programm einfach auf eine Adresse gesetzt wird, das ich dann anspringen kann.

  6. #6
    kann man nicht über MPLAB IDE das irgendwie einstellen,
    dass nur ein Programm als _startup da ist und das andere Programm einfach auf eine Adresse gesetzt wird, das ich dann anspringen kann.
    Das musst Du so oder so machen!!! Du musst erst den Bootloader schreiben. Dann (wenn der läuft) schreibst Du Dein Hauptprogramm, dass dann mit dem Bootloader in den PIC übertragen und gestartet wird.

    Kleine Hilfe:
    Wenn Du Deinen Bootloader compiliert hast dann schau doch im Project-Verzeichnis mal nach einer Datei mit der Endung .....lst. Da steht das Assemblerprogramm drinn und man kann sehen welche Speicherzellen es belegt und wo es anfängt und aufhört.

    Ich bin kein C-Experte, da ich die PIC´s in Assembler programmiere. Ich bin mir aber sicher, das es im Compiler Meta-Kommandos gibt, mit denen man die Startadresse und das verhalten des Linkers beeinflussen kann!

    GRUSS
    INGO

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    20.12.2005
    Beiträge
    11
    Danke,
    ich werde das morgen gleich auf der Arbeit probieren.
    Ich schreibe dir dann, ob es geklappt hat.

    Vielen Dank

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    20.12.2005
    Beiträge
    11
    Hi,
    habe es geschafft das mein zweites Projekt ab Adresse 2000 beginnt,
    ohne das er bei 0x0000 ein goto Befehl reinschreibt.
    Habe dazu die c018i.c ein wenig manipuliert.


    extern void main (void);
    void _entry (void);
    void _startup (void);
    void _do_cinit (void);

    extern volatile near unsigned long short TBLPTR;
    extern near unsigned FSR0;
    extern near char FPFLAGS;
    #define RND 6

    #pragma code _entry_scn=0x000000
    void _entry (void)
    {
    _asm goto _startup _endasm
    }
    #pragma code _startup_scn
    void _startup (void)
    {
    _asm
    lfsr 1, _stack lfsr 2, _stack clrf TBLPTRU, 0
    bcf FPFLAGS,RND,0
    bsf 0xa6, 7, 0
    bcf 0xa6, 6, 0
    _endasm
    _do_cinit ();

    loop:

    main ();

    goto loop;
    }

    extern far rom struct
    {
    unsigned short num_init;
    struct _init_entry
    {
    unsigned long from;
    unsigned long to;
    unsigned long size;
    }
    entries[];
    }
    _cinit;

    #pragma code _cinit_scn
    void
    _do_cinit (void)
    {
    static short long prom;
    static unsigned short curr_byte;
    static unsigned short curr_entry;
    static short long data_ptr;

    // Initialized data...
    TBLPTR = (short long)&_cinit;
    _asm
    movlb data_ptr
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf curr_entry, 1
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf curr_entry+1, 1
    _endasm

    test:
    _asm
    bnz 3
    tstfsz curr_entry, 1
    bra 1
    _endasm
    goto done;

    _asm
    /* read the source address */
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf prom, 1
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf prom+1, 1
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf prom+2, 1
    /* skip a byte since it's stored as a 32bit int */
    tblrdpostinc
    /* read the destination address directly into FSR0 */
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf FSR0L, 0
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf FSR0H, 0
    /* skip two bytes since it's stored as a 32bit int */
    tblrdpostinc
    tblrdpostinc
    /* read the destination address directly into FSR0 */
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf curr_byte, 1
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf curr_byte+1, 1
    /* skip two bytes since it's stored as a 32bit int */
    tblrdpostinc
    tblrdpostinc
    _endasm

    data_ptr = TBLPTR;

    /* now assign the source address to the table pointer */
    TBLPTR = prom;

    /* do the copy loop */
    _asm
    // determine if we have any more bytes to copy
    movlb curr_byte
    movf curr_byte, 1, 1
    copy_loop:
    bnz 2 // copy_one_byte
    movf curr_byte + 1, 1, 1
    bz 7 // done_copying

    copy_one_byte:
    tblrdpostinc
    movf TABLAT, 0, 0
    movwf POSTINC0, 0

    // decrement byte counter
    decf curr_byte, 1, 1
    bc -8 // copy_loop
    decf curr_byte + 1, 1, 1
    bra -7 // copy_one_byte

    done_copying:

    _endasm
    /* restore the table pointer for the next entry */
    TBLPTR = data_ptr;
    /* next entry... */
    curr_entry--;
    goto test;
    done:
    ;
    }


    Jetzt habe ich das Problem, wenn ich das erst Hex file auf den Pic
    flashe und danach das zweite, dann überschreibe ich das erste Hex file.

  9. #9
    Da Du das Problem mit dem Compiler gelöst hast, würde ich sagen, das Du ein Problem mit dem Bootloader hast. Da stimmt was nicht mit der Auswertung der Startadresse.
    Wenn ein Programm ab Adresse 2000h compiliert wird, dann muss es dort auch landen!

    GRUSS
    INGO

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    20.12.2005
    Beiträge
    11
    Ich hab das Programm auf den Pic geflasht und es lief.
    Habe mir dann die Program Memory angeschaut, es teht alles ab
    adresse 0x2000. Das Programm läuft auch.
    Meinst du ich soll das anders lösen.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress