PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC 18F Bootloader Problem



Thomas1234567
12.01.2006, 16:16
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.

ingo_46
13.01.2006, 15:52
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

Thomas1234567
14.01.2006, 12:01
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

ingo_46
14.01.2006, 13:27
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

Thomas1234567
14.01.2006, 14:14
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.

ingo_46
14.01.2006, 16:07
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

Thomas1234567
15.01.2006, 14:15
Danke,
ich werde das morgen gleich auf der Arbeit probieren.
Ich schreibe dir dann, ob es geklappt hat.

Vielen Dank

Thomas1234567
16.01.2006, 14:26
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.

ingo_46
16.01.2006, 17:23
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

Thomas1234567
17.01.2006, 09:34
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.

Thomas1234567
17.01.2006, 09:35
Ich hab das Programm auf den Pic geflasht und es lief.
Habe mir dann die Program Memory angeschaut, es steht alles ab
Adresse 0x2000. Das Programm läuft auch.
Meinst du ich soll das anders lösen.

thomasstoll
17.01.2006, 09:45
Hi Thomas,
warum schreibst du eigendlich den Bootloader selbst? Gerade für die PIC18F's gibt es doch von Microchip schon einen fertigen. Der funktioniert wunderbar, den hab ich erst vor ein paar Tagen ausprobiert. Es gibt aber noch eine böse Falle im Zusammenspiel zwischen Bootloader und ICD2. Wenn der ICD2 im Debuger-Modus läuft und das Programm dann aus diesem Modus heraus in den PIC übertragen wurde, dann Zeigt die Startadresse auf eine Adresse ziemlich am ende des Speicherbereiches, weil der ICD2 dort ein kleines (120byte grosses) Programm ablegt. Das Programm benötigt der ICD2 zum Debugen. Es kann unter umständen passieren das hier mehrere dinge sich nicht miteinander vertragen. Wenn du also einen Bootloader verwendest, solltest du das Programm am besten über den normal Programmer- Modus in den PIC schieben, dann wird das kleine Hilfsprogramm nicht mit übertragen.
Wenn du aber unbedingt einen Bootloader selbst Programmieren willst, warum setzt du den nicht ans ende des Speicherbereichs? Dann hast du nicht die Probleme mit dem Adressen- verbiegen in deinem Hauptprogramm, das kann dann ganz normal bei 0h starten. So macht das der Microchip Bootloader auch.

gruss
Thomas