LibOpenCM3 mit C++ verwenden
Jetzt wo ich einen schönen Open Source Debugging-Setup für STM32 Mikrocontroller habe, ist der letzte Schritt zu vollständiger Open Source Entwicklung, die von ST mitgelieferten Bibliotheken durch die Open Source Biliothek libopencm3 zu ersetzen.
Checkout und erste Anpassungen
Als Ausgangspunkt für meine Experimente verwende ich das offizielle “Hello-World” von libopencm3: Das libopencm3-miniblink!
Submakefiles
Das Projekt baut alle Targets auf einmal, das brauche ich nicht. Ich will nur genau ein Target. Zunächst lösche ich alle Submakefiles bis auf boards.stm32.mk. In boards.stm32.mk lösche ich alles was nicht zum STM32F103C8T6 passt (Cortex M3, Familie STM32F1). Und dort lasse ich spezifisch den Teil für die “Bluepill” (GPIOC, GIPIO13) stehen.
Dann sieht das boards.stm32.mk Makefile nur noch so aus:
LFLAGS_STM32=$(LFLAGS) template_stm32.c -T ld.stm32.basic
# STM32F1 starts up with HSI at 8Mhz
STM32F1_CFLAGS=$(M3_FLAGS) -DSTM32F1 -DLITTLE_BIT=200000 $(LFLAGS_STM32) -lopencm3_stm32f1
define RAWMakeBoard
mkdir -p $(OD)/$(7)
$(CC) -DRCC_LED1=RCC_$(1) -DPORT_LED1=$(1) -DPIN_LED1=$(2) \
$(if $(5),-DRCC_LED2=RCC_$(5) -DPORT_LED2=$(5) -DPIN_LED2=$(6),) \
$(3) -o $(OD)/$(7)/$(4)
endef
define MakeBoard
BOARDS_ELF+=$(OD)/$(5)/$(1).elf
BOARDS_BIN+=$(OD)/$(5)/$(1).bin
BOARDS_HEX+=$(OD)/$(5)/$(1).hex
$(OD)/$(5)/$(1).elf: template_stm32.c libopencm3/lib/libopencm3_$(5).a
@echo " $(5) -> Creating $(OD)/$(5)/$(1).elf"
$(call RAWMakeBoard,$(2),$(3),$(4),$(1).elf,$(6),$(7),$(5))
endef
define stm32f1board
$(call MakeBoard,$(1),$(2),$(3),$(STM32F1_CFLAGS),stm32f1,$(4),$(5))
endef
# STM32F1 boards
$(eval $(call stm32f1board,bluepill,GPIOC,GPIO13))
Jetzt einmal testweise bauen… Clont erstmal das libopencm3 Projekt… sehr langer build Prozess… Am Ende genau das eine, erwartete Binary
make clean make –> Deutlich scneller. Offenbar wurde beim erstenmal die kompllette libopencm3 gebaut.
Dann noch die ganzen .ld und .c Dateien zu den anderen Boards löschen… –> Baut weiterhin.
Einzelmakefile.
Die ganzen Methoden in dem gekürzten Makefile kann ich jetzt noch direkt auflösen. (Und dabei direkt das schreiben des stm32f1 Unterordners unterlassen, weil es ja nur noch das eine Target gibt.) Dann lande ich bei:
LFLAGS_STM32=$(LFLAGS) template_stm32.c -T ld.stm32.basic
# STM32F1 starts up with HSI at 8Mhz
STM32F1_CFLAGS=$(M3_FLAGS) -DSTM32F1 -DLITTLE_BIT=200000 $(LFLAGS_STM32) -lopencm3_stm32f1
BOARD = bluepill
FAMILY = stm32f1
BOARDS_ELF+=$(OD)/$(BOARD).elf
BOARDS_BIN+=$(OD)/$(BOARD).bin
BOARDS_HEX+=$(OD)/$(BOARD).hex
$(OD)/$(BOARD).elf: template_stm32.c libopencm3/lib/libopencm3_$(FAMILY).a
@echo " $(FAMILY) -> Creating $(OD)/$(BOARD).elf"
mkdir -p $(OD)
$(CC) -DRCC_LED1=RCC_GPIOC -DPORT_LED1=GPIOC -DPIN_LED1=GPIO13 \
$(STM32F1_CFLAGS) -o $(OD)/$(BOARD).elf
IntelliSense (SyntaxHighlighting in VSCode)
Funktioniert nicht komplett out of the Box. Die Defines im Makefile werden nicht erkannt. Lösung: Makefile doch wieder per bear ausführen (tasks.json anpassen), und dann bei IntelliSense hinterlegen, wo die compile_commands.json liegt:
c_cpp_properties.json
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools",
"compileCommands": [
"${workspaceFolder}/compile_commands.json"
]
}
],
"version": 4
}
(Quelle: https://code.visualstudio.com/docs/cpp/configure-intellisense)
C-Datei anpassen
Hier sind noch ein paar Makros die in meinem Single-Board Setup nicht mehr gebraucht werden. Die lösche ich raus:
- #if defined(RCC_LED2) –> Weg weil kommt nicht vor.
- #if defined(STM32F1) –> Dauerhaft an, also der #else Zweig weg.
Und damit habe ich dann das sehr überschaubare C-file:
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
int main(void) {
rcc_periph_clock_enable(RCC_LED1);
gpio_set_mode(PORT_LED1, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, PIN_LED1);
gpio_set(PORT_LED1, PIN_LED1);
while(1) {
/* wait a little bit */
for (int i = 0; i < LITTLE_BIT; i++) {
__asm__("nop");
}
gpio_toggle(PORT_LED1, PIN_LED1);
}
}
Testen:
Funktioniert es?
Umbau auf C++
Makefile
Um das ganze dann als C++ zu kompilieren, habe ich das Makefile um den folgenden Block ergänzt:
## C++ Settings / overrides:
SFLAGS_CPP= --static -nostartfiles -g3 -Os
SFLAGS_CPP+= -fno-common -ffunction-sections -fdata-sections
SFLAGS_CPP+= -I./libopencm3/include -L./libopencm3/lib
LFLAGS_CPP+=-Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
CPP_FLAGS_ADDITIONAL= -fno-exceptions
# Actual overrides (comment out, to switch back to C):
M3_FLAGS = $(SFLAGS_CPP) -mcpu=cortex-m3 -mthumb -msoft-float
CC=$(PREFIX)g++
LFLAGS_STM32=$(LFLAGS_CPP) template_stm32.c -T ld.stm32.basic $(CPP_FLAGS_ADDITIONAL)
## End of C++ overrides
An tatsächlicher Änderung bedeutet das:
- Die -std=c11 Einstellung fällt weg.
- Das -fno-exceptions Flag kommt hinzu.
- Der Compiler wird von gcc auf g++ umgestellt.
Mit diesen Änderungen ist das Projekt direkt wieder kompilierbar. Sowohl mit C als auch C++ erhalte ich:
arm-none-eabi-size bin/bluepill.elf
text data bss dec hex filename
1028 0 0 1028 404 bin/bluepill.elf
Bzw.:
wombat@T470s:~/VSCode/libopencm3-miniblink$ du -b bin/bluepill.hex
2952 bin/bluepill.hex
C- bzw. CPP-Datei
Dann habe ich mein Minimalset an C++-exklusiven Sprachelementen in die template_stm32.c integriert:
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <vector>
int main(void) {
rcc_periph_clock_enable(RCC_LED1);
gpio_set_mode(PORT_LED1, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, PIN_LED1);
gpio_set(PORT_LED1, PIN_LED1);
std::vector<bool> ledmuster {true, false, true, false, true, false, false, false, false};
while(1) {
for(auto ledstate : ledmuster){
if(!ledstate) {
// SET -> LED ist aus; RESET -> LED ist an.
gpio_set(PORT_LED1, PIN_LED1);
} else {
gpio_clear(PORT_LED1, PIN_LED1);
}
/* wait a little bit */
for (int i = 0; i < LITTLE_BIT; i++) {
__asm__("nop");
}
}
}
}
Beim bauen bekomme ich dann den Fehler:
/usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/lib/thumb/v7-m/nofp/libc.a(libc_a-signalr.o): in function `_getpid_r':
/build/reproducible-path/newlib-4.5.0.20241231/build/arm-none-eabi/thumb/v7-m/nofp/newlib/../../../../../../newlib/libc/reent/signalr.c:83:(.text+0x28): undefined reference to `_getpid'
/usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/bin/ld: (_getpid): Unknown destination type (ARM/Thumb) in /usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/lib/thumb/v7-m/nofp/libc.a(libc_a-signalr.o)
/build/reproducible-path/newlib-4.5.0.20241231/build/arm-none-eabi/thumb/v7-m/nofp/newlib/../../../../../../newlib/libc/reent/signalr.c:83:(.text+0x28): dangerous relocation: unsupported relocation
collect2: error: ld returned 1 exit status
Und einige weitere Fehler dieser Art zu Methoden wie “_exit”, “_sbrk_r”, “_write”, “_close” etc. Dies lies sich, durch das zusätliche Linker-Setting “–specs=nosys.specs” verbessern. Dadurch wurden aus den Fehlern Warnungen:
/usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/lib/thumb/v7-m/nofp/libc.a(libc_a-signalr.o): in function `_getpid_r':
/build/reproducible-path/newlib-4.5.0.20241231/build/arm-none-eabi/thumb/v7-m/nofp/newlib/../../../../../../newlib/libc/reent/signalr.c:83:(.text+0x28): warning: _getpid is not implemented and will always fail
Das sollte ich mir später nochmal genauer anschauen.
Außerdem hatte ich am Anfang des Logs den Hinweis:
/usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/bin/ld: bin/bluepill.elf section `.text' will not fit in region `rom'
/usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/bin/ld: region `rom' overflowed by 10824 bytes
Um das zu vermeiden, passe ich die Datei “ld.stm32.basic” an.
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 2K
}
Hier ändere ich den Minimalkonsens, der für alle STM32 passt und für eine blinkende LED in C ausreicht, auf die tatsächlichen Werte des STM32F103C8T6: 64kB ROM und 20kB RAM. Damit lässt sich das Programm dann vollständig bauen. Es lässt sich auch auf einen echten Mikrocontroller übertragen und funktioniert erwartungsgemäß.
Optimierungen
Nun gilt es einerseits die oben genannten Warnungen loszuwerden. Außerdem ist das Binary (für eine einfache, blinkende LED) extrem groß:
arm-none-eabi-size bin/bluepill.elf
text data bss dec hex filename
17744 1400 412 19556 4c64 bin/bluepill.elf
du -b bin/bluepill.hex
53926 bin/bluepill.hex
Mit einem einfachen Kommandozeilenaufruf (entnommen aus diesem Stackoverflow Post) lassen sich sämtliche Funktionen in der ELF-Datei auflisten:
readelf -sW bin/bluepill.elf | awk '$4 == "FUNC"' | c++filt
Hier passieren drei Dinge:
- readelf öffnet die ELF-Datei, -s zeigt die Symbole an, und -W sorgt dafür, dass lange Namen nicht abgeschnitten werden.
- awk ‘$4 == “FUNC”’ filtert, sodass nur Zeilen angezeigt werden, bei denen in der vierten Spalte “FUNC” steht.
- c++filt sorgt dafür, dass die Namen ordentlich angezeigt werden. (Z.B.: “std::type_info::__do_catch(std::type_info const*, void**, unsigned int) const “ statt “_ZNKSt9type_info10__do_catchEPKS_PPvj”)
Die Liste die so entsteht ist lang:
Symbol table '.symtab' contains 874 entries:
Num: Value Size Type Bind Vis Ndx Name
87: 080004e9 136 FUNC LOCAL DEFAULT 1 (anonymous namespace)::pool::free(void*) [clone .constprop.0]
92: 08000571 92 FUNC LOCAL DEFAULT 1 (anonymous namespace)::pool::allocate(unsigned int) [clone .constprop.0]
110: 0800067d 240 FUNC LOCAL DEFAULT 1 _GLOBAL__sub_I__ZN9__gnu_cxx9__freeresEv
184: 08000885 68 FUNC LOCAL DEFAULT 1 __gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Control_Block*)
283: 08000dad 192 FUNC LOCAL DEFAULT 1 read_encoded_value_with_base(unsigned char, unsigned int, unsigned char const*, unsigned int*)
287: 08000e6d 66 FUNC LOCAL DEFAULT 1 base_of_encoded_value(unsigned char, _Unwind_Context*)
291: 08000eb1 144 FUNC LOCAL DEFAULT 1 parse_lsda_header(_Unwind_Context*, unsigned char const*, lsda_header_info*)
315: 08001551 58 FUNC LOCAL DEFAULT 1 __cxxabiv1::__is_gxx_exception_class(char*)
336: 08001825 308 FUNC LOCAL DEFAULT 1 _strtoul_l.isra.0
344: 08001995 4 FUNC LOCAL DEFAULT 1 __fp_lock
345: 08001999 24 FUNC LOCAL DEFAULT 1 stdio_exit_handler
348: 080019b1 64 FUNC LOCAL DEFAULT 1 cleanup_stdio
351: 080019f1 4 FUNC LOCAL DEFAULT 1 __fp_unlock
352: 080019f5 208 FUNC LOCAL DEFAULT 1 global_stdio_init.part.0
454: 08002e4d 18 FUNC LOCAL DEFAULT 1 selfrel_offset31
456: 08002e61 98 FUNC LOCAL DEFAULT 1 search_EIT_table
457: 08002ec5 40 FUNC LOCAL DEFAULT 1 __gnu_unwind_get_pr_addr
460: 08002eed 152 FUNC LOCAL DEFAULT 1 get_eit_entry
463: 08002f85 88 FUNC LOCAL DEFAULT 1 restore_non_core_regs
464: 08002fdd 10 FUNC LOCAL DEFAULT 1 _Unwind_decode_typeinfo_ptr.constprop.0
465: 08002fe9 2 FUNC LOCAL DEFAULT 1 _Unwind_DebugHook
466: 08002fed 60 FUNC LOCAL DEFAULT 1 unwind_phase2
467: 08003029 218 FUNC LOCAL DEFAULT 1 unwind_phase2_forced
471: 0800322d 26 FUNC LOCAL DEFAULT 1 _Unwind_GetGR
474: 0800327d 24 FUNC LOCAL DEFAULT 1 _Unwind_SetGR
475: 08003321 680 FUNC LOCAL DEFAULT 1 __gnu_unwind_pr_common
484: 08003a65 56 FUNC LOCAL DEFAULT 1 next_unwind_byte
486: 08003a9d 26 FUNC LOCAL DEFAULT 1 _Unwind_GetGR.constprop.0
487: 08003ab9 2 FUNC LOCAL DEFAULT 1 unwind_UCB_from_context
523: 08000615 32 FUNC GLOBAL DEFAULT 1 __cxa_free_exception
524: 08003a1d 34 FUNC GLOBAL HIDDEN 1 ___Unwind_ForcedUnwind
525: 08003109 106 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_RaiseException
526: 08000b05 4 FUNC GLOBAL DEFAULT 1 std::type_info::__is_function_p() const
527: 08000801 20 FUNC GLOBAL DEFAULT 1 std::unexpected()
528: 08003f15 16 FUNC GLOBAL DEFAULT 1 _getpid
529: 080007a5 2 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__forced_unwind::~__forced_unwind()
530: 08002dc9 44 FUNC GLOBAL DEFAULT 1 _lseek_r
531: 080002bf 6 FUNC GLOBAL DEFAULT 1 gpio_port_read
532: 080003dd 148 FUNC WEAK DEFAULT 1 reset_handler
533: 08000945 110 FUNC GLOBAL DEFAULT 1 __cxa_rethrow
534: 0800084d 40 FUNC GLOBAL DEFAULT 1 std::set_unexpected(void (*)())
535: 08002e21 40 FUNC GLOBAL DEFAULT 1 _kill_r
536: 080004b5 20 FUNC GLOBAL DEFAULT 1 std::bad_alloc::~bad_alloc()
537: 08002ce5 28 FUNC GLOBAL DEFAULT 1 sysconf
538: 080003d9 2 FUNC WEAK DEFAULT 1 usart3_isr
539: 080013c1 0 FUNC GLOBAL DEFAULT 1 __cxa_end_cleanup
540: 080003d9 2 FUNC WEAK DEFAULT 1 rtc_isr
541: 080029b9 78 FUNC GLOBAL DEFAULT 1 _signal_r
542: 080027c1 34 FUNC GLOBAL DEFAULT 1 __sseek
543: 08001b69 32 FUNC GLOBAL DEFAULT 1 __sinit
544: 080003d9 2 FUNC WEAK DEFAULT 1 tim7_isr
545: 0800065d 32 FUNC GLOBAL DEFAULT 1 __cxa_free_dependent_exception
546: 080009e5 20 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__si_class_type_info::~__si_class_type_info()
548: 08002575 2 FUNC GLOBAL DEFAULT 1 __malloc_unlock
549: 080003d9 2 FUNC WEAK DEFAULT 1 adc1_2_isr
550: 080007a5 2 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__forced_unwind::~__forced_unwind()
551: 08000d81 16 FUNC GLOBAL DEFAULT 1 std::uncaught_exception()
552: 080003d9 2 FUNC WEAK DEFAULT 1 tim1_trg_com_isr
553: 080038d9 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Save_VFP
554: 0800076d 2 FUNC GLOBAL DEFAULT 1 std::exception::~exception()
555: 080039f9 34 FUNC GLOBAL HIDDEN 1 _Unwind_Resume_or_Rethrow
557: 080003d9 2 FUNC WEAK DEFAULT 1 usb_hp_can_tx_isr
558: 080035c9 4 FUNC GLOBAL HIDDEN 1 __aeabi_unwind_cpp_pr0
560: 08002d6d 12 FUNC GLOBAL DEFAULT 1 __errno
561: 08000279 20 FUNC GLOBAL DEFAULT 1 gpio_primary_remap
563: 08003ded 10 FUNC GLOBAL HIDDEN 1 _Unwind_GetRegionStart
564: 08001699 28 FUNC GLOBAL DEFAULT 1 getenv
565: 080039f9 34 FUNC GLOBAL HIDDEN 1 ___Unwind_Resume_or_Rethrow
567: 080003d9 2 FUNC WEAK DEFAULT 1 tim6_isr
568: 0800277d 4 FUNC GLOBAL DEFAULT 1 __seofread
570: 080001fd 106 FUNC GLOBAL DEFAULT 1 gpio_set_mode
571: 080003d9 2 FUNC WEAK DEFAULT 1 usb_wakeup_isr
572: 08003a41 34 FUNC GLOBAL HIDDEN 1 _Unwind_Backtrace
573: 080003d9 2 FUNC GLOBAL DEFAULT 1 blocking_handler
574: 080003d9 2 FUNC WEAK DEFAULT 1 tim5_isr
575: 0800147d 100 FUNC GLOBAL DEFAULT 1 __cxa_begin_cleanup
576: 080003d9 2 FUNC WEAK DEFAULT 1 otg_fs_isr
577: 080038b9 24 FUNC GLOBAL HIDDEN 1 __restore_core_regs
578: 080038f9 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Save_VFP_D_16_to_31
579: 080003d9 2 FUNC WEAK DEFAULT 1 spi1_isr
580: 080015a9 220 FUNC GLOBAL DEFAULT 1 __cxa_call_unexpected
581: 08000c75 4 FUNC GLOBAL DEFAULT 1 __cxa_get_exception_ptr
582: 08003105 4 FUNC GLOBAL HIDDEN 1 _Unwind_GetCFA
583: 08000815 40 FUNC GLOBAL DEFAULT 1 std::set_terminate(void (*)())
584: 08003e19 236 FUNC GLOBAL DEFAULT 1 memcpy
585: 080003d9 2 FUNC WEAK DEFAULT 1 exti2_isr
586: 080003d9 2 FUNC WEAK DEFAULT 1 dma1_channel6_isr
587: 08000635 40 FUNC GLOBAL DEFAULT 1 __cxa_allocate_dependent_exception
588: 08003249 52 FUNC GLOBAL HIDDEN 1 _Unwind_VRS_Set
589: 080003db 2 FUNC GLOBAL DEFAULT 1 null_handler
590: 08000ba9 12 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::__do_find_public_src(int, void const*, __cxxabiv1::__class_type_info const*, void const*) const
591: 08000bb5 20 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::~__class_type_info()
592: 080003d9 2 FUNC WEAK DEFAULT 1 can_rx1_isr
594: 080003d9 2 FUNC WEAK DEFAULT 1 dma1_channel5_isr
595: 080002ad 18 FUNC GLOBAL DEFAULT 1 gpio_toggle
596: 080024c1 16 FUNC GLOBAL DEFAULT 1 malloc
597: 08002a09 82 FUNC GLOBAL DEFAULT 1 _raise_r
598: 080003d9 2 FUNC WEAK DEFAULT 1 dma2_channel5_isr
599: 080003d9 2 FUNC WEAK DEFAULT 1 usart1_isr
601: 08002e49 4 FUNC GLOBAL DEFAULT 1 _getpid_r
602: 08003295 140 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Backtrace
603: 08001979 28 FUNC GLOBAL DEFAULT 1 strtoul
604: 08000d91 10 FUNC GLOBAL DEFAULT 1 std::uncaught_exceptions()
605: 080005cd 24 FUNC GLOBAL DEFAULT 1 __gnu_cxx::__freeres()
606: 080014e1 112 FUNC GLOBAL DEFAULT 1 __gnu_end_cleanup
607: 08000c45 42 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::__do_catch(std::type_info const*, void**, unsigned int) const
608: 08002a5d 102 FUNC GLOBAL DEFAULT 1 __sigtramp_r
609: 080002d9 8 FUNC GLOBAL DEFAULT 1 rcc_peripheral_enable_clock
610: 08002579 36 FUNC GLOBAL DEFAULT 1 _sbrk_r
611: 08000775 8 FUNC GLOBAL DEFAULT 1 transaction clone for std::exception::what() const
612: 080038e9 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Save_VFP_D
614: 080003d9 2 FUNC WEAK DEFAULT 1 usage_fault_handler
615: 080003d9 2 FUNC WEAK DEFAULT 1 tim8_trg_com_isr
616: 080003d9 2 FUNC WEAK DEFAULT 1 can2_rx0_isr
617: 08002df5 44 FUNC GLOBAL DEFAULT 1 _read_r
618: 08000775 8 FUNC GLOBAL DEFAULT 1 std::exception::what() const
619: 080003d9 2 FUNC WEAK DEFAULT 1 tim1_brk_isr
620: 080035d5 740 FUNC GLOBAL HIDDEN 1 _Unwind_VRS_Pop
621: 08001bb9 128 FUNC GLOBAL DEFAULT 1 _fclose_r
622: 080035d1 4 FUNC WEAK HIDDEN 1 __aeabi_unwind_cpp_pr2
624: 08002941 72 FUNC GLOBAL DEFAULT 1 fflush
626: 08003a41 34 FUNC GLOBAL HIDDEN 1 ___Unwind_Backtrace
627: 08000269 16 FUNC GLOBAL DEFAULT 1 gpio_set_eventout
630: 080003d9 2 FUNC WEAK DEFAULT 1 can2_rx1_isr
631: 08000c29 26 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::__do_upcast(__cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__upcast_result&) const
632: 08000c71 4 FUNC GLOBAL DEFAULT 1 operator delete(void*)
633: 080009d5 16 FUNC GLOBAL DEFAULT 1 std::get_new_handler()
634: 080003d9 2 FUNC WEAK DEFAULT 1 tim1_cc_isr
635: 080002fd 26 FUNC GLOBAL DEFAULT 1 rcc_periph_clock_enable
636: 080039b1 34 FUNC GLOBAL HIDDEN 1 ___Unwind_RaiseException
637: 08001c49 14 FUNC GLOBAL DEFAULT 1 abort
638: 080039d5 34 FUNC GLOBAL HIDDEN 1 ___Unwind_Resume
639: 08003f55 28 FUNC GLOBAL DEFAULT 1 _sbrk
640: 080003d9 2 FUNC WEAK DEFAULT 1 sdio_isr
641: 08000cf9 136 FUNC GLOBAL DEFAULT 1 __cxa_end_catch
642: 08001b91 20 FUNC GLOBAL DEFAULT 1 __fp_lock_all
643: 08000771 2 FUNC GLOBAL DEFAULT 1 std::bad_exception::~bad_exception()
644: 080003d9 2 FUNC WEAK DEFAULT 1 eth_isr
645: 08000355 4 FUNC GLOBAL DEFAULT 1 rcc_periph_reset_hold
646: 080003d9 2 FUNC WEAK DEFAULT 1 dma1_channel4_isr
647: 080003d9 2 FUNC WEAK DEFAULT 1 tim8_brk_isr
648: 080003d9 2 FUNC WEAK DEFAULT 1 dma2_channel4_5_isr
649: 080007e5 20 FUNC GLOBAL DEFAULT 1 std::terminate()
650: 08003901 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Restore_WMMXD
652: 080007b9 2 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__foreign_exception::~__foreign_exception()
653: 08002d01 108 FUNC GLOBAL DEFAULT 1 _reclaim_reent
655: 080003d9 2 FUNC WEAK DEFAULT 1 pvd_isr
656: 08000f41 1152 FUNC GLOBAL DEFAULT 1 __gxx_personality_v0
658: 08000371 40 FUNC GLOBAL DEFAULT 1 rcc_osc_bypass_enable
659: 080003c1 24 FUNC GLOBAL DEFAULT 1 rcc_get_div_from_hpre
660: 08000b01 2 FUNC GLOBAL DEFAULT 1 std::type_info::~type_info()
662: 080007b9 2 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__foreign_exception::~__foreign_exception()
663: 080002c9 16 FUNC GLOBAL DEFAULT 1 gpio_port_config_lock
664: 08000b0d 14 FUNC GLOBAL DEFAULT 1 std::type_info::~type_info()
666: 080004e5 4 FUNC GLOBAL DEFAULT 1 operator delete(void*, unsigned int)
667: 080003db 2 FUNC WEAK DEFAULT 1 sv_call_handler
668: 080003d9 2 FUNC WEAK DEFAULT 1 rcc_isr
670: 08000b09 4 FUNC GLOBAL DEFAULT 1 std::type_info::__do_upcast(__cxxabiv1::__class_type_info const*, void**) const
671: 080038d1 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Restore_VFP
672: 080008c9 68 FUNC GLOBAL DEFAULT 1 __cxa_init_primary_exception
673: 080003d9 2 FUNC WEAK DEFAULT 1 flash_isr
674: 0800083d 16 FUNC GLOBAL DEFAULT 1 std::get_terminate()
677: 080003d9 2 FUNC WEAK DEFAULT 1 uart4_isr
678: 08000b49 44 FUNC GLOBAL DEFAULT 1 std::type_info::__equal(std::type_info const&) const
679: 080003d9 2 FUNC WEAK DEFAULT 1 rtc_alarm_isr
680: 080003d9 2 FUNC WEAK DEFAULT 1 exti15_10_isr
681: 080039d5 34 FUNC GLOBAL HIDDEN 1 _Unwind_Resume
682: 080031ed 12 FUNC GLOBAL HIDDEN 1 _Unwind_DeleteException
683: 080031e9 2 FUNC GLOBAL HIDDEN 1 _Unwind_Complete
684: 08000be5 66 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::__do_dyncast(int, __cxxabiv1::__class_type_info::__sub_kind, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__dyncast_result&) const
685: 08000b75 52 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::__do_upcast(__cxxabiv1::__class_type_info const*, void**) const
686: 08001b89 2 FUNC GLOBAL DEFAULT 1 __sfp_lock_acquire
688: 080003d9 2 FUNC WEAK DEFAULT 1 hard_fault_handler
689: 080003d9 2 FUNC WEAK DEFAULT 1 exti1_isr
690: 0800226d 504 FUNC GLOBAL DEFAULT 1 _free_r
691: 080002a7 6 FUNC GLOBAL DEFAULT 1 gpio_get
692: 080003d9 2 FUNC WEAK DEFAULT 1 i2c1_ev_isr
693: 08000333 34 FUNC GLOBAL DEFAULT 1 rcc_periph_reset_pulse
694: 080003d9 2 FUNC WEAK DEFAULT 1 dma2_channel1_isr
696: 080003db 2 FUNC WEAK DEFAULT 1 pend_sv_handler
698: 080004ad 8 FUNC GLOBAL DEFAULT 1 std::bad_alloc::what() const
699: 08003f35 16 FUNC GLOBAL DEFAULT 1 _lseek
701: 080003d9 2 FUNC WEAK DEFAULT 1 spi2_isr
702: 08002b1d 80 FUNC GLOBAL DEFAULT 1 signal
703: 08003abd 766 FUNC GLOBAL HIDDEN 1 __gnu_unwind_execute
705: 0800077d 8 FUNC GLOBAL DEFAULT 1 transaction clone for std::bad_exception::what() const
706: 08002c59 138 FUNC GLOBAL DEFAULT 1 strncmp
707: 08000a51 132 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__si_class_type_info::__do_dyncast(int, __cxxabiv1::__class_type_info::__sub_kind, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__dyncast_result&) const
708: 080038e1 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Restore_VFP_D
709: 080003d9 2 FUNC WEAK DEFAULT 1 tim8_up_isr
710: 08000359 4 FUNC GLOBAL DEFAULT 1 rcc_periph_reset_release
711: 080002eb 8 FUNC GLOBAL DEFAULT 1 rcc_peripheral_reset
714: 080013cd 176 FUNC GLOBAL DEFAULT 1 __cxa_type_match
715: 08000b01 2 FUNC GLOBAL DEFAULT 1 std::type_info::~type_info()
716: 080007bd 14 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__foreign_exception::~__foreign_exception()
717: 08000ad5 42 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__si_class_type_info::__do_upcast(__cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__upcast_result&) const
718: 08001959 2 FUNC GLOBAL DEFAULT 1 _strtoul_r
719: 08003189 64 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Resume
721: 08002da5 36 FUNC GLOBAL DEFAULT 1 _close_r
722: 080002e1 10 FUNC GLOBAL DEFAULT 1 rcc_peripheral_disable_clock
723: 080003d9 2 FUNC WEAK DEFAULT 1 dma2_channel2_isr
724: 080038f1 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Restore_VFP_D_16_to_31
725: 08002465 92 FUNC GLOBAL DEFAULT 1 memcmp
726: 080004c9 28 FUNC GLOBAL DEFAULT 1 std::bad_alloc::~bad_alloc()
727: 080009e5 20 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__si_class_type_info::~__si_class_type_info()
728: 080039b1 34 FUNC GLOBAL HIDDEN 1 _Unwind_RaiseException
729: 080003db 2 FUNC WEAK DEFAULT 1 debug_monitor_handler
730: 080003d9 2 FUNC WEAK DEFAULT 1 exti3_isr
731: 080003d9 2 FUNC WEAK DEFAULT 1 adc3_isr
732: 08001ac5 164 FUNC GLOBAL DEFAULT 1 __sfp
733: 08000b05 4 FUNC GLOBAL DEFAULT 1 std::type_info::__is_pointer_p() const
734: 080003d9 2 FUNC WEAK DEFAULT 1 tim3_isr
735: 080003d9 2 FUNC WEAK DEFAULT 1 usart2_isr
737: 08002759 34 FUNC GLOBAL DEFAULT 1 __sread
738: 080003d9 2 FUNC WEAK DEFAULT 1 usb_lp_can_rx0_isr
740: 080007a9 14 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__forced_unwind::~__forced_unwind()
741: 08002571 2 FUNC GLOBAL DEFAULT 1 __malloc_lock
743: 080003d9 2 FUNC WEAK DEFAULT 1 i2c2_er_isr
745: 0800090d 54 FUNC GLOBAL DEFAULT 1 __cxa_throw
746: 08002915 44 FUNC GLOBAL DEFAULT 1 _fflush_r
747: 080016b5 160 FUNC GLOBAL DEFAULT 1 memset
748: 08000151 172 FUNC GLOBAL DEFAULT 1 main
750: 080003d9 2 FUNC WEAK DEFAULT 1 i2c2_ev_isr
751: 080007cd 2 FUNC GLOBAL DEFAULT 1 transaction clone for std::exception::~exception() const
752: 080003d9 2 FUNC WEAK DEFAULT 1 uart5_isr
753: 08000d9d 8 FUNC GLOBAL DEFAULT 1 __cxa_get_globals_fast
754: 080003db 2 FUNC WEAK DEFAULT 1 sys_tick_handler
755: 080027e5 8 FUNC GLOBAL DEFAULT 1 __sclose
756: 08001c39 16 FUNC GLOBAL DEFAULT 1 fclose
757: 080024e1 128 FUNC GLOBAL DEFAULT 1 _findenv_r
759: 080003d9 2 FUNC WEAK DEFAULT 1 fsmc_isr
760: 080003d9 2 FUNC WEAK DEFAULT 1 dma1_channel1_isr
761: 080003d9 2 FUNC WEAK DEFAULT 1 exti4_isr
762: 08001c59 1370 FUNC GLOBAL DEFAULT 1 _malloc_r
763: 0800077d 8 FUNC GLOBAL DEFAULT 1 std::bad_exception::what() const
764: 08002b6d 56 FUNC GLOBAL DEFAULT 1 _init_signal
765: 08002c55 2 FUNC GLOBAL DEFAULT 1 __env_unlock
767: 08001685 20 FUNC GLOBAL DEFAULT 1 _findenv
768: 08000771 2 FUNC GLOBAL DEFAULT 1 std::bad_exception::~bad_exception()
769: 080021b5 184 FUNC GLOBAL DEFAULT 1 _malloc_trim_r
770: 08003175 20 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_ForcedUnwind
771: 0800259d 442 FUNC GLOBAL DEFAULT 1 strcmp
773: 080002c5 4 FUNC GLOBAL DEFAULT 1 gpio_port_write
774: 080031c9 30 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Resume_or_Rethrow
775: 080003d9 2 FUNC WEAK DEFAULT 1 mem_manage_handler
776: 0800195d 28 FUNC GLOBAL DEFAULT 1 strtoul_l
777: 080038b9 24 FUNC GLOBAL HIDDEN 1 restore_core_regs
778: 0800399d 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Save_WMMXC
779: 080009f9 28 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__si_class_type_info::~__si_class_type_info()
780: 080003d9 2 FUNC WEAK DEFAULT 1 can2_tx_isr
781: 080003d9 2 FUNC WEAK DEFAULT 1 exti9_5_isr
782: 08002d79 44 FUNC GLOBAL DEFAULT 1 _write_r
783: 080003d9 2 FUNC WEAK DEFAULT 1 dma2_channel3_isr
784: 08003e13 6 FUNC GLOBAL HIDDEN 1 _Unwind_GetTextRelBase
785: 0800158b 30 FUNC GLOBAL DEFAULT 1 __cxa_call_terminate
788: 080027ed 296 FUNC GLOBAL DEFAULT 1 __sflush_r
789: 08000317 28 FUNC GLOBAL DEFAULT 1 rcc_periph_clock_disable
790: 08002c0d 68 FUNC GLOBAL DEFAULT 1 _fwalk_sglue
792: 080003d9 2 FUNC WEAK DEFAULT 1 dma1_channel7_isr
793: 08000875 16 FUNC GLOBAL DEFAULT 1 std::get_unexpected()
795: 080003d9 2 FUNC WEAK DEFAULT 1 tim1_up_isr
796: 08001ba5 20 FUNC GLOBAL DEFAULT 1 __fp_unlock_all
798: 08003df9 18 FUNC GLOBAL HIDDEN 1 _Unwind_GetLanguageSpecificData
799: 08000c79 126 FUNC GLOBAL DEFAULT 1 __cxa_begin_catch
800: 08000bb5 20 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::~__class_type_info()
801: 080007f9 8 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__unexpected(void (*)())
802: 080031f9 52 FUNC GLOBAL HIDDEN 1 _Unwind_VRS_Get
803: 080003d9 2 FUNC WEAK DEFAULT 1 can2_sce_isr
804: 080003d9 2 FUNC WEAK DEFAULT 1 tim4_isr
805: 08000795 14 FUNC GLOBAL DEFAULT 1 std::bad_exception::~bad_exception()
807: 08003989 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Restore_WMMXC
808: 0800035d 20 FUNC GLOBAL DEFAULT 1 rcc_set_mco
809: 080005e5 46 FUNC GLOBAL DEFAULT 1 __cxa_allocate_exception
812: 08003f71 16 FUNC GLOBAL DEFAULT 1 _write
813: 08003dbd 46 FUNC GLOBAL HIDDEN 1 __gnu_unwind_frame
814: 080009b5 32 FUNC GLOBAL DEFAULT 1 std::set_new_handler(void (*)())
815: 08003a1d 34 FUNC GLOBAL HIDDEN 1 _Unwind_ForcedUnwind
817: 080003d9 2 FUNC WEAK DEFAULT 1 dma1_channel2_isr
819: 080003d9 2 FUNC WEAK DEFAULT 1 i2c1_er_isr
820: 080003d9 2 FUNC WEAK DEFAULT 1 can_sce_isr
821: 08000399 40 FUNC GLOBAL DEFAULT 1 rcc_osc_bypass_disable
822: 080003db 2 FUNC WEAK DEFAULT 1 nmi_handler
823: 0800076d 2 FUNC GLOBAL DEFAULT 1 std::exception::~exception()
824: 080002f3 10 FUNC GLOBAL DEFAULT 1 rcc_peripheral_clear_reset
825: 08002781 62 FUNC GLOBAL DEFAULT 1 __swrite
826: 08000471 60 FUNC GLOBAL DEFAULT 1 operator new(unsigned int)
828: 08000a15 58 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__si_class_type_info::__do_find_public_src(int, void const*, __cxxabiv1::__class_type_info const*, void const*) const
829: 0800028d 16 FUNC GLOBAL DEFAULT 1 gpio_secondary_remap
830: 080003d9 2 FUNC WEAK DEFAULT 1 tim8_cc_isr
831: 080007d5 16 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__terminate(void (*)())
832: 08003945 0 FUNC GLOBAL HIDDEN 1 __gnu_Unwind_Save_WMMXD
833: 08003f25 16 FUNC GLOBAL DEFAULT 1 _kill
835: 080004b5 20 FUNC GLOBAL DEFAULT 1 std::bad_alloc::~bad_alloc()
836: 08001b8d 2 FUNC GLOBAL DEFAULT 1 __sfp_lock_release
838: 080003d9 2 FUNC WEAK DEFAULT 1 tamper_isr
840: 08003f45 16 FUNC GLOBAL DEFAULT 1 _read
842: 080002a1 6 FUNC GLOBAL DEFAULT 1 gpio_clear
843: 080003d9 2 FUNC WEAK DEFAULT 1 eth_wkup_isr
844: 08003f81 2 FUNC GLOBAL DEFAULT 1 _exit
845: 08000da5 8 FUNC GLOBAL DEFAULT 1 __cxa_get_globals
847: 08002989 48 FUNC GLOBAL DEFAULT 1 _init_signal_r
849: 080035cd 4 FUNC WEAK HIDDEN 1 __aeabi_unwind_cpp_pr1
850: 080007d1 2 FUNC GLOBAL DEFAULT 1 transaction clone for std::bad_exception::~bad_exception() const
853: 0800029d 4 FUNC GLOBAL DEFAULT 1 gpio_set
854: 08000785 14 FUNC GLOBAL DEFAULT 1 std::exception::~exception()
855: 08001755 206 FUNC GLOBAL DEFAULT 1 strchr
856: 080003d9 2 FUNC WEAK DEFAULT 1 bus_fault_handler
857: 080003d9 2 FUNC WEAK DEFAULT 1 wwdg_isr
858: 08003e0d 6 FUNC GLOBAL HIDDEN 1 _Unwind_GetDataRelBase
859: 080003d9 2 FUNC WEAK DEFAULT 1 dma1_channel3_isr
860: 08002c51 2 FUNC GLOBAL DEFAULT 1 __env_lock
862: 080003d9 2 FUNC WEAK DEFAULT 1 spi3_isr
863: 08002ba5 104 FUNC GLOBAL DEFAULT 1 __sigtramp
864: 08000b49 44 FUNC GLOBAL DEFAULT 1 std::type_info::operator==(std::type_info const&) const
866: 08000b1d 44 FUNC GLOBAL DEFAULT 1 std::type_info::__do_catch(std::type_info const*, void**, unsigned int) const
867: 080003d9 2 FUNC WEAK DEFAULT 1 tim2_isr
868: 08003f05 16 FUNC GLOBAL DEFAULT 1 _close
869: 08002ac5 88 FUNC GLOBAL DEFAULT 1 raise
870: 080024d1 16 FUNC GLOBAL DEFAULT 1 free
871: 08000bc9 28 FUNC GLOBAL DEFAULT 1 __cxxabiv1::__class_type_info::~__class_type_info()
872: 08002561 16 FUNC GLOBAL DEFAULT 1 _getenv_r
873: 080003d9 2 FUNC WEAK DEFAULT 1 exti0_isr
Außerdem enthält sie diverse Methoden die doch stark nach Exception-Handling klingen. So als ob mein -fno-exceptions Flag nicht wirksam wäre. Also nocham zurück zu den Linker-Flags. Was haben wir da alles?
arm-none-eabi-g++ -DRCC_LED1=RCC_GPIOC -DPORT_LED1=GPIOC -DPIN_LED1=GPIO13 \
-static -nostartfiles -g3 -Os -fno-common -ffunction-sections -fdata-sections -I./libopencm3/include -L./libopencm3/lib -mcpu=cortex-m3 -mthumb -msoft-float -DSTM32F1 -DLITTLE_BIT=200000 -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group template_stm32.cpp -T ld.stm32.basic -fno-exceptions -specs=nosys.specs -lopencm3_stm32f1 -o bin/bluepill.elf
wombat@T470s:~/blog$ arm-none-eabi-g++ --help
...
-Wa,<options> Pass comma-separated <options> on to the assembler.
-Wp,<options> Pass comma-separated <options> on to the preprocessor.
-Wl,<options> Pass comma-separated <options> on to the linker.
...
Options starting with -g, -f, -m, -O, -W, or --param are automatically
passed on to the various sub-processes invoked by arm-none-eabi-g++. In order to pass
other options on to these processes the -W<letter> options must be used.
D.h. wir haben für den Compiler:
- -DRCC_LED1=RCC_GPIOC -DPORT_LED1=GPIOC -DPIN_LED1=GPIO13 -DSTM32F1 -DLITTLE_BIT=200000 # Einige Defines, das spielt keine Rolle
- -g3 # Maximaler Level an Debugging infos im Output. Hier könnte auch -g0 oder -g1 stehen.
- -Os # Optmiere Output auf Gröze (“size”); könnte auch -O0, -O1, -O2 -O3 oder einige weitere Level sein. -Og für optimale Debug infos
- -fno-common # Keinen Einheitlichen Block für alle deklarierten aber nicht direkt initialisierten Globalen Variablen anlegen. (Weicht vom GCC/Unix default ab!).
- -ffunction-sections # Place each function or data item into its own section in the output file if the target supports arbitrary sections.
- -fdata-sections# Place each function or data item into its own section in the output file if the target supports arbitrary sections.
- -I./libopencm3/include
- -L./libopencm3/lib
- -mcpu=cortex-m3
- -mthumb # Thumb Code (weil Cortex-M)
- -msoft-float # Floating-Point libraries verwenden.
- -fno-exceptions # Sollte Exception Handling deaktivieren
- -specs=nosys.specs # Welches specs-file verwendet wird. Steuert Linker, Assembler etc.
- -lopencm3_stm32f1 # Bibliothek zu benutzen.
- -o bin/bluepill.elf # Output Datei
Und für den Linker:
- -static
- -nostartfiles
- -T ld.stm32.basic
- -Wl,–start-group -lc -lgcc -lnosys -Wl,–end-group
Hauptquelle: https://www.man7.org/linux/man-pages/man1/g++.1.html
In meinem CubeMX Setup:
arm-none-eabi-g++ -c -mcpu=cortex-m3 -mthumb -DUSE_HAL_DRIVER -DSTM32F103xB -ICore/Inc -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy -IDrivers/STM32F1xx_HAL_Driver/Inc -IDrivers/CMSIS/Device/ST/STM32F1xx/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -fno-exceptions -g -gdwarf-2 -MMD -MP -MF"build/main.d" -Wa,-a,-ad,-alms=build/main.lst Core/Src/main.cpp -o build/main.o
arm-none-eabi-gcc -x assembler-with-cpp -c -mcpu=cortex-m3 -mthumb -DUSE_HAL_DRIVER -DSTM32F103xB -ICore/Inc -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy -IDrivers/STM32F1xx_HAL_Driver/Inc -IDrivers/CMSIS/Device/ST/STM32F1xx/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -fno-exceptions -g -gdwarf-2 -MMD -MP -MF"build/startup_stm32f103xb.d" startup_stm32f103xb.s -o build/startup_stm32f103xb.o
arm-none-eabi-g++ build/stm32f1xx_it.o build/stm32f1xx_hal_msp.o build/stm32f1xx_hal_gpio_ex.o build/stm32f1xx_hal.o build/stm32f1xx_hal_rcc.o build/stm32f1xx_hal_rcc_ex.o build/stm32f1xx_hal_gpio.o build/stm32f1xx_hal_dma.o build/stm32f1xx_hal_cortex.o build/stm32f1xx_hal_pwr.o build/stm32f1xx_hal_flash.o build/stm32f1xx_hal_flash_ex.o build/stm32f1xx_hal_exti.o build/system_stm32f1xx.o build/sysmem.o build/syscalls.o build/main.o build/startup_stm32f103xb.o -mcpu=cortex-m3 -mthumb -specs=nano.specs -TSTM32F103XX_FLASH.ld -lc -lm -lnosys -Wl,-Map=build/Projekt01.map,--cref -Wl,--gc-sections -o build/Projekt01.elf