Hallo allerseits!
Ich versuche nun seit Tagen die Interruptvektoren in einer Applikation,
die per Secondary Bootloader auf einen LPC2366 geladen wird, zum laufen
zu kriegen.
Der Bootloader steht an Adresse 0x0000, die Applikation wird an Adresse
0x6000 ins Flash geschrieben und danach per Funktionspointer aufgerufen.
Dies klappt auch soweit als dass keine Interrupts ausgeloest
werden;dabei stuerzt die Applikation ab bzw. verlaeuft sich im Nirvana.
Dies OBWOHL ich die NXP Appnote dazu befolgt habe und die
Interruptvektoren entsprechend aus der Applikation an den Anfang des
RAMs kopiere (0x6000 -> 0x40000000) und das Mapping auf RAM umstelle.
Dies mache ich bevor der Bootloader die Applikation anspringt, der
Bootloader laeuft im Supervisor mode damit die Stackadressen in der
Applikation nachher erfolgreich gesetzt werden koennen.
Ich kann leider keinen der beiden Sourecodes posten aber falls ihr mir
noch Tipps geben koennt, was ich moeglicherweise vergessen habe, bitte
gerne, ich waere Euch sehr dankbar :-)
Gruss
Nik
Hallo Nik,
melde ich mich halt nochmal, vielleicht hilft es ja diese mal.
Wie ist der Sprung zu den Exception-Handlern gemacht. Eine
Branchanweisung alleine wird nicht funktionieren. Ist der Jump zu den
Handlern mit einem LDR-Befehl gemacht? Kopierst Du 0x40 Byte in den RAM?
Ich mache das z.B so:
Vectors: LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP @ Reserved Vector
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr: .word Reset_Handler
Undef_Addr: .word Undef_Handler
SWI_Addr: .word SWI_Handler
PAbt_Addr: .word PAbt_Handler
DAbt_Addr: .word DAbt_Handler
.word 0xB9206E28 @ Reserved Address
IRQ_Addr: .word IRQ_Handler
FIQ_Addr: .word FIQ_Handler
Gruß Microman
PS: Ist es jetzt doch nicht ein ein LPC2368 wie in den ersten Posting?
Hey Microman, danke dass du dich dem Problem nochmal annimst.
In dem anderen Thread habe ich erst am Montag geantwortet, da ich erst
dann wieder an die Hardware konnte. Leider bist du nicht angemeldet
sonst haette ich dir natuerlich eine PM geschickt :-)
Die 0x40 Bytes kopiere ich direkt bevor ich zur Applikation springe
1
dst_ptr = (U32 *)0x40000000;
2
src_ptr = (U32 *)0x6000;
3
4
for (j=0;j<(16);j++){dst_ptr[j] = src_ptr[j];}
Der Abschnitt im Startupcode der Applikation sieht bei mir aber etwas
anders aus, ich habe mich schon gefragt woher dort die Adressen denn
kommen sollen aber die betreffenden Konstanten nicht gefunden.
Der Code in dem Abschnitt ist unveraendert aus einem Projekt welches
nach 0x0000 gelinkt wurde, kann gut sein dass hier der Fehler liegt. Ich
muss allerdings auch gestehen, dass ich mit ARM-ASM nicht wirklich viel
am Hut habe; Inwiefern muesste ich hier etwas anpassen? (bzw: wie kommst
du auf die 0xB9206E28?)
1
Vectors LDR PC, Reset_Addr
2
LDR PC, Undef_Addr
3
LDR PC, SWI_Addr
4
LDR PC, PAbt_Addr
5
LDR PC, DAbt_Addr
6
NOP ; Reserved Vector
7
; LDR PC, IRQ_Addr
8
LDR PC, [PC, #-0x0120] ; Vector from VicVectAddr
9
LDR PC, FIQ_Addr
10
11
Reset_Addr DCD Reset_Handler
12
Undef_Addr DCD Undef_Handler
13
SWI_Addr DCD SWI_Handler
14
PAbt_Addr DCD PAbt_Handler
15
DAbt_Addr DCD DAbt_Handler
16
DCD 0 ; Reserved Address
17
IRQ_Addr DCD IRQ_Handler
18
FIQ_Addr DCD FIQ_Handler
LPC2366/68 ist je nach Hardwarerevision unterschiedlich, in der alten
Version wurde noch mit dem 66er gearbeitet, mit welchem ich im Moment
auch arbeite.
Gruss
Nik
Hallo Nik,
ich denke das Problem ist der Sprung zum VicVectAddr Register.
LDR PC, [PC, #-0x0120] ; Vector from VicVectAddr
Wenn das Programm auf 0x0 gelinkt ist und der PC auf auf der Zeile
steht, dann würde er den Inhalt von der Adresse 0x20-0x0120 = 0xFFFFFF00
( an dieser Stelle ist das VicVectAddr-Register in dem die Sprungadresse
der Interruptfunktion steht) in den PC laden und somit dahin springen.
Jetzt hast Du aber das Remapping eingeschaltet und der PC hat an dieser
Stelle einen Offset von 0x40000000 ( ist jetzt ja im RAM) und die
Berechnung und damit auch der Sprung, gehen vollkommen daneben. Eine
Lösung ist der Umweg über den IRQ_Handler, falls dieser denn richtig
implemetiert ist.
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP ; Reserved Vector
LDR PC, IRQ_Addr
; LDR PC, [PC, #-0x0120] ; Vector from VicVectAddr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
So sollten dann die IRQ auch mit Remapping funktionieren. Einfach mal
ausprobieren.
Gruß Microman
PS: Die 0xB9206E28 sind nur ein Platzhalter und ohne Bedeutung.
Achso so ist das, dankeschoen!
Ich habe dies soeben einmal ausprobiert, leider gibts immer noch
aehnliche Anzeichen, teilweise schmiert er sogar no deutlich vor dem
ersten Interrupt ab, dann aber an unterschiedlichen Stellen.
Ich vermute, dass es wohl auch noch was mit dem Stack zu tun hat. Dieser
kannn angeblich nur im Supervisor mode neu initilisiert werden, aber
dafuer
sorge ich ja, indem ich im Bootloader den Supervisor gar nicht erst
verlasse, die App wird also noch im Supervisor mode aufgerufen.
Alle Beispiele fuer Bootloader, die ich finde, sind leider ziemlich
unbrauchbar, da in der Applikation weder Interrupts noch gross etwas an
Ram verwendet wird.
Hast du noch Ideen, wie ich das ganze immerhin anstaendig Debuggen
koennte? Leider handelt es sich bei mir ja um ein zweiteilges Projekt,
der uVision Debugger ist also ziemlich ratlos nachdem ich den Appsprung
mache. Dort wuerde es aber erst so richtig interessant...
Gruss
Nik
Ich wollte es nun doch mit dem VicVect controller versuchen,
und habe daher die folgende Zeile(1) nach(2) modifiziert
(1)
LDR PC, [PC, #-0x0120] ; Vector from VicVectAddr
(2)
LDR PC, =0xFFFFFF00 ; Vector from VicVectAddr
Der Fehler bleibt bestehen, ich habe sogar noch ein neues Phaenomen;
printf spuckt mir nun teilweise den Inhalt innerhalb der
Anfuehrungszeichen aus, sprich ich schribe printf("Dies ist eine Zahl
%u", Zahl); dann kommt das auch genau so raus, ohne dass das %u ersetzt
wuerde.
Was koennte das denn sein?
Hallo Nik,
werde Dir noch was zum debuggen mit Bootloader schreiben, zumindest so
wie ich es umgesetzt habe, dauert aber noch bis zum WE. Poste doch noch
mal den Code den Du für das Remapping verwendest, werde den dann mal mit
dem von mir vergleichen.
Gruß Microman
(Startup: entweder mit oder ohne usermode Switch, selbes ergebnis!)
2
3
U32 *src_ptr;
4
U32 *dst_ptr;
5
U32 j;
6
void (*appjump)(void);
7
8
src_ptr = (U32 *)0x6000; //Exeptionvects in app
9
dst_ptr = (U32 *)0x40000000; //Ram
10
11
//Copy intvects to
12
for (j=0;j<8;j++)
13
{dst_ptr[j] = src_ptr[j];}
14
15
//Set mapping to RAM
16
MEMMAP = 0x02;
17
18
appjump = (void (*)(void))0x6000;
19
appjump();
Den Startupcode der Anwendung habe ich angehaengt, die Makros "RAM_MODE"
und "REMAP" sind gesetzt, es wird damit also dort auch nochmal MEMMAP
auf 2 gesetzt.
Zusaetzlich habe ich die Stelle um die Exceptionvektoren noch einmal
folgendermassen ueberarbeitet um dann doch zum VIC zu kommen (LDR geht
so wie ichs oben gepostet habe ja nicht, da nur relativ nur ueber 12bit
Adressraum gesprungen werden kann)
1
Vectors LDR PC, Reset_Addr
2
LDR PC, Undef_Addr
3
LDR PC, SWI_Addr
4
LDR PC, PAbt_Addr
5
LDR PC, DAbt_Addr
6
NOP ; Reserved Vector
7
LDR PC, IRQ_Addr
8
; LDR PC, [PC, #-0x0120] ; Vector from VicVectAddr
Hallo Nik,
mir ist bei deinem Code aufgefallen, daß Du nur 32 Byte kopierst. Du
mußt aber 64 Byte kopieren. Erst die 32 Byte Exception-Vectoren und dann
noch die 32 Byte der Sprungadressen. Deshalb werden auch 0x40 Byte
"ge-remapped", damit ein Sprung überall in den Speicherraum möglich ist.
Bitte ändere den Code doch wie folgt, und teste das Ergebnis.
//Copy intvects to
for (j=0;j<16;j++)
{dst_ptr[j] = src_ptr[j];}
Beim Debuggen habe ich ein Label mit folgendem Code in die Firmware
eingebaut. Dieses Label wird direkt nach dem Flashen der Firmware, bei
Dir auf 0x6000, angesprungen und augeführt, erst dann wird zur
Reset-Handler gesprungen. Die Firmware ganz Du ganz normal debuggen,
obwohl auf 0x0 noch ein Bootloader schlummert, der aber gar nicht
aufgerufen wird beim Debuggen. Ausserdem stört Dich dieser Code nicht,
denn die Firmware kann diesen Code gar nicht erreichen. Teste das doch
mal aus.
.global Startup_Label
Startup_Label:
.extern sys_remap_sectors_startup
ldr SP, =Stack_Top
@ temporary stack at Stack_Top
LDR R0, =sys_remap_sectors_startup
MOV LR, PC
BX R0
LDR R0, =Reset_Handler
BX R0
.end
Gruß Microman
PS: Denke bitte daran, den Speicher von 0x40000000 bis 0x40000040 bei
deiner Firmware als Reserved zu markieren; denn hier liegen ja deine
"ge-remappten" Vectoren.
Hallo Microman,
danke dass du mich darauf hingewiesen hast-ich habe ganz uebersehen,
dass ich nicht mehr 64 Bytes kopiere. Das habe ich im Zuge all der Tipps
und Tricks, die im WWW aufstoebern konnte einmal ausprobiert und
vergessen zurueck zu korrigieren. Leider bringt allerdings dies auch
keine Aenderung.
Oben habe ich ja gepostet, inwiefern ich den VICvect nun anspringe,
hier ein Schnippsel daraus:
1
IRQ_Handler LDR R5, Vic_Addr
2
LDR PC, [R5]
Nun, damit startet meine Firmware noch, allerdings mit den selben
Fehlern wie schon immer.
Aendere ich dies nun korrekterweise auf folgendes:
1
IRQ_Handler LDR R5, Vic_Addr
2
MOV PC, [R5]
dann startet gar nichts mehr. Weshalb? - Register in ein anderes
Register geht mit LDR ja im Grunde nicht, MOV muesste dazu ja korrekt
sein?
Ich denke der Fehler liegt schon um die Zeilen mit dem
Vektorinterruptcontroller, aber mir gehen so langsam die Ideen aus, wie
ich den wert aus 0xFFFFFF00 bei 0x6000 denn korrekt auslesen und
anspringen koennte.
Das mit dem Debuggen werde ich gerne ausprobieren, danke!
Der 0x4000 0000 - 0x4000 0040 indem ich dem Keil mitteile er solle IRAM1
erst ab 0x40000040 verwenden.
Gruss
Nik
Danke fuer deine Hilfe, ich habs nun endlich hingekriegt!
Was fuer mich voellig unverstaendlich ist, ist dass es fuer den vicVect
dennoch folgende Zeile tut.
LDR PC, [PC, #-0x0120]
Wie du mir ja dargestellt hast und mir nun auch einleuchtet, duerfte er
diesen Bereich gar nicht erreichen, es funktioniert so aber auch von
0x6000 aus.
Der Fehler lag bei den CCLK Einstellungen fuer die IAP Funktionen; Der
Code wurde richtig ins Flash geladen, dafuer zickte er bei der
Ausfuehrung dessen dann so richtig rum. (Oben genannte Phaenomene)
Nochmals Dankeschoen fuer deine Muehe :-)
Gruss
Nik