Forum: Compiler & IDEs arm-none-eabi Problem.


von Holm T. (Gast)


Lesenswert?

Ich habe hier auf meinem FreeBSD einen arm-none-eabi  GCC Port der schon 
etwas angegraut ist.
Ich habe deshalb die aktuelle Toolchain Version 8-2018-q4-major selber 
gebaut, was ein ziemlich längliches Verfaren war, weil die Shell-Scripte 
doch etliche Bugs hatten und sinnloser Weise immer wieder von vorne 
anfangen zu konfigurieren und zu kompilieren als gäbe es kein Make und 
keine Depencies.
Wenig hilfreich ist auch das die Definitionen für sämtliche Interrupts 
fehlen, die darf man sich dann selber ins Linkerscript oder 
Startup-Assemblerfile häkeln..52 Stück... hmm....

Irgendwann bin ich doch mal fertig damit geworden und mein Programm an 
dem ich herumbastele läuft nun sowohl auf der alten, also auch auf der 
neuen Toolchain....so lange ich die Finger von strcpy() lasse, da ist 
noch irgendwas faul und ich weiß nicht was.

in meinem Progrämmchen gibts diesen simplen code:
1
uint8_t disp_buff[32];
2
[..]
3
strcpy((char *)disp_buff,"1234");
4
...

damit hängt sich das Programm auf, damit auch:
1
[..]
2
      strcpy(obp,"lolo!\r\n");
3
      USART3_PutString(obp);
4
[..]

..damit aber nicht:
1
uint8_t disp_buff[32];
2
[..]
3
        disp_buff[0]='1';
4
        disp_buff[2]='2';
5
        disp_buff[3]='3';
6
        disp_buff[4]='4';

und damit auch nicht:
1
uint8_t disp_buff[32];
2
[..]
3
char * mstrcpy(char *d, char *s)
4
{
5
        while(*s)
6
                *d++=*s++;
7
        return d;
8
}
9
[..]
10
mstrcpy((char *)disp_buff,"1234");
11
12
[..]

..und ich pople schon eine Weile dran herum ohne zu finden was lost ist.
Ehe jetzt nachfragen nach dem gesamten Code kommen..der wäre sinnlos. 
Ich habs schon bis dahin eingegrenzt und code kommt noch..allerdings 
Assembler. Das strcpy() aus der newlib sieht dann so aus:
1
08002550 <strcpy>:
2
 8002550:       e1a03000        mov     r3, r0
3
 8002554:       e4d12001        ldrb    r2, [r1], #1
4
 8002558:       e4c32001        strb    r2, [r3], #1
5
 800255c:       e3520000        cmp     r2, #0, 0
6
 8002560:       1afffffb        bne     8002554 <strcpy+0x4>
7
 8002564:       e12fff1e        bx      lr
8
9
08002568 <_init>:

Ich kann daran eigentlich gar nichts Falsches finden, gesetzt den Fall
dass r1 und r3 die Pointer zu den Strings enthalten. Ich kenne ARM Thumb 
nicht, aber zumindest siehts nicht doof aus.
mstrcpy sieht so aus:
1
080005a6 <mstrcpy>:
2
 80005a6:       3901            subs    r1, #1
3
 80005a8:       f811 3f01       ldrb.w  r3, [r1, #1]!
4
 80005ac:       b90b            cbnz    r3, 80005b2 <mstrcpy+0xc>
5
 80005ae:       7800            ldrb    r0, [r0, #0]
6
 80005b0:       4770            bx      lr
7
 80005b2:       f800 3b01       strb.w  r3, [r0], #1
8
 80005b6:       e7f7            b.n     80005a8 <mstrcpy+0x2>

..keine Ahnung was das treibt, aber es funktioniert.

Die alte Version des Compilers mach sowas Schickes:
1
080023f4 <strcpy>:
2
 80023f4:       e0202001        eor     r2, r0, r1
3
 80023f8:       e1a0c000        mov     ip, r0
4
 80023fc:       e3120003        tst     r2, #3, 0
5
 8002400:       1a000032        bne     80024d0 <strcpy+0xdc>
6
 8002404:       e3110003        tst     r1, #3, 0
7
 8002408:       1a000021        bne     8002494 <strcpy+0xa0>
8
 800240c:       e52d5004        push    {r5}            ; (str r5, [sp, #-4]!)
9
 8002410:       e3a05001        mov     r5, #1, 0
10
 8002414:       e1855405        orr     r5, r5, r5, lsl #8
11
 8002418:       e1855805        orr     r5, r5, r5, lsl #16
12
 800241c:       e52d4004        push    {r4}            ; (str r4, [sp, #-4]!)
13
 8002420:       e3110004        tst     r1, #4, 0
14
 8002424:       e4913004        ldr     r3, [r1], #4
15
 8002428:       0a000005        beq     8002444 <strcpy+0x50>
16
 800242c:       e0432005        sub     r2, r3, r5
17
 8002430:       e1d22003        bics    r2, r2, r3
18
 8002434:       e1120385        tst     r2, r5, lsl #7
19
 8002438:       048c3004        streq   r3, [ip], #4
20
 800243c:       04913004        ldreq   r3, [r1], #4
21
 8002440:       1a00000c        bne     8002478 <strcpy+0x84>
22
 8002444:       e4914004        ldr     r4, [r1], #4
23
 8002448:       e0432005        sub     r2, r3, r5
24
 800244c:       e1d22003        bics    r2, r2, r3
25
 8002450:       e1120385        tst     r2, r5, lsl #7
26
 8002454:       e0442005        sub     r2, r4, r5
27
 8002458:       1a000006        bne     8002478 <strcpy+0x84>
28
 800245c:       e48c3004        str     r3, [ip], #4
29
 8002460:       e1d22004        bics    r2, r2, r4
30
 8002464:       e1120385        tst     r2, r5, lsl #7
31
 8002468:       04913004        ldreq   r3, [r1], #4
32
 800246c:       048c4004        streq   r4, [ip], #4
33
 8002470:       0afffff3        beq     8002444 <strcpy+0x50>
34
 8002474:       e1a03004        mov     r3, r4
35
 8002478:       e4cc3001        strb    r3, [ip], #1
36
 800247c:       e31300ff        tst     r3, #255, 0     ; 0xff
37
 8002480:       e1a03463        ror     r3, r3, #8
38
 8002484:       1afffffb        bne     8002478 <strcpy+0x84>
39
 8002488:       e49d4004        pop     {r4}            ; (ldr r4, [sp], #4)
40
 800248c:       e49d5004        pop     {r5}            ; (ldr r5, [sp], #4)
41
 8002490:       e12fff1e        bx      lr
42
 8002494:       e3110001        tst     r1, #1, 0
43
 8002498:       0a000003        beq     80024ac <strcpy+0xb8>
44
 800249c:       e4d12001        ldrb    r2, [r1], #1
45
 80024a0:       e4cc2001        strb    r2, [ip], #1
46
 80024a4:       e3520000        cmp     r2, #0, 0
47
 80024a8:       012fff1e        bxeq    lr
48
 80024ac:       e3110002        tst     r1, #2, 0
49
 80024b0:       0affffd5        beq     800240c <strcpy+0x18>
50
 80024b4:       e0d120b2        ldrh    r2, [r1], #2
51
 80024b8:       e31200ff        tst     r2, #255, 0     ; 0xff
52
 80024bc:       10cc20b2        strhne  r2, [ip], #2
53
 80024c0:       05cc2000        strbeq  r2, [ip]
54
 80024c4:       13120cff        tstne   r2, #65280      ; 0xff00
55
 80024c8:       1affffcf        bne     800240c <strcpy+0x18>
56
 80024cc:       e12fff1e        bx      lr
57
 80024d0:       e4d12001        ldrb    r2, [r1], #1
58
 80024d4:       e4cc2001        strb    r2, [ip], #1
59
 80024d8:       e3520000        cmp     r2, #0, 0
60
 80024dc:       1afffffb        bne     80024d0 <strcpy+0xdc>
61
 80024e0:       e12fff1e        bx      lr

..aber da kommt bei mir der Maschinist mit der weißen Fahne raus. Das 
funktioniert auch, aber mir ist unklar wie man das so lang machen kann.

Ich bastele das Ganze auf einer Bluepill, also einem STM32F103C8T6, die 
Compiler Optionen sind
1
 
2
arm-none-eabi-gcc --specs=nano.specs -u _printf_float -fno-builtin -mcpu=cortex-m3 -mthumb -Wall -g -Os -D__STARTUP_CLEAR_BSS  -D__START=main  -c   -c -o startup_ARMCM3-holm.o startup_ARMCM3-holm.S
3
arm-none-eabi-gcc --specs=nano.specs -u _printf_float -fno-builtin -mcpu=cortex-m3 -mthumb -Wall -g -Os -I /home/holm/arm-none-eabi/include -I . -I lib/inc -I STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport -I STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x   -c -o main.o main.c
4
main.c: In function 'main':
5
main.c:389:8: warning: variable 'obp' set but not used [-Wunused-but-set-variable]
6
 char * obp;
7
        ^~~
8
main.c:386:8: warning: variable 'sevenths' set but not used [-Wunused-but-set-variable]
9
 double sevenths;
10
        ^~~~~~~~
11
arm-none-eabi-gcc --specs=nano.specs -u _printf_float -fno-builtin -mcpu=cortex-m3 -mthumb -Wall -g -Os -I /home/holm/arm-none-eabi/include -I . -I lib/inc -I STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport -I STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x   -c -o usart.o usart.c
12
[..]
13
CMSIS Library
14
[..]
15
arm-none-eabi-gcc -fno-builtin --specs=nano.specs  -fno-builtin -Wl,--gc-sections,-Map=main.elf.map,-cref -L lib -T gcc.ld startup_ARMCM3-holm.o main.o usart.o stm32f10x_it.o eeprom.o system_stm32f10x.o lib/libstm32.a --output main.elf
16
arm-none-eabi-objcopy -O binary main.elf main.bin


Kennt sich Einer mit Thumb Assembler gut aus und hat eine Idee zu meinem 
Problem?

Danke im Vorraus,

Holm

von Fred (Gast)


Lesenswert?

Hast du mal die disassembly von deinem strcpy-Aufruf der nicht 
funtkioniert? lass dir mal strlen("abcd") ausgeben

von Holm T. (Gast)


Lesenswert?

Fred schrieb:
> Hast du mal die disassembly von deinem strcpy-Aufruf der nicht
> funtkioniert? lass dir mal strlen("abcd") ausgeben

..da sieht man nicht viel..
1
 5a:   f24a 52a5       movw    r2, #42405      ; 0xa5a5
2
  5e:   4291            cmp     r1, r2
3
  60:   d001            beq.n   66 <main+0x66>
4
  62:   f7ff fffe       bl      2d0 <eeprom_init>
5
  66:   6823            ldr     r3, [r4, #0]
6
  68:   4f31            ldr     r7, [pc, #196]  ; (130 <main+0x130>)
7
  6a:   8818            ldrh    r0, [r3, #0]
8
  6c:   f7ff fffe       bl      190 <sevenseg_disp>
9
  70:   f44f 70fa       mov.w   r0, #500        ; 0x1f4
10
  74:   f7ff fffe       bl      0 <main>
11
12
  78:   492e            ldr     r1, [pc, #184]  ; (134 <main+0x134>)
13
  7a:   4638            mov     r0, r7
14
  7c:   f7ff fffe       bl      0 <strcpy>
15
16
  80:   492c            ldr     r1, [pc, #176]  ; (134 <main+0x134>)
17
  82:   4638            mov     r0, r7
18
  84:   f7ff fffe       bl      406 <mstrcpy>
19
20
  88:   7838            ldrb    r0, [r7, #0]
21
  8a:   463e            mov     r6, r7
22
  8c:   3830            subs    r0, #48 ; 0x30
23
  8e:   b283            uxth    r3, r0
24
  90:   7878            ldrb    r0, [r7, #1]
25
  92:   4c29            ldr     r4, [pc, #164]  ; (138 <main+0x138>)
26
  94:   3830            subs    r0, #48 ; 0x30
27
  96:   b280            uxth    r0, r0

Rest mach ich Dir morgen, ich habs für heute satt.

Gruß,
Holm

von M.K. B. (mkbit)


Lesenswert?

Kannst du auf dem Target debuggen? Vielleicht geht irgendwas beim Aufruf 
schief. Sonst könntest du durch den Assembler einzeln durchsteppen und 
sehen was nicht funktioniert.

von Holm T. (Gast)


Lesenswert?

..nein, hab ich noch nicht probiert, sollte allerdings möglich sein...

Gruß,

Holm

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Holm T. schrieb:
> Das strcpy() aus der newlib sieht dann so aus:
>
> 08002550 <strcpy>:
>  8002550:       e1a03000        mov     r3, r0

Das ist "ARM"-Code, kein Thumb-Code. Den kann der Cortex-M nicht 
ausführen und stürzt zurecht ab. Du hast die falsche C-Bibliothek 
gelinkt bzw. die richtige Bibliothek falsch konfiguriert.

Holm T. schrieb:
> Die alte Version des Compilers mach sowas Schickes:080023f4 <strcpy>:
Auch ARM-Code...


Holm T. schrieb:
> ..aber da kommt bei mir der Maschinist mit der weißen Fahne raus. Das
> funktioniert auch, aber mir ist unklar wie man das so lang machen kann.

Da war Loop Unrolling im Spiel (C-Library mit -O3 kompiliert?). Da das 
ARM-Code ist kann das auf dem Cortex-M nicht funktionieren. Auf den 
großen Cortex-A, für welche solcher Code ist, kann das die Performance 
verbessern.

Holm T. schrieb:
> ..keine Ahnung was das treibt, aber es funktioniert.
Weil das Thumb2-Code ist. Leicht (heuristisch) daran zu erkennen, dass 
die meisten Instruktionen im Maschinencode (siehe Hex-Dump in der 2. 
Spalte) 16bit, manche 32bit sind. Beim ARM-Code hingegen ist alles 
32bit, und vieles fängt mit "E" an (für Condition Code .AL, "always").

Versuche mal auch beim Linken "-mthumb -mcpu=cortex-m3" zu übergeben, 
damit der Linker weiß, welche Bibliothek er nehmen muss.

Holm T. schrieb:
> Wenig hilfreich ist auch das die Definitionen für sämtliche Interrupts
> fehlen, die darf man sich dann selber ins Linkerscript oder
> Startup-Assemblerfile häkeln..52 Stück... hmm....

Normalerweise kopiert man sich die startup_stm32XX.S aus einem 
Template/Beispiel-Projekt, da stehen die drin.

: Bearbeitet durch User
von Holm T. (Gast)


Lesenswert?

Niklas G. schrieb:
> Holm T. schrieb:
>> Das strcpy() aus der newlib sieht dann so aus:
>>
>> 08002550 <strcpy>:
>>  8002550:       e1a03000        mov     r3, r0
>
> Das ist "ARM"-Code, kein Thumb-Code. Den kann der Cortex-M nicht
> ausführen und stürzt zurecht ab. Du hast die falsche C-Bibliothek
> gelinkt bzw. die richtige Bibliothek falsch konfiguriert.

Du kriegst einen Schmatz auf den Bauch das die Seele quietscht :-)

Die Maschinendefinition war zwar im Compiler Aufruf drin, allerdings 
fehlte sie beim Lader.

.. es ist halt gut wenn man die Mnemonics kennt, die sind mir aber 
vorläufig ein Buch mit 7 Siegeln. Wird schon noch werden..

>
> Holm T. schrieb:
>> Die alte Version des Compilers mach sowas Schickes:080023f4 <strcpy>:
> Auch ARM-Code...


..ist aber komisch..weil das geht?
>
>
> Holm T. schrieb:
>> ..aber da kommt bei mir der Maschinist mit der weißen Fahne raus. Das
>> funktioniert auch, aber mir ist unklar wie man das so lang machen kann.
>
> Da war Loop Unrolling im Spiel (C-Library mit -O3 kompiliert?). Da das
> ARM-Code ist kann das auf dem Cortex-M nicht funktionieren. Auf den
> großen Cortex-A, für welche solcher Code ist, kann das die Performance
> verbessern.

..es funktioniert aber, keine Ahnung was da los ist. Ich glaube Dir 
schon..kann das sein das das falsch disassembliert ist?
>
> Holm T. schrieb:
>> ..keine Ahnung was das treibt, aber es funktioniert.
> Weil das Thumb2-Code ist. Leicht (heuristisch) daran zu erkennen, dass
> die meisten Instruktionen im Maschinencode (siehe Hex-Dump in der 2.
> Spalte) 16bit, manche 32bit sind. Beim ARM-Code hingegen ist alles
> 32bit, und vieles fängt mit "E" an (für Condition Code .AL, "always").
>
> Versuche mal auch beim Linken "-mthumb -mcpu=cortex-m3" zu übergeben,
> damit der Linker weiß, welche Bibliothek er nehmen muss.
>
> Holm T. schrieb:
>> Wenig hilfreich ist auch das die Definitionen für sämtliche Interrupts
>> fehlen, die darf man sich dann selber ins Linkerscript oder
>> Startup-Assemblerfile häkeln..52 Stück... hmm....
>
> Normalerweise kopiert man sich die startup_stm32XX.S aus einem
> Template/Beispiel-Projekt, da stehen die drin.

Nö..sonst hätte ich sie da nicht nachtragen müssen. Da stehen die ersten 
paar drin, bis SysTick_Handler, danach ist ein DEF_Handler definiert und 
dann kommt da nichts mehr. Ich habe ne Weile gebraucht um zu realisieren 
das ein Teil des Start Codes auf den Vector Adressen lag.

Hab vielen Dank!

funktioniert jetzt wie es sollte.

Gruß,

Holm

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Holm T. schrieb:
> .. es ist halt gut wenn man die Mnemonics kennt, die sind mir aber
> vorläufig ein Buch mit 7 Siegeln. Wird schon noch werden..

Das Gemeine ist, dass die Mnemonics von ARM und Thumb2 teilweise 
gleich/ähnlich sind. Der Unterschied wird erst am Maschinencode 
sichtbar.

Holm T. schrieb:
> ..es funktioniert aber, keine Ahnung was da los ist.

Dann hast du das falsche Binary ausprobiert, die Funktion wird nie 
aufgerufen, das falsche Disassembly gepostet... Das kann so auf keinen 
Fall laufen.

Holm T. schrieb:
> kann das sein das das falsch disassembliert ist?
>>

Nö, der Maschinencode ist definitiv ARM-Code, egal was der Disassembler 
da draus macht.

Holm T. schrieb:
> Nö..sonst hätte ich sie da nicht nachtragen müssen.

Dann hast du die falsche Datei erwischt. Das gibts auch schon alles 
fertig. Du musst halt eines der ST-Beispiele/Templates für den STM32F103 
nehmen, oder per STM32CubeMX generieren. Der Compiler kann kaum 
ISR-Vektor-Definitionen für die Zigtausend verschiedenen ARM-Prozessoren 
mitliefern, daher muss man das selbst einbinden.

von Nico W. (nico_w)


Lesenswert?

Bis zum SysTick sind die Cortexe auch alle gleich. Daher "fehlt" der 
Rest.

: Bearbeitet durch User
von Holm T. (Gast)


Lesenswert?

Niklas G. schrieb:
> Holm T. schrieb:
>> .. es ist halt gut wenn man die Mnemonics kennt, die sind mir aber
>> vorläufig ein Buch mit 7 Siegeln. Wird schon noch werden..
>
> Das Gemeine ist, dass die Mnemonics von ARM und Thumb2 teilweise
> gleich/ähnlich sind. Der Unterschied wird erst am Maschinencode
> sichtbar.
>
> Holm T. schrieb:
>> ..es funktioniert aber, keine Ahnung was da los ist.
>
> Dann hast du das falsche Binary ausprobiert, die Funktion wird nie
> aufgerufen, das falsche Disassembly gepostet... Das kann so auf keinen
> Fall laufen.
>
> Holm T. schrieb:
>> kann das sein das das falsch disassembliert ist?
>>>
>
> Nö, der Maschinencode ist definitiv ARM-Code, egal was der Disassembler
> da draus macht.
>
> Holm T. schrieb:
>> Nö..sonst hätte ich sie da nicht nachtragen müssen.
>
> Dann hast du die falsche Datei erwischt. Das gibts auch schon alles
> fertig. Du musst halt eines der ST-Beispiele/Templates für den STM32F103
> nehmen, oder per STM32CubeMX generieren. Der Compiler kann kaum
> ISR-Vektor-Definitionen für die Zigtausend verschiedenen ARM-Prozessoren
> mitliefern, daher muss man das selbst einbinden.

Das war aus dem Beispiel/Template:
Keine Ahnung ob das automagisch expandiert werden sollte..

gcc-arm-none-eabi/samples/startup/startup_ARMCM0.S
gcc-arm-none-eabi/samples/startup/startup_ARMCM3.S
gcc-arm-none-eabi/samples/startup/startup_ARMCM7.S
gcc-arm-none-eabi/samples/startup/startup_ARMCM4.S
1
/* File: startup_ARMCM3.S
2
 * Purpose: startup file for Cortex-M3 devices. Should use with
3
 *   GCC for ARM Embedded Processors
4
 * Version: V2.0
5
 * Date: 16 August 2013
6
 *
7
/* Copyright (c) 2011 - 2013 ARM LIMITED
8
9
   All rights reserved.
10
   Redistribution and use in source and binary forms, with or without
11
   modification, are permitted provided that the following conditions are met:
12
   - Redistributions of source code must retain the above copyright
13
     notice, this list of conditions and the following disclaimer.
14
   - Redistributions in binary form must reproduce the above copyright
15
     notice, this list of conditions and the following disclaimer in the
16
     documentation and/or other materials provided with the distribution.
17
   - Neither the name of ARM nor the names of its contributors may be used
18
     to endorse or promote products derived from this software without
19
     specific prior written permission.
20
   *
21
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
25
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
   POSSIBILITY OF SUCH DAMAGE.
32
   ---------------------------------------------------------------------------*/
33
        .syntax unified
34
        .arch   armv7-m
35
36
        .section .stack
37
        .align  3
38
#ifdef __STACK_SIZE
39
        .equ    Stack_Size, __STACK_SIZE
40
#else
41
        .equ    Stack_Size, 0xc00
42
#endif
43
        .globl  __StackTop
44
        .globl  __StackLimit
45
__StackLimit:
46
        .space  Stack_Size
47
        .size   __StackLimit, . - __StackLimit
48
__StackTop:
49
        .size   __StackTop, . - __StackTop
50
51
        .section .heap
52
        .align  3
53
#ifdef __HEAP_SIZE
54
        .equ    Heap_Size, __HEAP_SIZE
55
#else
56
        .equ    Heap_Size, 0
57
#endif
58
        .globl  __HeapBase
59
        .globl  __HeapLimit
60
__HeapBase:
61
        .if     Heap_Size
62
        .space  Heap_Size
63
        .endif
64
        .size   __HeapBase, . - __HeapBase
65
__HeapLimit:
66
        .size   __HeapLimit, . - __HeapLimit
67
68
        .section .isr_vector
69
        .align  2
70
        .globl  __isr_vector
71
__isr_vector:
72
        .long   __StackTop            /* Top of Stack */
73
        .long   Reset_Handler         /* Reset Handler */
74
        .long   NMI_Handler           /* NMI Handler */
75
        .long   HardFault_Handler     /* Hard Fault Handler */
76
        .long   MemManage_Handler     /* MPU Fault Handler */
77
        .long   BusFault_Handler      /* Bus Fault Handler */
78
        .long   UsageFault_Handler    /* Usage Fault Handler */
79
        .long   0                     /* Reserved */
80
        .long   0                     /* Reserved */
81
        .long   0                     /* Reserved */
82
        .long   0                     /* Reserved */
83
        .long   SVC_Handler           /* SVCall Handler */
84
        .long   DebugMon_Handler      /* Debug Monitor Handler */
85
        .long   0                     /* Reserved */
86
        .long   PendSV_Handler        /* PendSV Handler */
87
        .long   SysTick_Handler       /* SysTick Handler */
88
89
        /* External interrupts */
90
        .long   Default_Handler
91
92
        .size   __isr_vector, . - __isr_vector
93
94
        .text
95
        .thumb
96
        .thumb_func
97
        .align  2
98
        .globl  Reset_Handler
99
        .type   Reset_Handler, %function
100
Reset_Handler:
101
/*  Firstly it copies data from read only memory to RAM. There are two schemes
102
 *  to copy. One can copy more than one sections. Another can only copy
103
 *  one section.  The former scheme needs more instructions and read-only
104
 *  data to implement than the latter.
105
 *  Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes.  */
106
107
#ifdef __STARTUP_COPY_MULTIPLE
108
/*  Multiple sections scheme.
109
 *
110
 *  Between symbol address __copy_table_start__ and __copy_table_end__,
111
 *  there are array of triplets, each of which specify:
112
 *    offset 0: LMA of start of a section to copy from
113
 *    offset 4: VMA of start of a section to copy to
114
 *    offset 8: size of the section to copy. Must be multiply of 4
115
 *
116
 *  All addresses must be aligned to 4 bytes boundary.
117
 */
118
        ldr     r4, =__copy_table_start__
119
        ldr     r5, =__copy_table_end__
120
121
.L_loop0:
122
        cmp     r4, r5
123
        bge     .L_loop0_done
124
        ldr     r1, [r4]
125
        ldr     r2, [r4, #4]
126
        ldr     r3, [r4, #8]
127
128
.L_loop0_0:
129
        subs    r3, #4
130
        ittt    ge
131
        ldrge   r0, [r1, r3]
132
        strge   r0, [r2, r3]
133
        bge     .L_loop0_0
134
135
        adds    r4, #12
136
        b       .L_loop0
137
138
.L_loop0_done:
139
#else
140
/*  Single section scheme.
141
 *
142
 *  The ranges of copy from/to are specified by following symbols
143
 *    __etext: LMA of start of the section to copy from. Usually end of text
144
 *    __data_start__: VMA of start of the section to copy to
145
 *    __data_end__: VMA of end of the section to copy to
146
 *
147
 *  All addresses must be aligned to 4 bytes boundary.
148
 */
149
        ldr     r1, =__etext
150
        ldr     r2, =__data_start__
151
        ldr     r3, =__data_end__
152
153
.L_loop1:
154
        cmp     r2, r3
155
        ittt    lt
156
        ldrlt   r0, [r1], #4
157
        strlt   r0, [r2], #4
158
        blt     .L_loop1
159
#endif /*__STARTUP_COPY_MULTIPLE */
160
161
/*  This part of work usually is done in C library startup code. Otherwise,
162
 *  define this macro to enable it in this startup.
163
 *
164
 *  There are two schemes too. One can clear multiple BSS sections. Another
165
 *  can only clear one section. The former is more size expensive than the
166
 *  latter.
167
 *
168
 *  Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
169
 *  Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
170
 */
171
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
172
/*  Multiple sections scheme.
173
 *
174
 *  Between symbol address __copy_table_start__ and __copy_table_end__,
175
 *  there are array of tuples specifying:
176
 *    offset 0: Start of a BSS section
177
 *    offset 4: Size of this BSS section. Must be multiply of 4
178
 */
179
        ldr     r3, =__zero_table_start__
180
        ldr     r4, =__zero_table_end__
181
182
.L_loop2:
183
        cmp     r3, r4
184
        bge     .L_loop2_done
185
        ldr     r1, [r3]
186
        ldr     r2, [r3, #4]
187
        movs    r0, 0
188
189
.L_loop2_0:
190
        subs    r2, #4
191
        itt     ge
192
        strge   r0, [r1, r2]
193
        bge     .L_loop2_0
194
195
        adds    r3, #8
196
        b       .L_loop2
197
.L_loop2_done:
198
#elif defined (__STARTUP_CLEAR_BSS)
199
/*  Single BSS section scheme.
200
 *
201
 *  The BSS section is specified by following symbols
202
 *    __bss_start__: start of the BSS section.
203
 *    __bss_end__: end of the BSS section.
204
 *
205
 *  Both addresses must be aligned to 4 bytes boundary.
206
 */
207
        ldr     r1, =__bss_start__
208
        ldr     r2, =__bss_end__
209
210
        movs    r0, 0
211
.L_loop3:
212
        cmp     r1, r2
213
        itt     lt
214
        strlt   r0, [r1], #4
215
        blt     .L_loop3
216
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
217
218
#ifndef __NO_SYSTEM_INIT
219
        bl      SystemInit
220
#endif
221
        strlt   r0, [r1], #4
222
        blt     .L_loop3
223
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
224
225
#ifndef __NO_SYSTEM_INIT
226
        bl      SystemInit
227
#endif
228
229
#ifndef __START
230
#define __START _start
231
#endif
232
        bl      __START
233
234
        .pool
235
        .size   Reset_Handler, . - Reset_Handler
236
237
        .align  1
238
        .thumb_func
239
        .weak   Default_Handler
240
        .type   Default_Handler, %function
241
Default_Handler:
242
        b       .
243
        .size   Default_Handler, . - Default_Handler
244
245
/*    Macro to define default handlers. Default handler
246
 *    will be weak symbol and just dead loops. They can be
247
 *    overwritten by other handlers */
248
        .macro  def_irq_handler handler_name
249
        .weak   \handler_name
250
        .set    \handler_name, Default_Handler
251
        .endm
252
253
        def_irq_handler NMI_Handler
254
        def_irq_handler HardFault_Handler
255
        def_irq_handler MemManage_Handler
256
        def_irq_handler BusFault_Handler
257
        def_irq_handler UsageFault_Handler
258
        def_irq_handler SVC_Handler
259
        def_irq_handler DebugMon_Handler
260
        def_irq_handler PendSV_Handler
261
        def_irq_handler SysTick_Handler
262
        def_irq_handler DEF_IRQHandler
263
264
        .end

Gruß,
Holm

von Holm T. (Gast)


Lesenswert?

Nico W. schrieb:
> Bis zum SysTick sind die Cortexe auch alle gleich. Daher "fehlt" der
> Rest.

Kann man so auch wieder nicht sagen, es gibt unterschiedliche Sample 
Files,
aber die Interrupts sind halt nicht drin.

Gruß,

Holm

von Niklas G. (erlkoenig) Benutzerseite


Angehängte Dateien:

Lesenswert?

Holm T. schrieb:
> Das war aus dem Beispiel/Template:

Wo hast du das her? Das ist von ARM allgemein für Cortex-M3, da sind 
natürlich keine STM32F103-spezifischen Dinge drin.

Im STM32CubeF1 (wird auch durch STM32CubeMX installiert) gibt es einen 
Ordner

STM32Cube_FW_F1_V1.7.0/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Template 
s/gcc/

mit Dateien Startup-Codes für die diversen STM32F1, z.B. 
startup_stm32f103xb.s, siehe Anhang. Linker-Scripte sind auch dabei.

von Holm T. (Gast)


Lesenswert?

Niklas G. schrieb:
> Holm T. schrieb:
>> Das war aus dem Beispiel/Template:
>
> Wo hast du das her? Das ist von ARM allgemein für Cortex-M3, da sind
> natürlich keine STM32F103-spezifischen Dinge drin.
>
> Im STM32CubeF1 (wird auch durch STM32CubeMX installiert) gibt es einen
> Ordner
>
> STM32Cube_FW_F1_V1.7.0/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Template s/gcc/
>
> mit Dateien Startup-Codes für die diversen STM32F1, z.B.
> startup_stm32f103xb.s, siehe Anhang. Linker-Scripte sind auch dabei.

..hatte ich oben verlinkt, das ist Bestandteil der Toolchain:

https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads

...die ich für FreeBSD portiert habe.

Ich arbeite unter FreeBSD mit den klassischen Programmiertools und eher 
ich irgend ein Cube Zeugs baue, baue ich doch erst mal einen 
funktionierenden gcc samt newlib und binutils...
Ich hätte ja auch nicht genörgelt wenn da irgendwelche hooks für Default 
Handler installiert gewesen wären, so landete der Code aber out of the 
box dort, wo eigentlich die Vectortabelle sein sollte. Dabei gibts da 
Programmbeispiele für CM3 die funktionieren sollten..printf mit 
semihosting etc.. aber ohne jeden Interrupt.

Ich werde mir das Cube Zeugs mal ansehen.

Gruß,

Holm

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Holm T. schrieb:
> ..hatte ich oben verlinkt, das ist Bestandteil der Toolchain:

Achso. Ja, da sind nur allgemeine Sachen für Cortex-M drin, aber 
natürlich keine Startupcodes, Linker-Scripte, Libraries usw. für die 
Unzahl an ARMs.

Holm T. schrieb:
> und eher
> ich irgend ein Cube Zeugs baue, baue ich doch erst mal einen
> funktionierenden gcc samt newlib und binutils...
Da gibts zum Glück nix zu bauen, dank Java läuft STM32CubeMX überall. 
Die Bibliotheken STM32CubeFxx muss man einfach nur runterladen.

Holm T. schrieb:
> Ich hätte ja auch nicht genörgelt wenn da irgendwelche hooks für Default
> Handler installiert gewesen wären, so landete der Code aber out of the
> box dort, wo eigentlich die Vectortabelle sein sollte.

Aber wie soll das denn sonst gehen? Die Vektor-Tabelle hat bei jedem 
Controller eine andere Größe, manchmal sogar Lücken, manche brauchen 
noch einen speziellen "Magic Wert" - wie soll das generische Beispiel 
die alle abdecken?

von Holm T. (Gast)


Lesenswert?

Niklas G. schrieb:
[..]
> Aber wie soll das denn sonst gehen? Die Vektor-Tabelle hat bei jedem
> Controller eine andere Größe, manchmal sogar Lücken, manche brauchen
> noch einen speziellen "Magic Wert" - wie soll das generische Beispiel
> die alle abdecken?

..mit einem selbst zu erstellenden Header und einem Template?

Gruß,
Holm

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Holm T. schrieb:
> ..mit einem selbst zu erstellenden Header und einem Template?

Beim vorgegebenen Startup-Code kannst du doch die fehlenden Handler 
ergänzen oder Platz lassen. Oder wie meinst du das?

von Holm T. (Gast)


Lesenswert?

Niklas G. schrieb:
> Holm T. schrieb:
>> ..mit einem selbst zu erstellenden Header und einem Template?
>
> Beim vorgegebenen Startup-Code kannst du doch die fehlenden Handler
> ergänzen oder Platz lassen. Oder wie meinst du das?

Natürlich habe ich das.
Aber eine Erwähnung in den readme oder Doku Files und ein Beispiel hätte 
doch geholfen? Es gibt übrigens ein Lader File gcc.ld das auch nicht auf 
das Problem hinweist:
1
[..]
2
SECTIONS
3
{
4
        .text :
5
        {
6
                KEEP(*(.isr_vector))
7
                *(.text*)
8
9
                KEEP(*(.init))
10
                KEEP(*(.fini))
11
12
[..]

..Alles bei der Fehlersuche nicht hilfreich.

Gruß,
Holm

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Holm T. schrieb:
> Aber eine Erwähnung in den readme oder Doku Files und ein Beispiel hätte
> doch geholfen?

Die Autoren davon haben vermutlich angenommen, dass jemand, der mit 
einem "nackten" Compiler ohne Hersteller-Libraries & Co anfängt, um das 
Problem des ISR-Vektor weiß. Das GCC-Paket ist eben keine 
Rundum-Sorglos-Lösung. Wenn da im readme alle Fallstricke aufgeführt 
wären, wäre es ziemlich lang!

Wer ein Tutorial für STM32 unter Verwendung gängiger Tools (IDEs) liest, 
wird vermutlich früher oder später etwas über den ISR-Vektor lernen. Wer 
aber alles selber macht (BSD, eigenen Compiler bauen, 
Hersteller-Libraries & Beispiele nicht benutzen) muss sich halt alles 
selbst erarbeiten...

Holm T. schrieb:
> Es gibt übrigens ein Lader File gcc.ld das auch nicht auf
> das Problem hinweist:

Wozu auch? Das "KEEP(*(.isr_vector))" reicht. Der ISR-Vektor muss im 
Startup-Code korrekt definiert sein.

Holm T. schrieb:
> ..Alles bei der Fehlersuche nicht hilfreich.
In der Anleitung zu einer Bohrmaschine steht auch nicht drin, dass der 
Schrank, den du damit zusammenbaust, eine Rückwand braucht. Braucht er 
nämlich auch nicht immer, und nicht jedes ARM-Programm hat einen 
ISR-Vektor, und mit einer Bohrmaschine baut man nicht nur Schränke.

von Holm T. (Gast)


Lesenswert?

Niklas G. schrieb:
> Holm T. schrieb:
>> Aber eine Erwähnung in den readme oder Doku Files und ein Beispiel hätte
>> doch geholfen?
>
> Die Autoren davon haben vermutlich angenommen, dass jemand, der mit
> einem "nackten" Compiler ohne Hersteller-Libraries & Co anfängt, um das
> Problem des ISR-Vektor weiß. Das GCC-Paket ist eben keine
> Rundum-Sorglos-Lösung. Wenn da im readme alle Fallstricke aufgeführt
> wären, wäre es ziemlich lang!
>
> Wer ein Tutorial für STM32 unter Verwendung gängiger Tools (IDEs) liest,
> wird vermutlich früher oder später etwas über den ISR-Vektor lernen. Wer
> aber alles selber macht (BSD, eigenen Compiler bauen,
> Hersteller-Libraries & Beispiele nicht benutzen) muss sich halt alles
> selbst erarbeiten...
>
Meinst Du das BSD ist schuld? Das Paket ist offiziell für MacOSX und 
Linux..

> Holm T. schrieb:
>> Es gibt übrigens ein Lader File gcc.ld das auch nicht auf
>> das Problem hinweist:
>
> Wozu auch? Das "KEEP(*(.isr_vector))" reicht. Der ISR-Vektor muss im
> Startup-Code korrekt definiert sein.

..und .init wird nicht verwendet, schließt aber direkt da an.
Das Startup file hatte ich oben bereits gepostet.

>
> Holm T. schrieb:
>> ..Alles bei der Fehlersuche nicht hilfreich.
> In der Anleitung zu einer Bohrmaschine steht auch nicht drin, dass der
> Schrank, den du damit zusammenbaust, eine Rückwand braucht. Braucht er
> nämlich auch nicht immer, und nicht jedes ARM-Programm hat einen
> ISR-Vektor, und mit einer Bohrmaschine baut man nicht nur Schränke.

In einer BDA zu einer Bohrmaschine steht noch viel mehr drin was Du gar 
nicht wissen willst. Es wird auch darauf hingewiesen das man Strom und 
auch Bohrer braucht und auch die gängigen Arbeitsschutzanweisungen und 
Normen sind Bestandteil der Dokumentation.

Gruß,

Holm

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Holm T. schrieb:
> Meinst Du das BSD ist schuld?

Nein, aber ein Eigenbau-Compiler ist schon weit abseits der gängigen 
Pfade. Man macht es sich deutlich einfacher, z.B. mit Atollic Studio 
unter Windows oder Linux anzufangen.

Holm T. schrieb:
> ..und .init wird nicht verwendet, schließt aber direkt da an.

Doch, da packt der Compiler Initialisierungs-Funktionen hinein, z.B. 
Konstruktoren von globalen C++-Objekten. Kann aber leer sein. Eher 
sinnlos ist .fini, weil Mikrocontroller-Programme sich nicht beenden.

Holm T. schrieb:
> In einer BDA zu einer Bohrmaschine steht noch viel mehr drin was Du gar
> nicht wissen willst.

Das hat aber alles unmittelbar mit der Bohrmaschine zu tun. ISR-Vektoren 
haben nichts mit Compilern zu tun. Lies nicht das Readme vom Compiler, 
sondern STM32-Tutorials.

Das von dir gefundene Beispiel ist vermutlich an Hersteller wie ST 
gerichtet, damit sie auf dessen Basis Beispiele für bestimmte Controller 
wie eben STM32 bauen können.

: Bearbeitet durch User
von Holm T. (Gast)


Lesenswert?

Niklas G. schrieb:
> Holm T. schrieb:
>> Meinst Du das BSD ist schuld?
>
> Nein, aber ein Eigenbau-Compiler ist schon weit abseits der gängigen
> Pfade. Man macht es sich deutlich einfacher, z.B. mit Atollic Studio
> unter Windows oder Linux anzufangen.

Das relativiert sich wenn der Eigenbau Compiler immernoch funktioniert 
trotz dem Microsoft gerade wieder ein Sicherheitsupdate gefahren hat.

>
> Holm T. schrieb:
>> ..und .init wird nicht verwendet, schließt aber direkt da an.
>
> Doch, da packt der Compiler Initialisierungs-Funktionen hinein, z.B.
> Konstruktoren von globalen C++-Objekten. Kann aber leer sein. Eher
> sinnlos ist .fini, weil Mikrocontroller-Programme sich nicht beenden.
>
> Holm T. schrieb:
>> In einer BDA zu einer Bohrmaschine steht noch viel mehr drin was Du gar
>> nicht wissen willst.
>
> Das hat aber alles unmittelbar mit der Bohrmaschine zu tun. ISR-Vektoren
> haben nichts mit Compilern zu tun. Lies nicht das Readme vom Compiler,
> sondern STM32-Tutorials.

Ich habe die von STM mitgelieferte Doku zu den Startup Files, dem 
Linkerscript und zur gesamten Toolchain gelesen bzw. durchsucht.
Nichts desto trotz erweckt der ganze Kram nicht den Eindruck fertig zu 
sein.
>
> Das von dir gefundene Beispiel ist vermutlich an Hersteller wie ST
> gerichtet, damit sie auf dessen Basis Beispiele für bestimmte Controller
> wie eben STM32 bauen können.

Viele der Files haben ein ST Copyright.

Gruß,

Holm

von S. R. (svenska)


Lesenswert?

Du nutzt den falschen Startup-Code.

Wenn du den Controller sinnvoll benutzen willst, dann solltest du auch 
einen zum Controller passenden Startup-Code benutzen und keinen 
allgemeinen, für dich unvollständigen Core.

Du brauchst nur ein paar Dateien von ST.
In meinem Fall (ein STM32L-Discovery) waren das:
- core_cm3.h, core_cmInstr.h und core_cmFunc.h (bisschen Kleinkram)
- stm32l152vb_flash.ld (Linkerscript)
- startup_stm32l1xx_md.S (Startup-Code und ISRs)
- system_stm32l1xx.c (enthält SystemInit() und Taktzeugs)
- system_stm32l1xx.h (gehört zur C-Datei)
- stm32l1xx.h (Registerdefinitionen)

Mehr Fremdcode braucht man in so einem Projekt nicht, um den Controller 
vollständig zu benutzen.

Mit dem von ARM gelieferten Code hast du nichts am Hut, denn was der 
tut, hat ST schon integriert.

von Holm T. (Gast)


Lesenswert?

Laß mal gut sein, mein Zeuch macht das was es soll.

Gruß,

Holm

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.