Forum: Mikrocontroller und Digitale Elektronik ARM9 mit SDRAM


von Till (Gast)


Lesenswert?

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.

von maik (Gast)


Lesenswert?

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

von Till (Gast)


Lesenswert?

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

von maik (Gast)


Lesenswert?

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

von maik (Gast)


Lesenswert?

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

von Till (Gast)


Lesenswert?

Hallo Maik,

danke für deine Hilfe. Werde mal in Ruhe schauen.

Till

von maik (Gast)


Lesenswert?

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

von Till (Gast)


Lesenswert?

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

von maik (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.