Forum: Mikrocontroller und Digitale Elektronik Interrupt Problem sam7


von Gast (Gast)


Lesenswert?

Hallo letzte Rettung,

ich will ueber die I2C bzw. das TWI Daten heraussenden. Allerdings hab 
ich Probleme beim aufrufen der portRESTORE_CONTEXT() und 
portSAVE_CONTEXT() macros bei freertos und gcc... Ich erhalte jedes mal 
die Fehlermeldung

"invalid literal constant: pool needs to be closer". Komischerweise 
koennen die Funktionen an anderen Stellen ohne weiteres aufgerufen 
werden.

Es handelt sich hierbei um einen Atmel AT91 Sam7x256 und die Yagarto 
Toolchain... :/

1
#define portRESTORE_CONTEXT()                      \
2
{                                    \
3
extern volatile void * volatile pxCurrentTCB;              \
4
extern volatile unsigned portLONG ulCriticalNesting;          \
5
                                    \
6
  /* Set the LR to the task stack. */                  \
7
  asm volatile (                            \
8
  "LDR    R0, =pxCurrentTCB                \n\t"  \
9
  "LDR    R0, [R0]                    \n\t"  \
10
  "LDR    LR, [R0]                    \n\t"  \
11
                                    \
12
  /* The critical nesting depth is the first item on the stack. */  \
13
  /* Load it into the ulCriticalNesting variable. */          \
14
  "LDR    R0, =ulCriticalNesting              \n\t"  \
15
  "LDMFD  LR!, {R1}                      \n\t"  \
16
  "STR    R1, [R0]                    \n\t"  \
17
                                    \
18
  /* Get the SPSR from the stack. */                  \
19
  "LDMFD  LR!, {R0}                      \n\t"  \
20
  "MSR    SPSR, R0                    \n\t"  \
21
                                    \
22
  /* Restore all system mode registers for the task. */        \
23
  "LDMFD  LR, {R0-R14}^                    \n\t"  \
24
  "NOP                            \n\t"  \
25
                                    \
26
  /* Restore the return address. */                  \
27
  "LDR    LR, [LR, #+60]                  \n\t"  \
28
                                    \
29
  /* And return - correcting the offset in the LR to obtain the */  \
30
  /* correct address. */                        \
31
  "SUBS  PC, LR, #4                      \n\t"  \
32
  );                                  \
33
  ( void ) ulCriticalNesting;                      \
34
  ( void ) pxCurrentTCB;                        \
35
}
36
37
#define portSAVE_CONTEXT()                        \
38
{                                    \
39
extern volatile void * volatile pxCurrentTCB;              \
40
extern volatile unsigned portLONG ulCriticalNesting;          \
41
                                    \
42
  /* Push R0 as we are going to use the register. */          \
43
  asm volatile (                            \
44
  "STMDB  SP!, {R0}                      \n\t"  \
45
                                    \
46
  /* Set R0 to point to the task stack pointer. */          \
47
  "STMDB  SP,{SP}^                      \n\t"  \
48
  "NOP                            \n\t"  \
49
  "SUB  SP, SP, #4                      \n\t"  \
50
  "LDMIA  SP!,{R0}                      \n\t"  \
51
                                    \
52
  /* Push the return address onto the stack. */            \
53
  "STMDB  R0!, {LR}                      \n\t"  \
54
                                    \
55
  /* Now we have saved LR we can use it instead of R0. */        \
56
  "MOV  LR, R0                        \n\t"  \
57
                                    \
58
  /* Pop R0 so we can save it onto the system mode stack. */      \
59
  "LDMIA  SP!, {R0}                      \n\t"  \
60
                                    \
61
  /* Push all the system mode registers onto the task stack. */    \
62
  "STMDB  LR,{R0-LR}^                      \n\t"  \
63
  "NOP                            \n\t"  \
64
  "SUB  LR, LR, #60                      \n\t"  \
65
                                    \
66
  /* Push the SPSR onto the task stack. */              \
67
  "MRS  R0, SPSR                      \n\t"  \
68
  "STMDB  LR!, {R0}                      \n\t"  \
69
                                    \
70
  "LDR  R0, =ulCriticalNesting                \n\t"  \
71
  "LDR  R0, [R0]                      \n\t"  \
72
  "STMDB  LR!, {R0}                      \n\t"  \
73
                                    \
74
  /* Store the new top of stack for the task. */            \
75
  "LDR  R0, =pxCurrentTCB                  \n\t"  \
76
  "LDR  R0, [R0]                      \n\t"  \
77
  "STR  LR, [R0]                      \n\t"  \
78
  );                                  \
79
  ( void ) ulCriticalNesting;                      \
80
  ( void ) pxCurrentTCB;                        \
81
}

von Microman (Gast)


Lesenswert?

Hallo Gast,

hatte auch das Problem, schau doch mal hier nach:

Beitrag "ARM GCC literal pool needs to be closer"

Gruß Microman

von Gast (Gast)


Lesenswert?

Hab ich gesehen und eingefuegt, allerdings kommt dann diese 
fehlermeldung:
1
error: no memory region specified for loadable section '.text.i2c_handler'

:(

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Gast wrote:
> Hab ich gesehen und eingefuegt, allerdings kommt dann diese
> fehlermeldung:
>
>
1
error: no memory region specified for loadable section
2
> '.text.i2c_handler'
>
> :(

Das Linker-Script muss für -ffunction-section angepasst werden. Vgl. 
default linker-script ($(toolchainprefix)-ld --verbose) im Bereich um 
.text.*

von Gast (Gast)


Lesenswert?

Entschuldigung, aber geht das vielleicht etwas genauer? bin neu in der 
programmierung von Arms und kenn mich nicht wirklich aus.

Mein LinkerScript sieht derzeit so aus:
1
MEMORY 
2
{
3
  flash  : ORIGIN = 0x00400000, LENGTH = 256K
4
  ram    : ORIGIN = 0x00200000, LENGTH = 64K
5
}
6
7
__stack_end__ = 0x00200000 + 64K - 4;
8
9
SECTIONS 
10
{
11
  . = 0;
12
  startup : { *(.startup)} >flash
13
  
14
  prog : 
15
  {
16
    *(.rodata)
17
    *(.rodata*)
18
    *(.glue_7)
19
    *(.glue_7t) 
20
  } >flash
21
  
22
  __end_of_text__ = .;
23
24
  .data : 
25
  {
26
    __data_beg__ = .;
27
    __data_beg_src__ = __end_of_text__;
28
    *(.data)
29
    __data_end__ = .;
30
  } >ram AT>flash
31
32
  .bss : 
33
  {
34
    __bss_beg__ = .;
35
    *(.bss)
36
  } >ram
37
  
38
  
39
40
41
  /* Align here to ensure that the .bss section occupies space up to
42
  _end.  Align after .bss to ensure correct alignment even if the
43
  .bss section disappears because there are no input sections.  */
44
  . = ALIGN(32 / 8);
45
}
46
  . = ALIGN(32 / 8);
47
  _end = .;
48
  _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
49
  PROVIDE (end = .);

von Gast (Gast)


Lesenswert?

ha...problem geloest, im prinzip ganz einfach:

die quellcode datei mit dem interrupt sollte so klein/kurz wie moeglich 
gehalten werden. wenn sie zu groß ist, kommt es zu diesem problem...

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.