mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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:

uint8_t disp_buff[32];
[..]
strcpy((char *)disp_buff,"1234");
...

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

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

und damit auch nicht:
uint8_t disp_buff[32];
[..]
char * mstrcpy(char *d, char *s)
{
        while(*s)
                *d++=*s++;
        return d;
}
[..]
mstrcpy((char *)disp_buff,"1234");

[..]

..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:

08002550 <strcpy>:
 8002550:       e1a03000        mov     r3, r0
 8002554:       e4d12001        ldrb    r2, [r1], #1
 8002558:       e4c32001        strb    r2, [r3], #1
 800255c:       e3520000        cmp     r2, #0, 0
 8002560:       1afffffb        bne     8002554 <strcpy+0x4>
 8002564:       e12fff1e        bx      lr

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:
080005a6 <mstrcpy>:
 80005a6:       3901            subs    r1, #1
 80005a8:       f811 3f01       ldrb.w  r3, [r1, #1]!
 80005ac:       b90b            cbnz    r3, 80005b2 <mstrcpy+0xc>
 80005ae:       7800            ldrb    r0, [r0, #0]
 80005b0:       4770            bx      lr
 80005b2:       f800 3b01       strb.w  r3, [r0], #1
 80005b6:       e7f7            b.n     80005a8 <mstrcpy+0x2>

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

Die alte Version des Compilers mach sowas Schickes:
080023f4 <strcpy>:
 80023f4:       e0202001        eor     r2, r0, r1
 80023f8:       e1a0c000        mov     ip, r0
 80023fc:       e3120003        tst     r2, #3, 0
 8002400:       1a000032        bne     80024d0 <strcpy+0xdc>
 8002404:       e3110003        tst     r1, #3, 0
 8002408:       1a000021        bne     8002494 <strcpy+0xa0>
 800240c:       e52d5004        push    {r5}            ; (str r5, [sp, #-4]!)
 8002410:       e3a05001        mov     r5, #1, 0
 8002414:       e1855405        orr     r5, r5, r5, lsl #8
 8002418:       e1855805        orr     r5, r5, r5, lsl #16
 800241c:       e52d4004        push    {r4}            ; (str r4, [sp, #-4]!)
 8002420:       e3110004        tst     r1, #4, 0
 8002424:       e4913004        ldr     r3, [r1], #4
 8002428:       0a000005        beq     8002444 <strcpy+0x50>
 800242c:       e0432005        sub     r2, r3, r5
 8002430:       e1d22003        bics    r2, r2, r3
 8002434:       e1120385        tst     r2, r5, lsl #7
 8002438:       048c3004        streq   r3, [ip], #4
 800243c:       04913004        ldreq   r3, [r1], #4
 8002440:       1a00000c        bne     8002478 <strcpy+0x84>
 8002444:       e4914004        ldr     r4, [r1], #4
 8002448:       e0432005        sub     r2, r3, r5
 800244c:       e1d22003        bics    r2, r2, r3
 8002450:       e1120385        tst     r2, r5, lsl #7
 8002454:       e0442005        sub     r2, r4, r5
 8002458:       1a000006        bne     8002478 <strcpy+0x84>
 800245c:       e48c3004        str     r3, [ip], #4
 8002460:       e1d22004        bics    r2, r2, r4
 8002464:       e1120385        tst     r2, r5, lsl #7
 8002468:       04913004        ldreq   r3, [r1], #4
 800246c:       048c4004        streq   r4, [ip], #4
 8002470:       0afffff3        beq     8002444 <strcpy+0x50>
 8002474:       e1a03004        mov     r3, r4
 8002478:       e4cc3001        strb    r3, [ip], #1
 800247c:       e31300ff        tst     r3, #255, 0     ; 0xff
 8002480:       e1a03463        ror     r3, r3, #8
 8002484:       1afffffb        bne     8002478 <strcpy+0x84>
 8002488:       e49d4004        pop     {r4}            ; (ldr r4, [sp], #4)
 800248c:       e49d5004        pop     {r5}            ; (ldr r5, [sp], #4)
 8002490:       e12fff1e        bx      lr
 8002494:       e3110001        tst     r1, #1, 0
 8002498:       0a000003        beq     80024ac <strcpy+0xb8>
 800249c:       e4d12001        ldrb    r2, [r1], #1
 80024a0:       e4cc2001        strb    r2, [ip], #1
 80024a4:       e3520000        cmp     r2, #0, 0
 80024a8:       012fff1e        bxeq    lr
 80024ac:       e3110002        tst     r1, #2, 0
 80024b0:       0affffd5        beq     800240c <strcpy+0x18>
 80024b4:       e0d120b2        ldrh    r2, [r1], #2
 80024b8:       e31200ff        tst     r2, #255, 0     ; 0xff
 80024bc:       10cc20b2        strhne  r2, [ip], #2
 80024c0:       05cc2000        strbeq  r2, [ip]
 80024c4:       13120cff        tstne   r2, #65280      ; 0xff00
 80024c8:       1affffcf        bne     800240c <strcpy+0x18>
 80024cc:       e12fff1e        bx      lr
 80024d0:       e4d12001        ldrb    r2, [r1], #1
 80024d4:       e4cc2001        strb    r2, [ip], #1
 80024d8:       e3520000        cmp     r2, #0, 0
 80024dc:       1afffffb        bne     80024d0 <strcpy+0xdc>
 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
 
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
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
main.c: In function 'main':
main.c:389:8: warning: variable 'obp' set but not used [-Wunused-but-set-variable]
 char * obp;
        ^~~
main.c:386:8: warning: variable 'sevenths' set but not used [-Wunused-but-set-variable]
 double sevenths;
        ^~~~~~~~
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
[..]
CMSIS Library
[..]
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
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

Autor: Fred (Gast)
Datum:

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

Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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..
 5a:   f24a 52a5       movw    r2, #42405      ; 0xa5a5
  5e:   4291            cmp     r1, r2
  60:   d001            beq.n   66 <main+0x66>
  62:   f7ff fffe       bl      2d0 <eeprom_init>
  66:   6823            ldr     r3, [r4, #0]
  68:   4f31            ldr     r7, [pc, #196]  ; (130 <main+0x130>)
  6a:   8818            ldrh    r0, [r3, #0]
  6c:   f7ff fffe       bl      190 <sevenseg_disp>
  70:   f44f 70fa       mov.w   r0, #500        ; 0x1f4
  74:   f7ff fffe       bl      0 <main>

  78:   492e            ldr     r1, [pc, #184]  ; (134 <main+0x134>)
  7a:   4638            mov     r0, r7
  7c:   f7ff fffe       bl      0 <strcpy>

  80:   492c            ldr     r1, [pc, #176]  ; (134 <main+0x134>)
  82:   4638            mov     r0, r7
  84:   f7ff fffe       bl      406 <mstrcpy>

  88:   7838            ldrb    r0, [r7, #0]
  8a:   463e            mov     r6, r7
  8c:   3830            subs    r0, #48 ; 0x30
  8e:   b283            uxth    r3, r0
  90:   7878            ldrb    r0, [r7, #1]
  92:   4c29            ldr     r4, [pc, #164]  ; (138 <main+0x138>)
  94:   3830            subs    r0, #48 ; 0x30
  96:   b280            uxth    r0, r0


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

Gruß,
Holm

: Bearbeitet durch User
Autor: M.K. B. (mkbit)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
..nein, hab ich noch nicht probiert, sollte allerdings möglich sein...

Gruß,

Holm

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nico W. (nico_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bis zum SysTick sind die Cortexe auch alle gleich. Daher "fehlt" der 
Rest.

: Bearbeitet durch User
Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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
/* File: startup_ARMCM3.S
 * Purpose: startup file for Cortex-M3 devices. Should use with
 *   GCC for ARM Embedded Processors
 * Version: V2.0
 * Date: 16 August 2013
 *
/* Copyright (c) 2011 - 2013 ARM LIMITED

   All rights reserved.
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
   - Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
   - Neither the name of ARM nor the names of its contributors may be used
     to endorse or promote products derived from this software without
     specific prior written permission.
   *
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
   ---------------------------------------------------------------------------*/
        .syntax unified
        .arch   armv7-m

        .section .stack
        .align  3
#ifdef __STACK_SIZE
        .equ    Stack_Size, __STACK_SIZE
#else
        .equ    Stack_Size, 0xc00
#endif
        .globl  __StackTop
        .globl  __StackLimit
__StackLimit:
        .space  Stack_Size
        .size   __StackLimit, . - __StackLimit
__StackTop:
        .size   __StackTop, . - __StackTop

        .section .heap
        .align  3
#ifdef __HEAP_SIZE
        .equ    Heap_Size, __HEAP_SIZE
#else
        .equ    Heap_Size, 0
#endif
        .globl  __HeapBase
        .globl  __HeapLimit
__HeapBase:
        .if     Heap_Size
        .space  Heap_Size
        .endif
        .size   __HeapBase, . - __HeapBase
__HeapLimit:
        .size   __HeapLimit, . - __HeapLimit

        .section .isr_vector
        .align  2
        .globl  __isr_vector
__isr_vector:
        .long   __StackTop            /* Top of Stack */
        .long   Reset_Handler         /* Reset Handler */
        .long   NMI_Handler           /* NMI Handler */
        .long   HardFault_Handler     /* Hard Fault Handler */
        .long   MemManage_Handler     /* MPU Fault Handler */
        .long   BusFault_Handler      /* Bus Fault Handler */
        .long   UsageFault_Handler    /* Usage Fault Handler */
        .long   0                     /* Reserved */
        .long   0                     /* Reserved */
        .long   0                     /* Reserved */
        .long   0                     /* Reserved */
        .long   SVC_Handler           /* SVCall Handler */
        .long   DebugMon_Handler      /* Debug Monitor Handler */
        .long   0                     /* Reserved */
        .long   PendSV_Handler        /* PendSV Handler */
        .long   SysTick_Handler       /* SysTick Handler */

        /* External interrupts */
        .long   Default_Handler

        .size   __isr_vector, . - __isr_vector

        .text
        .thumb
        .thumb_func
        .align  2
        .globl  Reset_Handler
        .type   Reset_Handler, %function
Reset_Handler:
/*  Firstly it copies data from read only memory to RAM. There are two schemes
 *  to copy. One can copy more than one sections. Another can only copy
 *  one section.  The former scheme needs more instructions and read-only
 *  data to implement than the latter.
 *  Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes.  */

#ifdef __STARTUP_COPY_MULTIPLE
/*  Multiple sections scheme.
 *
 *  Between symbol address __copy_table_start__ and __copy_table_end__,
 *  there are array of triplets, each of which specify:
 *    offset 0: LMA of start of a section to copy from
 *    offset 4: VMA of start of a section to copy to
 *    offset 8: size of the section to copy. Must be multiply of 4
 *
 *  All addresses must be aligned to 4 bytes boundary.
 */
        ldr     r4, =__copy_table_start__
        ldr     r5, =__copy_table_end__

.L_loop0:
        cmp     r4, r5
        bge     .L_loop0_done
        ldr     r1, [r4]
        ldr     r2, [r4, #4]
        ldr     r3, [r4, #8]

.L_loop0_0:
        subs    r3, #4
        ittt    ge
        ldrge   r0, [r1, r3]
        strge   r0, [r2, r3]
        bge     .L_loop0_0

        adds    r4, #12
        b       .L_loop0

.L_loop0_done:
#else
/*  Single section scheme.
 *
 *  The ranges of copy from/to are specified by following symbols
 *    __etext: LMA of start of the section to copy from. Usually end of text
 *    __data_start__: VMA of start of the section to copy to
 *    __data_end__: VMA of end of the section to copy to
 *
 *  All addresses must be aligned to 4 bytes boundary.
 */
        ldr     r1, =__etext
        ldr     r2, =__data_start__
        ldr     r3, =__data_end__

.L_loop1:
        cmp     r2, r3
        ittt    lt
        ldrlt   r0, [r1], #4
        strlt   r0, [r2], #4
        blt     .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */

/*  This part of work usually is done in C library startup code. Otherwise,
 *  define this macro to enable it in this startup.
 *
 *  There are two schemes too. One can clear multiple BSS sections. Another
 *  can only clear one section. The former is more size expensive than the
 *  latter.
 *
 *  Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
 *  Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
 */
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/*  Multiple sections scheme.
 *
 *  Between symbol address __copy_table_start__ and __copy_table_end__,
 *  there are array of tuples specifying:
 *    offset 0: Start of a BSS section
 *    offset 4: Size of this BSS section. Must be multiply of 4
 */
        ldr     r3, =__zero_table_start__
        ldr     r4, =__zero_table_end__

.L_loop2:
        cmp     r3, r4
        bge     .L_loop2_done
        ldr     r1, [r3]
        ldr     r2, [r3, #4]
        movs    r0, 0

.L_loop2_0:
        subs    r2, #4
        itt     ge
        strge   r0, [r1, r2]
        bge     .L_loop2_0

        adds    r3, #8
        b       .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/*  Single BSS section scheme.
 *
 *  The BSS section is specified by following symbols
 *    __bss_start__: start of the BSS section.
 *    __bss_end__: end of the BSS section.
 *
 *  Both addresses must be aligned to 4 bytes boundary.
 */
        ldr     r1, =__bss_start__
        ldr     r2, =__bss_end__

        movs    r0, 0
.L_loop3:
        cmp     r1, r2
        itt     lt
        strlt   r0, [r1], #4
        blt     .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */

#ifndef __NO_SYSTEM_INIT
        bl      SystemInit
#endif
        strlt   r0, [r1], #4
        blt     .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */

#ifndef __NO_SYSTEM_INIT
        bl      SystemInit
#endif

#ifndef __START
#define __START _start
#endif
        bl      __START

        .pool
        .size   Reset_Handler, . - Reset_Handler

        .align  1
        .thumb_func
        .weak   Default_Handler
        .type   Default_Handler, %function
Default_Handler:
        b       .
        .size   Default_Handler, . - Default_Handler

/*    Macro to define default handlers. Default handler
 *    will be weak symbol and just dead loops. They can be
 *    overwritten by other handlers */
        .macro  def_irq_handler handler_name
        .weak   \handler_name
        .set    \handler_name, Default_Handler
        .endm

        def_irq_handler NMI_Handler
        def_irq_handler HardFault_Handler
        def_irq_handler MemManage_Handler
        def_irq_handler BusFault_Handler
        def_irq_handler UsageFault_Handler
        def_irq_handler SVC_Handler
        def_irq_handler DebugMon_Handler
        def_irq_handler PendSV_Handler
        def_irq_handler SysTick_Handler
        def_irq_handler DEF_IRQHandler

        .end


Gruß,
Holm

: Bearbeitet durch User
Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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

: Bearbeitet durch User
Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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:
[..]
SECTIONS
{
        .text :
        {
                KEEP(*(.isr_vector))
                *(.text*)

                KEEP(*(.init))
                KEEP(*(.fini))

[..]

..Alles bei der Fehlersuche nicht hilfreich.

Gruß,
Holm

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht 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

Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holm T. (holm)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Laß mal gut sein, mein Zeuch macht das was es soll.

Gruß,

Holm

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.