Forum: Mikrocontroller und Digitale Elektronik LPC1788 - startup / .ld-script


von Tobias Neumann (Gast)


Lesenswert?

Hallo,

ich unternehme gerade meine ersten Gehversuche mit dem LPC1788 und 
nachdem nun die LED blinkt und die Dummy-Text UART Ausgabe 
funktionieren, habe ich paar andere Probleme:

Problem 1) Gibt es ein Tool, welches mir die Startup-Variablen "bequem" 
ausrechnet ? In der system_LPC177x_8x.c steht etwas von "Use 
Configuration Wizard in Context Menu" - aber wo ?!!!

Ich würde gerne die CPU mit 25Mhz ext. Quarz betreiben und diese mit 
100Mhz intern betreiben. Momentan verwende ich folgende Config, 
allerdings wird dort der interne 12Mhz Quarz verwendet.

#define CLOCK_SETUP           1
#define SCS_Val               0x00000031 // 0x00000021
#define CLKSRCSEL_Val         0x00000000 // Use Internal Clk = 0, 
External = 1

#define PLL0_SETUP            1
#define PLL0CFG_Val           0x0000000C

#define PLL1_SETUP            0
#define PLL1CFG_Val           0x00000023

#define CCLKSEL_Val           0x00000101
#define USBCLKSEL_Val         0x00000201
#define EMCCLKSEL_Val         0x00000001
#define PCLKSEL_Val           0x00000005
#define PCONP_Val             0x0000A28E // 0x042887DE
#define CLKOUTCFG_Val         0x00000000 // 0x00000100



Problem 2)
Woher kriege ich das ld-script ? Die CodeRed Umgebung erzeugt zwar ein 
automatisches LD-Skript, aber ich habe Probleme mit 64bit Integer. Dort 
stürzt die CPU ab. Nach div. Recherchen habe ich nun rausgefunden, dass 
im LD-Skript etwas angepasst werden muss. Aber was ?!!

Gibt es ein Tool, der mir das ld-script erzeugt ? (Ist die Datei, die 
mit -T "xy" im Makefile angegeben ist).

Problem 3)
Beim benutzen von sprintf erhalte ich folgende Meldung:

/usr/local/lpcxpresso_4.2.0_224/lpcxpresso/tools/bin/../lib/gcc/arm-none 
-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb/libc.a(lib_a-sbrkr.o): 
In function `_sbrk_r':
sbrkr.c:(.text+0xc): undefined reference to `_sbrk'

Google-Suche ergibt div. Lösungen, einmal wird eine leere _sbrk 
definiert, dann gibt es sowas usw.

caddr_t _sbrk_r (struct _reent *r, int incr)
{
  ( void ) r;
  ( void ) incr;

  return 0;
}

Ich vermute, sbrk pusht Daten auf dem Stack, vondaher denke ich, dass 
eine leere sbrk nicht die Lösung des Problemes sein kann.

Vielen Dank schonmal im vorraus!

von Tobias Neumann (Gast)


Lesenswert?

achja, die syscalls.c (wo _sbrk definiert sein soll) finde ich in der 
gesamten CodeRed-Umgebung nicht...

von Tobias Neumann (Gast)


Lesenswert?

Die Frage nach einem Wizard hat sich erledigt. GGf. sollte jemand die 
Antwort in die FAQ aufnehmen, das Tool ist Weltklasse.

http://helmpcb.com/software/cmsis-configuration-wizard

von Roland H. (batchman)


Lesenswert?

Tobias Neumann schrieb:
> Die CodeRed Umgebung erzeugt zwar ein
> automatisches LD-Skript, aber ich habe Probleme mit 64bit Integer. Dort
> stürzt die CPU ab. Nach div. Recherchen habe ich nun rausgefunden, dass
> im LD-Skript etwas angepasst werden muss. Aber was ?!!

Dann poste bitte das erzeugte ld-Script, und bitte auch die Quellen, die 
besagen, dass man für 64-Bit-Integer das ld-script verändern soll.

Wofür benötigst Du 64-Bit-Integer?

Tobias Neumann schrieb:
> Beim benutzen von sprintf erhalte ich folgende Meldung:

Ob es Dir hilft, weiß ich nicht, aber ich hatte vor einiger Zeit 
ähnliche Probleme, vor allem beim "printf retarget". Nach einigen 
Debug-Sessions umd Herumsuchen habe ich mir die benötigten Funktionen 
selbst geschrieben.

Selbst wenn Du das zum Laufen kriegst, bleibt die Frage, ob dieses 
sprintf mit 64-Bit-Integer umgehen kann ...

von Tobias Neumann (Gast)


Lesenswert?

Hi,

die 64bit integer werden von lpc177x_8x_uart.c für uart_set_divisors 
verwendet (CMSIS v2 - . Ich habe jetzt die uart_set_divisors aus einer 
älteren CMSIS übernommen, wo uint32 verwendet wird und es geht.

Hier der Link zur CMSIS mit 64bit uints:
http://ics.nxp.com/support/documents/microcontrollers/zip/lpc177x.lpc178x.cmsis.driver.library.zip

Ich weiss leider nicht mehr, in welchem Kontext ich den Beitrag gefunden 
habe. Dort stand, dass der Eintrag .ARM.exidx modifiziert werden sollte.
- Kannst du bei dir 64bit operationen durchführen ?

unsigned char i;
uint64_t a;

for (i=0;i<5;i++) {
  a = i*10;
  delay (a);
}

Sobald ich 64bit einsetze, steigt der prozessor nach der Multiplikation 
aus.
Ändere ich die Datentypen auf uint32_t ab, ist alles in Ordnung.

von Jojo S. (Gast)


Lesenswert?

um die PLL Parameter zu berechnen gibt es auch ein Excel Sheet:
http://ics.nxp.com/support/documents/microcontrollers/xls/lpc17xx.pll.calculator.xls

zu dem _sbrk wirst du in der CodeRed Hilfe fündig:
http://support.code-red-tech.com/CodeRedWiki/UndefinedReference?highlight=%28sbrk%29

Das 64Bit Problem dürfte auch eher ein Lib-Problem als ein Linkerscript 
Problem sein. Um in der CodeRed Umgebung andere Libs zu wählen gibt es 
im 'Quicks' Fenster und 'Quick Settings' eine Auswahl für die Lib.

von juergen (Gast)


Lesenswert?

Ich denke es ist besser, für printf und Kollegen schreibt man sich was 
kleines selber oder nimmt eine der vielen kleinen Implementierungen. 
Wenn es nicht dringend nötig ist, würde ich auf die syscall.c - 
Geschichten verzichten. Damit ist es auch wesentlich leichter mal den 
Compiler zu wechseln.

von Tobias Neumann (Gast)


Lesenswert?

@jojo: danke, das Compile-Problem ist mittlerweile gelöst, dort hat eine 
lib gefehlt ( libcr_newlib_nohost.a) und es gibt keine Probleme mehr mit 
sbrk.

Allerdings habe ich ein neues Problem, dass der wieder abschmiert, wenn 
ich ein sprintf (variable, "...%d",123); ausführe.

Ich denke, das Problem ist, dass der die Daten auf dem Stack pusht, aber 
wie reserviere ich Platz auf dem Stack ? Meiner Meinung nach ist es doch 
hiermit abgehandelt ?! (100 Bytes)

Gibt eigentlich eine Möglichkeit, das ldscript automatisch zu generieren 
? (abgesehn von codered). Ich erinnere mich noch an die avr-zeiten, wo 
ich noch nicht mal wusste, was ein ldscript ist...

"
  PROVIDE(_vStackTop = __top_RamLoc64 - 104);
"

Anbei mein ldscript -

ENTRY(ResetISR)

SECTIONS
{

  /* MAIN TEXT SECTION */
  .text : ALIGN(4)
  {
    FILL(0xff)
    KEEP(*(.isr_vector))

    /* Global Section Table */
    . = ALIGN(4) ;
    __section_table_start = .;
    __data_section_table = .;
    LONG(LOADADDR(.data));
    LONG(    ADDR(.data)) ;
    LONG(  SIZEOF(.data));
    LONG(LOADADDR(.data_RAM2));
    LONG(    ADDR(.data_RAM2)) ;
    LONG(  SIZEOF(.data_RAM2));
    LONG(LOADADDR(.data_RAM3));
    LONG(    ADDR(.data_RAM3)) ;
    LONG(  SIZEOF(.data_RAM3));
    LONG(LOADADDR(.data_RAM4));
    LONG(    ADDR(.data_RAM4)) ;
    LONG(  SIZEOF(.data_RAM4));
    __data_section_table_end = .;
    __bss_section_table = .;
    LONG(    ADDR(.bss));
    LONG(  SIZEOF(.bss));
    LONG(    ADDR(.bss_RAM2));
    LONG(  SIZEOF(.bss_RAM2));
    LONG(    ADDR(.bss_RAM3));
    LONG(  SIZEOF(.bss_RAM3));
    LONG(    ADDR(.bss_RAM4));
    LONG(  SIZEOF(.bss_RAM4));
    __bss_section_table_end = .;
    __section_table_end = . ;
    /* End of Global Section Table */


    *(.after_vectors*)

    /* Code Read Protect data */
    . = 0x000002FC ;
    PROVIDE(_CRP_WORD_START_ = .) ;
    KEEP(*(.crp))
    PROVIDE(_CRP_WORD_END_ = .) ;
    ASSERT(!(_CRP_WORD_START_ == _CRP_WORD_END_), "Linker CRP 
Enabled, but no CRP_WORD provided within application");
    /* End of Code Read Protect */

    *(.text*)
    *(.rodata .rodata.*)
    . = ALIGN(4);

  } > MFlash512

  /*
   * for exception handling/unwind - some Newlib functions (in common
   * with C++ and STDC++) use this.
   */
  .ARM.extab : ALIGN(4)
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } > MFlash512
  __exidx_start = .;

  .ARM.exidx : ALIGN(4)
  {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  } > MFlash512
  __exidx_end = .;

  _etext = .;


  .data_RAM2 : ALIGN(4)
  {
     FILL(0xff)
    *(.data.$RAM2*)
    *(.data.$RamAHB8_B0A*)
     . = ALIGN(4) ;
  } > RamAHB8_B0A AT>MFlash512

  .data_RAM3 : ALIGN(4)
  {
     FILL(0xff)
    *(.data.$RAM3*)
    *(.data.$RamAHB8_B0B*)
     . = ALIGN(4) ;
  } > RamAHB8_B0B AT>MFlash512

  .data_RAM4 : ALIGN(4)
  {
     FILL(0xff)
    *(.data.$RAM4*)
    *(.data.$RamAHB16_B1*)
     . = ALIGN(4) ;
  } > RamAHB16_B1 AT>MFlash512

  /* MAIN DATA SECTION */

  .uninit_RESERVED : ALIGN(4)
  {
    KEEP(*(.bss.$RESERVED*))
  } > RamLoc64

  .data : ALIGN(4)
  {
    FILL(0xff)
    _data = .;
    *(vtable)
    *(.data*)
    . = ALIGN(4) ;
    _edata = .;
  } > RamLoc64 AT>MFlash512


  .bss_RAM2 : ALIGN(4)
  {
    *(.bss.$RAM2*)
    *(.bss.$RamAHB8_B0A*)
     . = ALIGN(4) ;
  } > RamAHB8_B0A

  .bss_RAM3 : ALIGN(4)
  {
    *(.bss.$RAM3*)
    *(.bss.$RamAHB8_B0B*)
     . = ALIGN(4) ;
  } > RamAHB8_B0B

  .bss_RAM4 : ALIGN(4)
  {
    *(.bss.$RAM4*)
    *(.bss.$RamAHB16_B1*)
     . = ALIGN(4) ;
  } > RamAHB16_B1

  /* MAIN BSS SECTION */
  .bss : ALIGN(4)
  {
    _bss = .;
    *(.bss*)
    *(COMMON)
    . = ALIGN(4) ;
    _ebss = .;
    PROVIDE(end = .);
  } > RamLoc64

  PROVIDE(_pvHeapStart = .);
  PROVIDE(_vStackTop = __top_RamLoc64 - 104);
}

von Jojo S. (Gast)


Lesenswert?

die 104 Bytes abzuziehen dürfte unnötig sein, der Stack wächst doch nach 
unten. In den CR .ld ist der Stack auch als __top - 0 definiert.
Gibt es da noch includes wo die absoluten adressen der Speicherbereiche 
definiert sind? Das fehlt wenn ich das mit den CR .ld vergleiche.

von Tobias Neumann (Gast)


Lesenswert?

nee, ist alles. könntest du mir bitte deine ldscript mal posten ?

von Jojo S. (Gast)


Angehängte Dateien:

Lesenswert?

ist aus einem Beispiel für den LPC1768 bzw. LPC1769.

von Tobias Neumann (Gast)


Angehängte Dateien:

Lesenswert?

nagut, kann ich so nicht verwenden. ich hab die datei übrigens doch 
gefunden, wird auch miteingebunden.

ich weiss langsam echt nicht mehr weiter. habe jetzt auch mal das 
gesamte projekt hier mal angehängt, ich verstehe nicht, wo der fehler 
ist.

das komische ist auch, dass wenn ich die sprintf-routine einbinde, der 
code plötzlich von 4kb -> 30kb aufgebläht wird.

von Jojo S. (Gast)


Lesenswert?


von Jojo S. (Gast)


Lesenswert?

vor dem sprintf() ist noch ein while(1), damit dürfte dein Programm 
garnicht zum sprintf kommen (wenn du nicht mit dem Debugger nachhilfst), 
das meinst du hoffentlich nicht mit 'abschmieren' ?
Und das printf den Code stark aufbläht ist richtig, es gibt bei den CR 
Beispielen auch einen schlanken Ersatz. Aber bei 512k Flash sollten die 
26kB doch nicht wehtun.

von Jojo S. (Gast)


Lesenswert?

nochmal wg. 64 Bit printf:
1
    char s[40];
2
    uint64_t ull = 123456789012ULL;
3
4
    sprintf(s, "ulonglong: %llu \n", ull);

in "stdint.h" stehen die format specifier, %lli, %lld und %llx gibts 
auch noch. Auch das printf() mit der Semihost-Lib funktioniert mit den 
long longs.
Compiliert mit der NXP CodeRed, läuft auf dem LPC1769.

von Roland H. (batchman)


Lesenswert?

Jojo S. schrieb:
> Compiliert mit der NXP CodeRed, läuft auf dem LPC1769.

Welcher GCC ist das? Mit welcher Optimierung?

Könntest Du bitte in Deiner Version eine Division einbauen und den Part 
posten, in welchem die Division aufgerufen wird?
1
ull /= 10

Bei mir erzeugt der "arm-none-eabi-gcc (Linaro GCC 4.5-2011.02-0) 4.5.2" 
mit -Os bei der uint64 Division ein "blx":
1
    1794:       f000 ebc8       blx     1f28 <__aeabi_uldivmod>

und dann landet er im "fault".

http://www.coocox.org/forum/topic.php?id=10
http://embdev.net/topic/201054
http://lists.denx.de/pipermail/u-boot/2011-December/112871.html

Tobias Neumann schrieb:
> Sobald ich 64bit einsetze, steigt der prozessor nach der Multiplikation
> aus.
> Ändere ich die Datentypen auf uint32_t ab, ist alles in Ordnung.

Das gleiche Bild. Auch hier die Frage, welcher GCC, welche Optimierung, 
Assembler listing?

Tobias Neumann schrieb:
> Hier der Link zur CMSIS mit 64bit uints:

War diese Teil der "Code Red Tool chain" oder wurde diese später 
installiert?

Tobias Neumann schrieb:
> Ich weiss leider nicht mehr, in welchem Kontext ich den Beitrag gefunden
> habe. Dort stand, dass der Eintrag .ARM.exidx modifiziert werden sollte.

War das einer der oben genannten Links?

von Jojo S. (Gast)


Lesenswert?

habe zwar jetzt nicht viel Zeit aber der erste Test ohne Probleme:
1
    uint32_t ul = 12345678UL;
2
    uint64_t ull = 123456789012ULL;
3
    long long ll = 123456789012LL;
4
5
    printf( "ulong    : %u\n", ul);
6
    printf( "ulonglong: %lld \n", ull);
7
    printf( "longlong: %lld \n", ll);
8
9
    ull /= 10;
10
    printf( "ulonglong/10: %lld \n", ull);
11
    ull /= 10;
12
    printf( "ulonglong/10: %lld \n", ull);
13
    ull /= 10;
14
    printf( "ulonglong/10: %lld \n", ull);
15
    ull /= 10;
16
    printf( "ulonglong/10: %lld \n", ull);
17
    ull /= 10;
18
    printf( "ulonglong/10: %lld \n", ull);
19
    ull /= 10;
20
    printf( "ulonglong/10: %lld \n", ull);
21
    ull /= 10;
22
    printf( "ulonglong/10: %lld \n", ull);

output wie erwartet:
ulong    : 12345678
ulonglong: 123456789012
longlong: 123456789012
ulonglong/10: 12345678901
ulonglong/10: 1234567890
ulonglong/10: 123456789
ulonglong/10: 12345678
ulonglong/10: 1234567
ulonglong/10: 123456
ulonglong/10: 12345


ASM:
00006df4: main+108   ldrd r2, r3, [r7, #72]  ; 0x48
00006df8: main+112   mov r0, r2
00006dfa: main+114   mov r1, r3
00006dfc: main+116   mov.w r2, #10
00006e00: main+120   mov.w r3, #0
00006e04: main+124   bl 0x10280 <__aeabi_uldivmod>
00006e08: main+128   mov r2, r0
00006e0a: main+130   mov r3, r1
00006e0c: main+132   strd r2, r3, [r7, #72]  ; 0x48
236                    printf( "ulonglong/10: %lld \n", ull);
00006e10: main+136   movw r3, #11124 ; 0x2b74
00006e14: main+140   movt r3, #1
00006e18: main+144   mov r0, r3
00006e1a: main+146   ldrd r2, r3, [r7, #72]  ; 0x48
00006e1e: main+150   bl 0xde70 <printf>
237                    ull /= 10;
00006e22: main+154   ldrd r2, r3, [r7, #72]  ; 0x48
00006e26: main+158   mov r0, r2
00006e28: main+160   mov r1, r3
00006e2a: main+162   mov.w r2, #10
00006e2e: main+166   mov.w r3, #0
00006e32: main+170   bl 0x10280 <__aeabi_uldivmod>
00006e36: main+174   mov r2, r0
00006e38: main+176   mov r3, r1
00006e3a: main+178   strd r2, r3, [r7, #72]  ; 0x48
238                    printf( "ulonglong/10: %lld \n", ull);
00006e3e: main+182   movw r3, #11124 ; 0x2b74
00006e42: main+186   movt r3, #1
00006e46: main+190   mov r0, r3
00006e48: main+192   ldrd r2, r3, [r7, #72]  ; 0x48
00006e4c: main+196   bl 0xde70 <printf>

Compiler ist aus der aktuellen CodeRed NXP LPCXresso Edition

c:/nxp/lpcxpresso_4.2.2_275/lpcxpresso/tools/bin/../lib/gcc/arm-none-eab 
i/4.5.1/../../../../arm-none-eabi/lib/thumb2\libcr_c.a(initio.o)

Building file: ../src/main.c
Invoking: MCU C Compiler
arm-none-eabi-gcc -DDEBUG -DGCC_ARMCM3 -D__USE_CMSIS=CMSISv1p30_LPC17xx 
-DALIGN_STRUCT_END=__attribute\(\(aligned\(4\)\)\) 
-DPACK_STRUCT_END=__attribute\(\(packed\)\) -D__REDLIB__ -D__CODE_RED 
-DARM_MATH_CM3 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\Lib_CMSIS 
20_DRIVER\Core\CM3\CoreSupport" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\Lib_CMSIS 
20_DRIVER\Core\CM3\DeviceSupport\NXP\LPC17xx" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\Lib_CMSIS 
20_DRIVER\Drivers\include" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\Lib_CMSIS 
20_DRIVER\Core\DSP_Lib\Include" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\RTOSDemo_ 
RDB1768\src" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\RTOSDemo_ 
RDB1768\src\Common  Demo Tasks\include" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\RTOSDemo_ 
RDB1768\src\FreeRTOS\portable\GCC\ARM_CM3" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\RTOSDemo_ 
RDB1768\src\FreeRTOS\include" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\RTOSDemo_ 
RDB1768\src\measuring" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\RTOSDemo_ 
RDB1768\src\OLED" 
-I"C:\Users\sn.DCIMS\Documents\lpcxpresso_3.6.3_317\workspace2\RTOSDemo_ 
RDB1768\src\webserver"  -O0 -g3 -Wall -c -fmessage-length=0 -fno-builtin 
-ffunction-sections -Wextra -mcpu=cortex-m3 -mthumb -MMD -MP 
-MF"src/main.d" -MT"src/main.d" -o"src/main.o" "../src/main.c"
../src/main.c: In function 'main':
../src/main.c:226:10: warning: unused variable 's'
../src/main.c:213:16: warning: unused variable 'cIPAddress'
Finished building: ../src/main.c

von Tobias Neumann (Gast)


Lesenswert?

wo siehst du denn eine end-los while-schleife vor der ausgabe ?!

die while-schleife beinhaltet den kompletten code (led toggle und 
sprintf).

ich hab mir jetzt auch die neueste code-red heruntergeladen, gcc 4.5.2.

hast du das makefile in meinem archiv mal ausgeführt ?

mit -O0 erzeugt der mir diesen code:

  movw  r0, #:lower16:.LC2  @,
  movt  r0, #:upper16:.LC2  @,
  ldrd  r2, [r7]  @, ll
  bl  printf  @
  .loc 2 119 0
  ldrd  r2, [r7, #16]  @ tmp167,,
  mov  r0, r2  @, tmp167
  mov  r1, r3  @,
  mov  r2, #10  @,
  mov  r3, #0  @,
  bl  __aeabi_uldivmod  @
  mov  r2, r0  @ tmp170,
  mov  r3, r1  @,
  strd  r2, [r7, #16]  @ tmp170,,
  .loc 2 120 0
  movw  r0, #:lower16:.LC3  @,
  movt  r0, #:upper16:.LC3  @,


gibt es eigentlich irgendeine andere quelle ? Ich brauch nur ein 
dementsprechendes makefile und paar beispiele mit dem jeweiligen 
startup-code.

von codered bin ich momentan wirklich verdammt enttäuscht.

von Tobias Neumann (Gast)


Lesenswert?

Ich hab das Problem selbst gefunden.

Hängt aufjedenfall mit der gelinkten lib zusammen. Mit diesem ld-script
funktioniert sprintf.

Im Makefile muss beim linken dann aufjedenfall die option "-nostdlib" 
angegeben werden.

64bit berechnungen gehen allerdings immer noch nicht. hat da noch jemand 
ein tipp für mich ?

MEMORY
{
  /* Define each memory region */
  MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 512k */
  RamLoc64 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x10000 /* 64k */
  RamAHB8_B0A (rwx) : ORIGIN = 0x20000000, LENGTH = 0x2000 /* 8k */
  RamAHB8_B0B (rwx) : ORIGIN = 0x20020000, LENGTH = 0x2000 /* 8k */
  RamAHB16_B1 (rwx) : ORIGIN = 0x20040000, LENGTH = 0x4000 /* 16k */

}
  /* Define a symbol for the top of each memory region */
  __top_MFlash512 = 0x0 + 0x80000;
  __top_RamLoc64 = 0x10000000 + 0x10000;
  __top_RamAHB8_B0A = 0x20000000 + 0x2000;
  __top_RamAHB8_B0B = 0x20020000 + 0x2000;
  __top_RamAHB16_B1 = 0x20040000 + 0x4000;

GROUP(libcr_nohost.a libcr_c.a libcr_eabihelpers.a)

ENTRY(ResetISR)

SECTIONS
{

  /* MAIN TEXT SECTION */
  .text : ALIGN(4)
  {
    FILL(0xff)
    KEEP(*(.isr_vector))

    /* Global Section Table */
    . = ALIGN(4) ;
    __section_table_start = .;
    __data_section_table = .;
    LONG(LOADADDR(.data));
    LONG(    ADDR(.data)) ;
    LONG(  SIZEOF(.data));
    LONG(LOADADDR(.data_RAM2));
    LONG(    ADDR(.data_RAM2)) ;
    LONG(  SIZEOF(.data_RAM2));
    LONG(LOADADDR(.data_RAM3));
    LONG(    ADDR(.data_RAM3)) ;
    LONG(  SIZEOF(.data_RAM3));
    LONG(LOADADDR(.data_RAM4));
    LONG(    ADDR(.data_RAM4)) ;
    LONG(  SIZEOF(.data_RAM4));
    __data_section_table_end = .;
    __bss_section_table = .;
    LONG(    ADDR(.bss));
    LONG(  SIZEOF(.bss));
    LONG(    ADDR(.bss_RAM2));
    LONG(  SIZEOF(.bss_RAM2));
    LONG(    ADDR(.bss_RAM3));
    LONG(  SIZEOF(.bss_RAM3));
    LONG(    ADDR(.bss_RAM4));
    LONG(  SIZEOF(.bss_RAM4));
    __bss_section_table_end = .;
    __section_table_end = . ;
    /* End of Global Section Table */


    *(.after_vectors*)

    /* Code Read Protect data */
    . = 0x000002FC ;
    PROVIDE(_CRP_WORD_START_ = .) ;
    KEEP(*(.crp))
    PROVIDE(_CRP_WORD_END_ = .) ;
    ASSERT(!(_CRP_WORD_START_ == _CRP_WORD_END_), "Linker CRP 
Enabled, but no CRP_WORD provided within application");
    /* End of Code Read Protect */

    *(.text*)
    *(.rodata .rodata.*)
    . = ALIGN(4);

  } > MFlash512

  /*
   * for exception handling/unwind - some Newlib functions (in common
   * with C++ and STDC++) use this.
   */
  .ARM.extab : ALIGN(4)
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } > MFlash512
  __exidx_start = .;

  .ARM.exidx : ALIGN(4)
  {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  } > MFlash512
  __exidx_end = .;

  _etext = .;


  .data_RAM2 : ALIGN(4)
  {
     FILL(0xff)
    *(.data.$RAM2*)
    *(.data.$RamAHB8_B0A*)
     . = ALIGN(4) ;
  } > RamAHB8_B0A AT>MFlash512

  .data_RAM3 : ALIGN(4)
  {
     FILL(0xff)
    *(.data.$RAM3*)
    *(.data.$RamAHB8_B0B*)
     . = ALIGN(4) ;
  } > RamAHB8_B0B AT>MFlash512

  .data_RAM4 : ALIGN(4)
  {
     FILL(0xff)
    *(.data.$RAM4*)
    *(.data.$RamAHB16_B1*)
     . = ALIGN(4) ;
  } > RamAHB16_B1 AT>MFlash512

  /* MAIN DATA SECTION */

  .uninit_RESERVED : ALIGN(4)
  {
    KEEP(*(.bss.$RESERVED*))
  } > RamLoc64

  .data : ALIGN(4)
  {
    FILL(0xff)
    _data = .;
    *(vtable)
    *(.data*)
    . = ALIGN(4) ;
    _edata = .;
  } > RamLoc64 AT>MFlash512


  .bss_RAM2 : ALIGN(4)
  {
    *(.bss.$RAM2*)
    *(.bss.$RamAHB8_B0A*)
     . = ALIGN(4) ;
  } > RamAHB8_B0A

  .bss_RAM3 : ALIGN(4)
  {
    *(.bss.$RAM3*)
    *(.bss.$RamAHB8_B0B*)
     . = ALIGN(4) ;
  } > RamAHB8_B0B

  .bss_RAM4 : ALIGN(4)
  {
    *(.bss.$RAM4*)
    *(.bss.$RamAHB16_B1*)
     . = ALIGN(4) ;
  } > RamAHB16_B1

  /* MAIN BSS SECTION */
  .bss : ALIGN(4)
  {
    _bss = .;
    *(.bss*)
    *(COMMON)
    . = ALIGN(4) ;
    _ebss = .;
    PROVIDE(end = .);
  } > RamLoc64

  PROVIDE(_pvHeapStart = .);
  PROVIDE(_vStackTop = __top_RamLoc64 - 0);
}

von Jojo S. (Gast)


Lesenswert?

ok, das while(1) sah nur hier im Editor komisch eingerückt aus.
Dann benutzt du die libcr_, also die CodeRed Lib, da sollte auch das 
_REDLIB_ define benutzt werden. Im Startcode wird dadurch zB __main() 
statt main() aufgerufen, evtl. fehlen dann Initialisierungen.
Hast du sonst keine Debugmöglichkeit? LPCLink? Ohne JTAG/SWD würde ich 
mich nicht an den Cortex-M3 wagen, das ist ganz schön mühselig.
Das CR Zeug gefällt mir schon ganz gut, es ist leider nur teuer. Und 
wenn du es schon runtergeladen hast, erstelle doch damit ein kleines 
Projekt und vergleiche.

von Roland H. (batchman)


Lesenswert?

Tobias Neumann schrieb:
> Hängt aufjedenfall mit der gelinkten lib zusammen. Mit diesem ld-script
> funktioniert sprintf.
> Im Makefile muss beim linken dann aufjedenfall die option "-nostdlib"
> angegeben werden.

Aus dem Makefile von test.zip
1
LDFLAGS  = -nostdlib -Xlinker --gc-sections -mthumb -T "ld_script.ld" -Xlinker -Map=$(PROG).map
2
3
...
4
5
$(PROG).axf: compile_msg $(DEPS) $(OBJS) link_msg
6
  @echo '$(CC) $(LDFLAGS) -o$@ $(CFLAGS) $(OBJS) '
7
  @$(CC) $(LDFLAGS) -o$@ $(OBJS)

Da war "-nostdlib" schon enthalten?!

Es fehlt m. E. bei den LDFLAGS die Option "-mcpu=cortex-m3". Wie man 
sieht, ist im "echo" davor diese Option durch die CFLAGS indirekt 
enthalten. Wen will der Verfasser damit verwirren?

In meinem Makefile war das gleiche Problem (fehlendes -mcpu in LDFLAGS), 
und es scheint nicht aufzufallen, solange man keine 64-Bit-Operationen 
durchführt. Vermutlich linkt er ohne die korrekte -mcpu-Angabe gegen die 
ARM32-libs. Die "blx" sind bei mir nun auch verschwunden.

Nun funktionieren 64-Bit-Operationen.

von Tobias Neumann (Gast)


Angehängte Dateien:

Lesenswert?

Jungs, Ihr seid Einsame spitze. Daumen hoch und vielen Dank an alle!

Ich hab leider nur die UART-Schnittstelle als Debugmöglichkeit, da ich 
die CPU bereits in meinem eigenen Design drin habe.

CodeRed ist aus meiner Sicht der letzte Mist und verfehlt den Sinn 
"auspacken, installieren, loslegen". Allein diese Eclipse-Umgebung ist 
ein
Krampf. Wer mit Emacs und Makefiles aufgewachsen ist, der dreht sich bei 
solchen Editoren im Grab um - und dann soll man da auch noch Geld für 
zahlen...

Das 64bit Problem ist nun durch die LDFLAGS-Erweiterung der mcpu auch 
behoben, DANKE!!! :)

"-nostdlib" hatte ich zum testen in der Zwischenzeit entfernt gehabt, 
aber das muss aufjedenfall mit rein.

Anbei das "bereinigte" Makefile und die startup.ld - bei dieser 
Konstellation wird kein sysconfig.c benötigt, da die richtigen libs 
gelinkt werden.

von Roland H. (batchman)


Lesenswert?

Tobias Neumann schrieb:
> Ich hab leider nur die UART-Schnittstelle als Debugmöglichkeit, da ich
> die CPU bereits in meinem eigenen Design drin habe.

Mehr verwende ich in der Regel auch nicht. Ich würde auch sagen, dass es 
mit Debugger in diesem Fall nicht einfacher gewesen wäre.

> CodeRed ist aus meiner Sicht der letzte Mist

Dem stimme ich schon zu, weil es sich nur als "root" installieren lässt 
und zumindest in früheren Versionen z. B. libusb überschrieben hat.

> Wer mit Emacs und Makefiles aufgewachsen ist, der dreht sich bei
> solchen Editoren im Grab um

Wieso wechselst Du dann? Du wirst lachen, ich verwende ausschließlich 
Emacs und make. Ich schätze Eclipse für Java, aber mit "Makefile based 
projects" und C/C++ bin ich 2x gescheitert.

> "-nostdlib" hatte ich zum testen in der Zwischenzeit entfernt gehabt,
> aber das muss aufjedenfall mit rein.

Mit "-nostdlib" wird es nicht immer funktionieren. Bei der 
Optimierungsstufe -Os wird gcc ab und zu memcpy oder memset einbauen. 
Kann man aber auch selbst schreiben oder aus der newlib kopieren.

> Das 64bit Problem ist nun durch die LDFLAGS-Erweiterung der mcpu auch
> behoben, DANKE!!! :)

Na also, geht doch :-)

von Jojo S. (Gast)


Lesenswert?

gibt der gcc keine Warnung aus wenn so eine wichtige Angabe fehlt? Der 
Fehler muss doch schon beim kompilieren, nicht erst beim Linken 
enstehen, den 'blx' erzeugt doch der Compiler.

von Jojo S. (Gast)


Lesenswert?

habe das aus Neugier auch nochmal getestet und das Test.zip mit dem 
installierten CR gcc compiliert: es wird ein 'bl' generiert :-)
Der Unterschied dürfte sein das der gcc mit anderen Voreinstellungen 
compiliert wurde (oder woher kommen die?). Setze mal die Flags 
'-save-temps' in das Makefile, dann bleibt das main.s stehen. Da steht 
bei mir im Kopf drin:

  .syntax unified
  .cpu cortex-m3
  .fpu softvfp
  .eabi_attribute 20, 1
  .eabi_attribute 21, 1
  .eabi_attribute 23, 3
  .eabi_attribute 24, 1
  .eabi_attribute 25, 1
  .eabi_attribute 26, 1
  .eabi_attribute 30, 4
  .eabi_attribute 18, 4
  .file  "main.c"
@ GNU C (Red Suite 2010Q4 by Code Red) version 4.5.1 (arm-none-eabi)
@  compiled by GNU C version 4.3.2, GMP version 4.3.2, MPFR version 
2.4.2, MPC version 0.8.1
@ GGC heuristics: --param ggc-min-expand=100 --param 
ggc-min-heapsize=131072
@ options passed:  -fpreprocessed main.i -mcpu=cortex-m3 -mthumb
@ -auxbase-strip main.o -Os -Wall -fmessage-length=0 -fno-builtin
@ -ffunction-sections -fdata-sections -fverbose-asm
@ options enabled:  -falign-loops -fargument-alias -fauto-inc-dec
@ -fbranch-count-reg -fcaller-saves -fcommon -fcprop-registers
@ -fcrossjumping -fcse-follow-jumps -fdata-sections -fdefer-pop
@ -fdelete-null-pointer-checks -fdwarf2-cfi-asm -fearly-inlining
@ -feliminate-unused-debug-types -fexpensive-optimizations
@ -fforward-propagate -ffunction-cse -ffunction-sections -fgcse 
-fgcse-lm
@ -fguess-branch-probability -fident -fif-conversion -fif-conversion2
@ -findirect-inlining -finline -finline-functions
@ -finline-functions-called-once -finline-small-functions -fipa-cp
@ -fipa-pure-const -fipa-reference -fipa-sra -fira-share-save-slots
@ -fira-share-spill-slots -fivopts -fkeep-static-consts
@ -fleading-underscore -fmath-errno -fmerge-constants 
-fmerge-debug-strings
@ -fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls
@ -fpeephole -fpeephole2 -freg-struct-return -fregmove -freorder-blocks
@ -freorder-functions -frerun-cse-after-loop
@ -fsched-critical-path-heuristic -fsched-dep-count-heuristic
@ -fsched-group-heuristic -fsched-interblock -fsched-last-insn-heuristic
@ -fsched-rank-heuristic -fsched-spec -fsched-spec-insn-heuristic
@ -fsched-stalled-insns-dep -fschedule-insns2 -fsection-anchors
@ -fshow-column -fsigned-zeros -fsplit-ivs-in-unroller 
-fsplit-wide-types
@ -fstrict-aliasing -fstrict-overflow -fstrict-volatile-bitfields
@ -fthread-jumps -ftoplevel-reorder -ftrapping-math 
-ftree-builtin-call-dce
@ -ftree-ccp -ftree-ch -ftree-copy-prop -ftree-copyrename -ftree-cselim
@ -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre
@ -ftree-loop-im -ftree-loop-ivcanon -ftree-loop-optimize
@ -ftree-parallelize-loops= -ftree-phiprop -ftree-pta -ftree-reassoc
@ -ftree-scev-cprop -ftree-sink -ftree-slp-vectorize -ftree-sra
@ -ftree-switch-conversion -ftree-ter -ftree-vect-loop-version 
-ftree-vrp
@ -funit-at-a-time -fverbose-asm -fzero-initialized-in-bss
@ -mfix-cortex-m3-ldrd -mlittle-endian -msched-prolog -mthumb

von Tobias Neumann (Gast)


Lesenswert?

Der LPC ist mein erster ARM, da hatte ich die Hoffnung, dass die ersten 
Gehversuche mit CodeRed einfacher wären, vorallem mit den 
Startup-Skripts etc.

Das einzige, was ich jetzt noch verwende sind die CodeRed GCC/Tools, da 
werde ich bei Gelegenheit auch den Kram runterschmeissen und auf bare 
metal gcc umsteigen. Gibt es da irgendwelche Empfehlungen ? Momentan 
weiss ich auch nicht, was die Vorteile der Libred sein sollen, habe da 
newlib aktiv.

Könntest du das Problem mit memcpy bitte noch etwas genauer ausführen ?

@Jojo:
Der Assembler generiert bei mir auch kein "blx", sondern "bl", aber
trotzdem geht da dann irgendwas beim linken in die Hose, wenn die mcpu 
dort nicht angegeben ist.

von Jojo S. (Gast)


Lesenswert?

> @Jojo:
> Der Assembler generiert bei mir auch kein "blx", sondern "bl", aber
> trotzdem geht da dann irgendwas beim linken in die Hose, wenn die mcpu
> dort nicht angegeben ist.

ja, sehe ich jetzt auch, ganz schön kompliziert... Zum kompilieren wurde 
der mcpu switch doch schon benutzt. In den map files sieht man aber 
Unterschiede, ohne die -mcpu wurden die 64 Bit Ops aus der 'thumb' lib 
benutzt, mit -mcpu aus der 'thumb2'.

Eine Diskussion über die Tools passt in diesen Thread nicht gut rein, 
das artet eh nur aus wg. IDE vs Kommandozeile oder Editor :-) Ich habe 
zumindest mit der CR/LPCXpresso einen guten Einstieg gefunden, hat alles 
auf Anhieb geklappt. Gut in der IDE muss man halt die Einstellungen 
erstmal alle finden.
Das CooCox sieht noch brauchbar aus, allerdings sind die von den 
Chinesen selbst geschriebenen Tools auch closed source und auf Fehler 
oder Probleme reagieren die da sehr langsam.
Nur bei den schönen SWD Debugmöglichkeiten möchte ich wirklich kein 
printf-Debugging mehr haben, das ist echt nicht state-of-the-art.

von Jojo S. (Gast)


Lesenswert?

wg. der Lib:
http://support.code-red-tech.com/CodeRedWiki/RedlibAndNewlib

die Redlib ist wesentlich schlanker, in meinem Bastelprojekt macht das 
85k zu 130k Codesize.
Den Startup Code finde ich auch sehr übersichtlich. Schwieriger ist eher 
erstmal PLL und Power richtig einzustellen, da hilft die CMSIS schon.

von Roland H. (batchman)


Lesenswert?

Jojo S. schrieb:
> gibt der gcc keine Warnung aus wenn so eine wichtige Angabe fehlt? Der
> Fehler muss doch schon beim kompilieren, nicht erst beim Linken
> enstehen, den 'blx' erzeugt doch der Compiler.

Nein, keine Warnung.

M. W. gibt es leider "Default-Werte" beim Compiler, Assembler und 
Linker.

Beim Kompilieren sind die Div-Routinen extern, da gibt es keine Fehler.

Das Linken von "thumb" und "arm32" "object files" gemischt kann im Falle 
von "interworking" durchaus Sinn machen. Bei Cortex-Mx natürlich nicht.

Vermutlich wirkt sich das "-mcpu" bei ld nur auf die Auswahl der zu 
linkenden Library aus. Darüber hinaus gibt es zumindest für diesen Fall 
keine Prüfung.

Die Sache mit dem "bl":
Das "blx" entstand nur bei mir, d. h. nicht mit einem GCC von Code Red.

Es ist in der Tat so, dass im .s noch ein "bl" steht (in beiden Fällen):
1
        bl      __aeabi_uldivmod

im .lss steht im Falle von "ohne -mcpu=cortex-m3"
1
     aba:       f002 e89e       blx     2bf8 <__aeabi_uldivmod>

Wer kann das gewesen sein, wenn nicht der Linker?

Jojo S. schrieb:
> Der Unterschied dürfte sein das der gcc mit anderen Voreinstellungen
> compiliert wurde (oder woher kommen die?). Setze mal die Flags
> '-save-temps' in das Makefile, dann bleibt das main.s stehen. Da steht
> bei mir im Kopf drin:

Da ist bei mir leider nix drin, schade eigentlich. Es ist der GCC aus 
"summon-arm-toolchain".

Tobias Neumann schrieb:
> Der LPC ist mein erster ARM, da hatte ich die Hoffnung, dass die ersten
> Gehversuche mit CodeRed einfacher wären, vorallem mit den
> Startup-Skripts etc.

Der guten Ordnung halber, es war ein Sammelsurium aus uint64, einer 
fehlenden Option im Makefile für den Linker, und einer nicht vorhandenen 
Prüfung im Linker. Kam das 64-Bit-CMSIS im Paket mit Code Red oder 
separat? Ich wage zu behaupten, es lag weder am Startup noch am Linker 
Skript.

Tobias Neumann schrieb:
> und auf bare
> metal gcc umsteigen. Gibt es da irgendwelche Empfehlungen ?

Bis zu diesem Thread hätte ich uneingeschränkt "summon-arm-toolchain" 
empfohlen, da diese auch den Cortex-M4 mit FPU unterstützt.

Zwischendurch wollte ich die uint64-Thematik auf dem stm32f407 (CM4 mit 
FPU) testen. Dort weigert sich der Linker, weil er für die 
Parameterübergabe der 64-Bit-Variablen über die VFP-Register eine 
separate multilib benötigt.

Vermutlich gibt es kein größeres Interesse, siehe:

https://github.com/esden/summon-arm-toolchain/issues/14

Ich teste gerade den "fork", aber die Existenz dieses "forks" ist etwas 
unschön.

> Momentan
> weiss ich auch nicht, was die Vorteile der Libred sein sollen, habe da
> newlib aktiv.

Generell bin ich über folgende Punkte gestolpert
- Es ging nicht (printf retargeting)
- Es bläht den Code auf
- Es benötigt Puffer (sprintf - schlecht auf attiny/msp430g)
- Es ist nicht portabel (8-Bitter, 16-Bitter, 32-Bitter:AVR - MSP430 - 
ARM/PIC32/Renesas RX)
- Es gibt Lizenzthemen im weitesten Sinne

Wie schon geschrieben, ich habe mir alles selbst geschrieben. Das Zeugs 
läuft also vom kleinen attiny bis zu den "großen" 32-Bittern. Seitdem 
ist Ruhe im Karton.

Tobias Neumann schrieb:
> Könntest du das Problem mit memcpy bitte noch etwas genauer ausführen ?

Manche "Massen-Initialisierungen" von Variablen/Arrays schreibt der GCC 
um. Statt irgendwelcher Einzelzuweisungen kopiert er dann per memcpy 
einen ganzen Bereich in die Zielvariablen. Soweit zumindest mein 
Verständnis.

Tobias Neumann schrieb:
> aber
> trotzdem geht da dann irgendwas beim linken in die Hose, wenn die mcpu
> dort nicht angegeben ist.

Tja, "Operation gelunden - Patient tot". Das Linken an sich ist 
erfolgreich, es kommt zur Laufzeit zu einer "undefined instruction".

Wobei zu klären ist, wo das "blx" gesehen wurde: Wie schon oben 
geschrieben, bei mir tauchte es erst im ".lss" auf, also dem Listung, 
welches aus der .elf generiert wurde.

von Tobias Neumann (Gast)


Lesenswert?

Ohje...

hab noch eine letzte frage, ich würde gerne die cpu mit volle Leistung 
betreiben. Werde allerdings nicht wirklich schlau.

Ich hab mittlerweile auch die XLS von NXP (siehe link von Jojo), weiss 
allerdings nicht richtig mit dem Teil umzugehen.

FIn = 25Mhz

Inwiefern ist jetzt Fcco wichtig, bzw: was muss ich dort eintragen, wenn 
ich auf 120mhz auftakten möchte ?

Wenn ich im Max-Cpu Feld 120 eintrage, dann ist es ein ungültiger Wert.

Kann mir das bitte jemand erklären, bzw: mir einfach die Werte für die 
Initialisierung für 120Mhz Systemtakt bei 25Mhz Fin geben ?

von Jojo S. (Gast)


Lesenswert?

Das xls ist vielleicht noch aus der Zeit bevor es die 120 MHz CPUs gab, 
die meisten aus der Serie laufen ja 'nur' bis 100 MHz.
Gültige Werte wären: Fcco=480 MHz bei Fin=25MHz.
Eingestellt werden muss dann der CPU Divider=4, M=48, N=5. Das Fcco von 
480 MHz damit man auch einen passenden Clock für USB hat, da kann man 
dann auch PLL0 verwenden und den USB Teiler von 10 einstellen.
Das Ganze ergibt sich leider nur aus Querlesen von Datenblatt, diesen 
Excelsheet und Beispielen...

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.