Hallo, ich habe ein Verständnisproblem beim ARM9. Ich habe eine Firmware die auf einem persistenten Speichermedium im Gerät liegt. Beim Gerätestart lade ich die SW vom Speichermedium ins externe SDRAM und starte diese dort. Das funktioniert soweit. Mein Problem ist, dass die Interrupts nicht bedient werden. Ich dachte ich linke die Vektoren in den Startbereich der bin-Datei und kopiere die Vektoren beim Programmstart vom SDRAM (LowLevelInit) in den internen RAM. Ich hoffe mein Anliegen ist verständlich. Till.
Hallo, habe so ein ähnliches Problem bei einem ARM7 (AT91SAM7A2). Internes RAM 16K, externes RAM 2M (Olimex Board). Nach einen Remap kopiere ich auch die Vectoren (allerdings vom Flash) ins interne RAM, ich muß aber auch die .data Section ins interne RAM legen (ich hätte sie gerne im externen RAM), da sonst die Section mit den Vectoren immer aus dem Binary entfernt wird. Ich glaube das war beim Commando objcpy. Also mal die generierten Binaries genau ansehen. lg maik
Hallo Maik, wie hast du denn die Linker-Einstellungen gemacht? Also ich habe bei meinem IAR wie folgt gelinkt:
1 | define region VEC_region = mem:[from 0x20000000 to 0x200000FF]; |
2 | define region APP_region = mem:[from 0x20000100 to 0x200FFFFF]; |
3 | define region RAM_region = mem:[from 0x20100000 to 0x201FFFFF]; |
4 | |
5 | place in VEC_region { |
6 | section .intvec |
7 | };
|
Das daraus resultierende binary liegt dann auf dem persistenten Speicher. Beim Gerätestart kopiere ich das gesamte binary (also ab 0x20000000) in den SDRAM und starte die Anwendung an der Adresse 0x20000000. In der LowelLevelInit-Routine kopiere ich dann die Vektoren an die Adresse 0x00300000 (also interner RAM). Klingt das vom Grundprinzip sinnig? Danke
Hallo, Linker Script für GCC:
1 | OUTPUT_FORMAT("elf32-littlearm") |
2 | OUTPUT_ARCH(arm) |
3 | ENTRY(reset_handler) |
4 | |
5 | cram_size = 16K; |
6 | sram_size = 2M; |
7 | stack_size = 1K; |
8 | |
9 | MEMORY |
10 | { |
11 | flash(rx) : o = 0x40000000, l = 1M |
12 | cram(rwx) : o = 0x00000000, l = 16K |
13 | sram(rwx) : o = 0x48000000, l = 2M |
14 | } |
15 | |
16 | SECTIONS |
17 | { |
18 | .text : |
19 | { |
20 | code_start = .; |
21 | text_start = .; |
22 | KEEP(*(.reset)) |
23 | KEEP(*(.unref)) |
24 | *(.text) |
25 | *(.text*) |
26 | text_end = .; |
27 | } > flash |
28 | |
29 | .rodata : |
30 | { |
31 | rodata_start = . ; |
32 | *(.rodata) |
33 | *(.rodata*) |
34 | . = ALIGN(4); |
35 | rodata_end = . ; |
36 | code_end = . ; |
37 | } > flash |
38 | |
39 | .data : AT (ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata)) |
40 | { |
41 | cram_start = .; |
42 | data_start = .; |
43 | KEEP(*(.vectors)) |
44 | *(.data) |
45 | *(.data*) |
46 | data_end = .; |
47 | } > cram |
48 | |
49 | .stack (NOLOAD): |
50 | { |
51 | . = cram_start + cram_size - stack_size - 0; |
52 | stack_start = . ; |
53 | *(.stack) |
54 | . = cram_start + cram_size - 0; |
55 | stack_end = . ; |
56 | cram_end = . ; |
57 | } > cram |
58 | |
59 | .ramc : AT (ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.data)) |
60 | { |
61 | sram_start = .; |
62 | ramc_start = .; |
63 | *(.ramcode) |
64 | ramc_end = .; |
65 | } > sram |
66 | |
67 | .bss (NOLOAD) : |
68 | { |
69 | . = ALIGN(4); |
70 | bss_start = .; |
71 | *(.bss) |
72 | *(COMMON) |
73 | bss_end = .; |
74 | } > sram |
75 | |
76 | .heap (NOLOAD): |
77 | { |
78 | . = ALIGN(4); |
79 | heap_start = . ; |
80 | *(.heap) |
81 | . = sram_start + sram_size - 0; |
82 | heap_end = .; |
83 | sram_end = . ; |
84 | } > sram |
85 | |
86 | } |
soweit ich weiß sollten die Vektoren an der Addresse 0 liegen, bei mir nach einen Remap das interne RAM, vor dem Remap liegt dort das externe Flash (damit überhaupt Code ausgeführt werden kann). lg maik
Hallo, der ARM9 hat auch eine MMU, vielleicht hängt es auch damit zusammen, aber da kenn ich mich nicht aus. http://forums.arm.com/index.php?/topic/14376-relocating-interrupt-vector-table/ lg maik
Hallo Till, noch ein kleiner Hinweis falls das Problem noch besteht, du linkst deine Vektoren (das ist ja ausführbarer Code) an die Adresse 0x20000000 to 0x200000FF und kopierst sie dan an eine andere Adresse 0x00300000, dann müssen deine Vektoren unbedingt positions unabhängiger Code sein. Viellechts besser sie direkt an die richtige Adresse zu linken. lg
Hallo Maik, irgendwie habe ich jetzt noch ein Verständnisproblem. Folgende Situation: 1.) Ich habe die Vektoren der Applikation auf 0x20000000 gelinkt und kopiere diese jetzt erst mal nicht in den internen RAM. Also das komplette binaray (intvec + code) in den externen SDRAM kopiert und über einen Jump auf 0x20000000 die Applikation im SDRAM gestartet. 2.) In der Applikation (wird im SDRAM ausgeführt) habe ich mir jetzt rudimentäre Funktionen mit Interrupts gebaut, um zu checken, dass die Interrupts (PIT) aktiviert sind und ausgelöst werden. Die kommen. 3.) Komischerweise habe ich jetzt das Problem, dass bei weiteren Initialisierungsschritten mir der Stackpointer krachen geht und mir das Programm abstürzt (harter Reset). Jetzt meine Frage - wenn ich von der Loaderanwendung den Jump auf die SDRAM-Applikation mache, muss ich dort den CSTACK, IRQ-STACK, usw. noch einmal manuell einrichten? Für mich ist diese Thematik Neuland, so dass ich hier noch Wissenslücken habe. Danke Till
Hallo Till, ich vermute mal, wenn das sonst der loader macht? ein CStack sollte initialisiert sein (sp auf einen reservierten bereich zeigen lassen) bevor du in die C funktionen springst. solange du in die exceptions eh nicht reinkommst sind die stacks dafür auch nicht notwendig :) lg
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.