Hallo,
ich habe den Stick inzwischen erfolgreich im Betrieb und bin fast
glücklick.
Bisher habe ich allerdings das Vektor-Problem umgangen indem ich vom
Bootblock (Flash Bank 1, Adresse 0x0) direkt auf den Applikationsflash
(Flash Bank 0, Adresse 0x80000) branche.
Jetzt versuche ich gerade stattdessen eine Vektortabelle im Ram zu
benutzen.
Auf embedded.com gibts einen Artikel - allerdings schmeckt mir gar nicht
wie hier die Tabelle angelegt wird:
1 | void init_mc(void)
|
2 | {
|
3 | /* RAM Start */
|
4 | static unsigned long const LDR_PC_PC = 0xE59FF000U;
|
5 |
|
6 | /* LDR table */
|
7 | *(unsigned long volatile *)(&__data_start__ + 0x00) = (LDR_PC_PC | 0x18); /* Reset Handler */
|
8 | *(unsigned long volatile *)(&__data_start__ + 0x04) = (LDR_PC_PC | 0x18);
|
9 | *(unsigned long volatile *)(&__data_start__ + 0x08) = (LDR_PC_PC | 0x18);
|
10 | *(unsigned long volatile *)(&__data_start__ + 0x0C) = (LDR_PC_PC | 0x18);
|
11 | *(unsigned long volatile *)(&__data_start__ + 0x10) = (LDR_PC_PC | 0x18);
|
12 | *(unsigned long volatile *)(&__data_start__ + 0x14) = (LDR_PC_PC | 0x18);
|
13 | *(unsigned long volatile *)(&__data_start__ + 0x18) = (LDR_PC_PC | 0x18);
|
14 |
|
15 | /* Address table */
|
16 | *(unsigned long volatile *)(&__data_start__ + 0x20) = _reset; /* Should never be reached because the reset vector is handled in the flash vector table */
|
17 | *(unsigned long volatile *)(&__data_start__ + 0x24) = Undefined_Handler;
|
18 | *(unsigned long volatile *)(&__data_start__ + 0x28) = Undefined_Handler;
|
19 | *(unsigned long volatile *)(&__data_start__ + 0x2C) = Undefined_Handler;
|
20 | *(unsigned long volatile *)(&__data_start__ + 0x30) = Undefined_Handler;
|
21 | *(unsigned long volatile *)(&__data_start__ + 0x34) = Undefined_Handler;
|
22 | *(unsigned long volatile *)(&__data_start__ + 0x38) = Undefined_Handler;
|
23 | };
|
Mir gefällt das jedoch nicht so richtig... - z.B. LDR_PC_PC...
Wie habt ihr eure Vektortabellen angelegt?
Mein gewünschter Ansatz wäre wie folgt:
Syntaktisch (sprich in Assembler) die Vektortabelle im RAM gleich wie
die erste Vektortabelle im Flash (Adresse 0x0) anzulegen und dann beim
Ausführen des Reset-Handlers einfach 1:1 ins RAM kopieren.
Meine Vektortabelle an 0x0 sieht wie folgt aus:
1 | #*************************************************************************
|
2 | # Exception Vectors FLASH
|
3 | #*************************************************************************
|
4 |
|
5 | .text
|
6 | .section .vectors_flash, "ax"
|
7 |
|
8 | .arm
|
9 | .code 32
|
10 |
|
11 | .global Reset_Vec
|
12 | .global _start
|
13 | .func _start
|
14 |
|
15 | _start:
|
16 |
|
17 | Reset_Vec: LDR PC, Reset_Addr /* 0x0000 */
|
18 | Undef_Vec: LDR PC, Undef_Addr /* 0x0004 */
|
19 | SWI_Vec: LDR PC, SWI_Addr /* 0x0008 */
|
20 | PAbt_Vec: LDR PC, PAbt_Addr /* 0x000C */
|
21 | DAbt_Vec: LDR PC, DAbt_Addr /* 0x0010 */
|
22 | NOP /* 0x0014 Reserved Vector */
|
23 | IRQ_Vec: LDR PC, IRQ_Addr /* 0x0018 IRC */
|
24 | #LDR PC, [PC, #-0xFF0] /* 0x001C wraps around address space to 0xFFFFFF030. Vector from VicVECAddr */
|
25 | FIQ_Vec: LDR PC, FIQ_Addr /* 0x0020 FIQ has no VIC vector slot! */
|
26 |
|
27 | /* Function table */
|
28 | Reset_Addr: .word _reset /* CPU reset vector and entry point */
|
29 |
|
30 | # Undef_Addr: .word UndefinedHandler
|
31 | # SWI_Addr: .word SWIHandler
|
32 | # PAbt_Addr: .word PrefetchHandler
|
33 | # DAbt_Addr: .word AbortHandler
|
34 | # .word 0 /* Reserved Address */
|
35 | # IRQ_Addr: .word IRQHandler
|
36 | # FIQ_Addr: .word FIQHandler /* Does not get used due to "LDR PC, [PC, #-0xFF0]" above */
|
Hat jemand einen konkreten Vorschlag wie diese zweite Tabelle in Code
zu realisieren ist?
Danke!!
Gruß,
mydani