Mein Blog    Projekte    Archiv    Impressum

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:

  1. readelf öffnet die ELF-Datei, -s zeigt die Symbole an, und -W sorgt dafür, dass lange Namen nicht abgeschnitten werden.
  2. awk ‘$4 == “FUNC”’ filtert, sodass nur Zeilen angezeigt werden, bei denen in der vierten Spalte “FUNC” steht.
  3. 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