From c3d81e3efdd98b1bf7cca69644bb66cd123688fc Mon Sep 17 00:00:00 2001 From: Terraneo Federico <fede.tft@miosix.org> Date: Fri, 26 Aug 2016 18:23:49 +0200 Subject: [PATCH] Modified the policy about global objects inside the kernel. The previous policy was to forbid them, by checking with a script that there were none. This policy was found to be too restrictive, so a new script (miosix/_tools/kernel_global_objects.pl) moves the pointers to function that cause their construction in a separate section compared to the one used for the application global objects. Thus the global objects are now divided in two group: the kernel ones, which are called before boot, and the application ones, which are called after boot, right before main. This is made necessary by the fact that Miosix allows an application to be statically linked with the kernel, so both end up in the same binary file. --- miosix/Makefile | 2 +- miosix/_doc/textdoc/Changelog.txt | 11 + miosix/_tools/kernel_global_objects.pl | 123 +++++ .../lpc2138_miosix_board/miosix.ld | 420 +++++++++--------- .../core/stage_1_boot.cpp | 5 +- .../efm32_1M+128k_rom_usbbootloader.ld | 5 + .../core/stage_1_boot.cpp | 5 +- .../stm32_127k+8k_rom.ld | 340 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_128k+8k_rom.ld | 338 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_256k+24k_rom.ld | 6 + .../core/stage_1_boot.cpp | 5 +- .../stm32_128k+20k_rom.ld | 338 +++++++------- .../stm32f103ve_mp3v2/core/stage_1_boot.cpp | 5 +- .../stm32f103ve_mp3v2/stm32_512k+64k_ram.ld | 6 + .../stm32f103ve_mp3v2/stm32_512k+64k_rom.ld | 340 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_512k+64k_rom.ld | 6 + .../core/stage_1_boot.cpp | 5 +- .../stm32_512k+64k_rom.ld | 6 + .../core/stage_1_boot.cpp | 5 +- .../stm32_512k+64k_all_in_xram.ld | 6 + .../stm32_512k+64k_rom.ld | 338 +++++++------- .../stm32_512k+64k_xram.ld | 340 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_512k+128k_rom.ld | 6 + .../core/stage_1_boot.cpp | 5 +- .../stm32_1M+128k_rom.ld | 402 ++++++++--------- .../core/stage_1_boot.cpp | 5 +- .../stm32_1m+128k_all_in_xram.ld | 286 ++++++------ .../stm32_1m+128k_all_in_xram_processes.ld | 6 + .../stm32_1m+128k_rom.ld | 338 +++++++------- .../stm32_1m+128k_xram.ld | 340 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_1m+128k_rom.ld | 338 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_1m+128k_code_in_xram.ld | 338 +++++++------- .../stm32_1m+128k_rom.ld | 338 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_64k+10k_rom.ld | 338 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_256k+64k_rom.ld | 6 + .../core/stage_1_boot.cpp | 5 +- .../stm32_1m+192k_rom.ld | 358 +++++++-------- .../core/stage_1_boot.cpp | 45 +- .../stm32_1m+192k_ram.ld | 6 + .../stm32_1m+192k_rom.ld | 358 +++++++-------- .../stm32_1m+192k_rom_processes.ld | 372 ++++++++-------- .../stm32f411re_nucleo/core/stage_1_boot.cpp | 5 +- .../stm32f411re_nucleo/stm32_512k+128k_rom.ld | 338 +++++++------- .../core/stage_1_boot.cpp | 5 +- .../stm32_2m+256k_rom.ld | 6 + .../stm32_2m+6m_xram.ld | 6 + .../stm32_2m+8m_xram.ld | 6 + .../core/stage_1_boot.cpp | 5 +- .../stm32_2m+256k_rom.ld | 6 + .../stm32_2m+8m_xram.ld | 6 + .../core/stage_1_boot.cpp | 5 +- .../stm32_2m+256k_rom.ld | 6 + .../stm32_2m+6m_xram.ld | 6 + .../stm32_2m+8m_xram.ld | 6 + miosix/kernel/stage_2_boot.cpp | 55 ++- miosix/kernel/stage_2_boot.h | 9 + miosix/kernel/timeconversion.cpp | 2 +- miosix/util/version.cpp | 2 +- 66 files changed, 3677 insertions(+), 3382 deletions(-) create mode 100644 miosix/_tools/kernel_global_objects.pl diff --git a/miosix/Makefile b/miosix/Makefile index f259ebfc..6ea4e4a8 100644 --- a/miosix/Makefile +++ b/miosix/Makefile @@ -73,7 +73,7 @@ DFLAGS := -MMD -MP ## it must not end up in libmiosix.a all: $(OBJ) $(BOOT_FILE) $(ECHO) "[PERL] Checking global objects" - $(Q)perl _tools/check_global_objects.pl $(OBJ) + $(Q)perl _tools/kernel_global_objects.pl $(OBJ) $(ECHO) "[AR ] libmiosix.a" $(Q)$(AR) rcs libmiosix.a $(OBJ) diff --git a/miosix/_doc/textdoc/Changelog.txt b/miosix/_doc/textdoc/Changelog.txt index d32b985d..696f14e5 100644 --- a/miosix/_doc/textdoc/Changelog.txt +++ b/miosix/_doc/textdoc/Changelog.txt @@ -1,5 +1,16 @@ Changelog for Miosix np embedded OS +v2.02 +- Modified the policy about global objects inside the kernel. The previous + policy was to forbid them, by checking with a script that there were none. + This policy was found to be too restrictive, so a new script + (miosix/_tools/kernel_global_objects.pl) moves the pointers to function that + cause their construction in a separate section compared to the one used for + the application global objects. Thus the global objects are now divided in + two group: the kernel ones, which are called before boot, and the application + ones, which are called after boot, right before main. This is made necessary + by the fact that Miosix allows an application to be statically linked with the + kernel, so both end up in the same binary file. - Added SoftwareI2C::sendRepeatedStart(), and fixed a glitch in SoftwareI2C::init() - Fixed bug in STM32Serial in IOCTL_SYNC diff --git a/miosix/_tools/kernel_global_objects.pl b/miosix/_tools/kernel_global_objects.pl new file mode 100644 index 00000000..6bedf9a7 --- /dev/null +++ b/miosix/_tools/kernel_global_objects.pl @@ -0,0 +1,123 @@ +#!/usr/bin/perl + +# +# usage: perl kernel_global_objects.pl <list of .o files to check> +# returns 0 on success, !=0 on failure. +# +# This program checks every object file in the kernel for the presence of +# global objects, and renames the section used by the compiler to call their +# constructors to a miosix-specific name, so that they can be called early +# in the kernel boot, and not late, which is what occurs for the application +# global objects. This issue arises due to the fact that the kernel and +# application are statically linked in a single executable file, so there is +# the need to separate the kernel global objects from the application ones. +# +# In Miosix up to 1.61 constructors were called as soon as possible, right +# after copying .data in RAM and clearing .bss, therefore before the kernel +# was started. This allowed to make use of global objects within the kernel, +# as their constructors were called before the objects were used. However, +# this created a problem with user code: also the global constructors of user +# code were called before the kernel was started, and this meant that an +# attempt to printf(), open files, create threads, or other operations possible +# only after the kernel is started would cause a crash of the kernel. +# +# To fix this in Miosix 2.0, application global constructors are called as late +# as possible, right before calling main(), when the kernel is already started. +# However this creates a problem within the kernel, as this creates the +# possibility of accessing an object before its constructor is called. +# The problem was initially fixed in Miosix 2.0 by writing a script, called +# check_global_objects.pl that checked that no global constructors are used +# in the kernel code. However this was found to be too restrictive, so this +# new approach divides the global constructor in two: +# 1) Those of the kernel (i.e: of object files in the miosix directory), which +# are called after copying .data in RAM and clearing .bss +# 2) Those of the application code (i.e: those in the miosix top level +# directory), which are called right before main +# + +use warnings; +use strict; + +my $verbose=0; # Edit this file and set this to 1 for testing + +my @files_with_global_objects; +my @files_to_fix; +my @files_broken; + +# Step #1: check all kernel object files and categorize them based on the +# relevant sections +foreach my $filename (@ARGV) +{ + # First, check that the argument is really an object file + die "$filename is not a file name." unless -f $filename; + die "$filename is not an object file." unless $filename=~/\.o$/; + + # Then use readelf to dump all sections of the file + my $output=`arm-miosix-eabi-readelf -SW \"$filename\"`; + my @lines=split("\n",$output); + + my $sections=0; + foreach my $line (@lines) + { + # Lines containing section information have the following format + # " [ 2] .text PROGBITS 00000000 000044 000088 00 AX 0 0 4" + next unless($line=~/^ \[ ?\d+\] (\S+) /); + my $section_name=$1; + $sections++; + + # This is the section that the C++ compiler uses and need to be fixed. + # Note: we dont care about .fini_array, as the kernel does not call + # finalizers on reboot + if($section_name=~/^\.init_array/) + { + push(@files_to_fix,$filename); + push(@files_with_global_objects,"$filename (.init_array)"); + } + # An already fixed file, may occur when make is called multiple times + if($section_name=~/^\.miosix_init_array/) + { + push(@files_with_global_objects,"$filename (.miosix_init_array)"); + } + # These sections are related to global objects, but they have not + # been observed in the wild with the current ABI miosix is using, + # so for now, to be on the safe side, we will fail compiling if they + # are found. Probably it is enough to transform their name as well. + if($section_name=~/^\.preinit_array|^\.ctors|^\.dtors|^\.init |^\.fini /) + { + push(@files_broken,$filename); + } + + } + + # Sanity check, if a file has no sections probably something is wrong + die "$filename has no sections. Something is wrong." unless $sections>0; +} + + +# Step #2: fix the required files so that they are called before the kernel is +# started, not after +foreach my $filename (@files_to_fix) +{ + my $exitcode=system("arm-miosix-eabi-objcopy \"$filename\" --rename-section .init_array=.miosix_init_array"); + die "Error calling objcopy" unless($exitcode==0); +} + +# Step #3: if required to be verbose, print the list of files with global objects +if($verbose) +{ + print("List of kernel files with global constructors\n"); + print("=============================================\n"); + foreach my $filename (@files_with_global_objects) + { + $filename=~s/\.o /.cpp /; + print("$filename\n"); + } + print("=============================================\n"); +} + +# Step #4: check that there are no broken files +if(@files_broken!=0) +{ + print("kernel_global_objects.pl: Error: @files_broken contain unexpected sections\n"); + exit(1); +} diff --git a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/miosix.ld b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/miosix.ld index 8ded4110..af7c176e 100644 --- a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/miosix.ld +++ b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/miosix.ld @@ -1,207 +1,213 @@ -/*****************************************************************************/ -/* C++ enabled linker script. V2.00 -- Designed for Miosix Embedded OS */ -/* */ -/* MEMORY MAP */ -/* | | */ -/* .-------->|--------------------------------|0x40008000 */ -/* . | 32Bytes reserved for flash |0x40007FFF */ -/* . | programming | */ -/* .-------->|--------------------------------|0x40007FE0 _stack_end */ -/* . | UNDEF Stack | */ -/* . |--------------------------------| */ -/* . | ABORT Stack | */ -/* . |--------------------------------| */ -/* . | FIQ Stack | */ -/* . |--------------------------------| */ -/* . | IRQ Stack | */ -/* . |--------------------------------| */ -/* ram | SVC Stack | */ -/* . |--------------------------------| _stack_start, _heap_end */ -/* . | | */ -/* . | heap | */ -/* . | | */ -/* . |--------------------------------| _bss_end, _end */ -/* . | .bss uninitialized variables | */ -/* . |--------------------------------| _bss_start, _edata */ -/* . | .data initialized variables | */ -/* .-------->|--------------------------------|0x40000000 _data */ -/* | | */ -/* . */ -/* . */ -/* . */ -/* | | */ -/* .--------> |--------------------------------|0x0007D000 */ -/* . | | */ -/* . | | */ -/* . | unused flash | */ -/* . | | */ -/* . | | */ -/* . |--------------------------------| */ -/* . | | */ -/* . | copy of .data area | */ -/* . | | */ -/* . |--------------------------------| _etext */ -/* . | | */ -/* flash | | */ -/* . | | */ -/* . | code | */ -/* . | | */ -/* . | | */ -/* . | | */ -/* . |--------------------------------| */ -/* . | Startup Code | */ -/* . | (assembler) | */ -/* . |--------------------------------|0x00000040 Reset_Handler */ -/* . | interrupt vectors | */ -/* .--------->|--------------------------------|0x00000000 _startup */ -/* */ -/* */ -/*****************************************************************************/ - -/* stack sizes, used by startup assembler code, can be modified if needed */ -_und_stack_size = 0x00000000; /* stack for "UND" is 0, (shared with "FIQ") */ -_abt_stack_size = 0x00000000; /* stack for "ABT" is 0, (shared with "FIQ") */ -_fiq_stack_size = 0x00000030; /* stack for "FIQ" 48 bytes */ -_irq_stack_size = 0x00000000; /* stack for "IRQ" is 0, (shared with "SVC") */ -_svc_stack_size = 0x00000200; /* stack for "SVC" 512 bytes */ -_sys_stack_size = 0x00000000; /* stack for "SYS" is 0, since this stack is only used at startup */ - -/* check stack sizes */ -ASSERT(_und_stack_size % 8 == 0, "UND stack size error"); -ASSERT(_abt_stack_size % 8 == 0, "ABT stack size error"); -ASSERT(_fiq_stack_size % 8 == 0, "FIQ stack size error"); -ASSERT(_irq_stack_size % 8 == 0, "IRQ stack size error"); -ASSERT(_svc_stack_size % 8 == 0, "SVC stack size error"); -ASSERT(_sys_stack_size % 8 == 0, "SYS stack size error"); - -/* end of the stack */ -_stack_end = 0x40007FE0; /* end of available ram */ - -/* calculate the stacks and the end of the heap, used to check heap overflow */ -_und_stack_top = _stack_end; -_abt_stack_top = _und_stack_top - _und_stack_size; -_fiq_stack_top = _abt_stack_top - _abt_stack_size; -_irq_stack_top = _fiq_stack_top - _fiq_stack_size; -_svc_stack_top = _irq_stack_top - _irq_stack_size; -_sys_stack_top = _svc_stack_top - _svc_stack_size; -_stack_start = _sys_stack_top - _sys_stack_size; -_heap_end = _stack_start; - -/* identify the Entry Point */ -ENTRY(_startup) - -/* specify the LPC2138 memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 500K /* 512K-12K bootloader */ - ram(wx) : ORIGIN = 0x40000000, LENGTH = 32736 /* free RAM area */ -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - /* Startup code must go a address 0 */ - .startup : - { - *stage_1_boot.o (.text) - } > flash - - /* .text section: code goes to flash */ - .text : - { - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(0x4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(0x4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/*****************************************************************************/ +/* C++ enabled linker script. V2.00 -- Designed for Miosix Embedded OS */ +/* */ +/* MEMORY MAP */ +/* | | */ +/* .-------->|--------------------------------|0x40008000 */ +/* . | 32Bytes reserved for flash |0x40007FFF */ +/* . | programming | */ +/* .-------->|--------------------------------|0x40007FE0 _stack_end */ +/* . | UNDEF Stack | */ +/* . |--------------------------------| */ +/* . | ABORT Stack | */ +/* . |--------------------------------| */ +/* . | FIQ Stack | */ +/* . |--------------------------------| */ +/* . | IRQ Stack | */ +/* . |--------------------------------| */ +/* ram | SVC Stack | */ +/* . |--------------------------------| _stack_start, _heap_end */ +/* . | | */ +/* . | heap | */ +/* . | | */ +/* . |--------------------------------| _bss_end, _end */ +/* . | .bss uninitialized variables | */ +/* . |--------------------------------| _bss_start, _edata */ +/* . | .data initialized variables | */ +/* .-------->|--------------------------------|0x40000000 _data */ +/* | | */ +/* . */ +/* . */ +/* . */ +/* | | */ +/* .--------> |--------------------------------|0x0007D000 */ +/* . | | */ +/* . | | */ +/* . | unused flash | */ +/* . | | */ +/* . | | */ +/* . |--------------------------------| */ +/* . | | */ +/* . | copy of .data area | */ +/* . | | */ +/* . |--------------------------------| _etext */ +/* . | | */ +/* flash | | */ +/* . | | */ +/* . | code | */ +/* . | | */ +/* . | | */ +/* . | | */ +/* . |--------------------------------| */ +/* . | Startup Code | */ +/* . | (assembler) | */ +/* . |--------------------------------|0x00000040 Reset_Handler */ +/* . | interrupt vectors | */ +/* .--------->|--------------------------------|0x00000000 _startup */ +/* */ +/* */ +/*****************************************************************************/ + +/* stack sizes, used by startup assembler code, can be modified if needed */ +_und_stack_size = 0x00000000; /* stack for "UND" is 0, (shared with "FIQ") */ +_abt_stack_size = 0x00000000; /* stack for "ABT" is 0, (shared with "FIQ") */ +_fiq_stack_size = 0x00000030; /* stack for "FIQ" 48 bytes */ +_irq_stack_size = 0x00000000; /* stack for "IRQ" is 0, (shared with "SVC") */ +_svc_stack_size = 0x00000200; /* stack for "SVC" 512 bytes */ +_sys_stack_size = 0x00000000; /* stack for "SYS" is 0, since this stack is only used at startup */ + +/* check stack sizes */ +ASSERT(_und_stack_size % 8 == 0, "UND stack size error"); +ASSERT(_abt_stack_size % 8 == 0, "ABT stack size error"); +ASSERT(_fiq_stack_size % 8 == 0, "FIQ stack size error"); +ASSERT(_irq_stack_size % 8 == 0, "IRQ stack size error"); +ASSERT(_svc_stack_size % 8 == 0, "SVC stack size error"); +ASSERT(_sys_stack_size % 8 == 0, "SYS stack size error"); + +/* end of the stack */ +_stack_end = 0x40007FE0; /* end of available ram */ + +/* calculate the stacks and the end of the heap, used to check heap overflow */ +_und_stack_top = _stack_end; +_abt_stack_top = _und_stack_top - _und_stack_size; +_fiq_stack_top = _abt_stack_top - _abt_stack_size; +_irq_stack_top = _fiq_stack_top - _fiq_stack_size; +_svc_stack_top = _irq_stack_top - _irq_stack_size; +_sys_stack_top = _svc_stack_top - _svc_stack_size; +_stack_start = _sys_stack_top - _sys_stack_size; +_heap_end = _stack_start; + +/* identify the Entry Point */ +ENTRY(_startup) + +/* specify the LPC2138 memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 500K /* 512K-12K bootloader */ + ram(wx) : ORIGIN = 0x40000000, LENGTH = 32736 /* free RAM area */ +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + /* Startup code must go a address 0 */ + .startup : + { + *stage_1_boot.o (.text) + } > flash + + /* .text section: code goes to flash */ + .text : + { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(0x4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/core/stage_1_boot.cpp b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/core/stage_1_boot.cpp index e28635d3..fea8a020 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/core/stage_1_boot.cpp @@ -2,6 +2,7 @@ #include "interfaces/arch_registers.h" #include "interfaces/bsp.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -11,10 +12,6 @@ * based on silicon laboratories startup code. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/efm32_1M+128k_rom_usbbootloader.ld b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/efm32_1M+128k_rom_usbbootloader.ld index 847a48a8..e619d563 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/efm32_1M+128k_rom_usbbootloader.ld +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/efm32_1M+128k_rom_usbbootloader.ld @@ -75,6 +75,11 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/core/stage_1_boot.cpp index ec923e72..3515c15e 100644 --- a/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/stm32_127k+8k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/stm32_127k+8k_rom.ld index 433487f8..c684f603 100644 --- a/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/stm32_127k+8k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f100cb_tempsensor/stm32_127k+8k_rom.ld @@ -1,167 +1,173 @@ -/* - * C++ enabled linker script for stm32 (127K FLASH, 8K RAM) - * Last 1K of FLASH is reserved as non-volatile storage by the BSP - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 8KB microcontrollers */ -_heap_end = 0x20002000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0x08000000, LENGTH = 127K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 8K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (127K FLASH, 8K RAM) + * Last 1K of FLASH is reserved as non-volatile storage by the BSP + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 8KB microcontrollers */ +_heap_end = 0x20002000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 127K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 8K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/core/stage_1_boot.cpp index ec923e72..3515c15e 100644 --- a/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/stm32_128k+8k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/stm32_128k+8k_rom.ld index 50b95122..8fc6fd93 100644 --- a/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/stm32_128k+8k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/stm32_128k+8k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (128K FLASH, 8K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 8KB microcontrollers */ -_heap_end = 0x20002000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0x08000000, LENGTH = 128K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 8K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (128K FLASH, 8K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 8KB microcontrollers */ +_heap_end = 0x20002000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 128K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 8K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/core/stage_1_boot.cpp index 9389a9db..b66892fc 100644 --- a/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/stm32_256k+24k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/stm32_256k+24k_rom.ld index 127fef28..f02ab166 100644 --- a/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/stm32_256k+24k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f100rc_solertegiard/stm32_256k+24k_rom.ld @@ -90,6 +90,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/core/stage_1_boot.cpp index 8364c301..1bcea824 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -11,10 +12,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/stm32_128k+20k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/stm32_128k+20k_rom.ld index 524fb95a..2022d7db 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/stm32_128k+20k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103cb_als_mainboard_rev2/stm32_128k+20k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (128K FLASH, 20K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 20KB microcontrollers */ -_heap_end = 0x20005000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 128K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 20K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (128K FLASH, 20K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 20KB microcontrollers */ +_heap_end = 0x20005000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 128K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 20K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/core/stage_1_boot.cpp index 2c841de6..37f02e13 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -11,10 +12,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_ram.ld b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_ram.ld index d0ae2edc..37e12192 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_ram.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_ram.ld @@ -62,6 +62,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_rom.ld index 2081d490..714abfea 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/stm32_512k+64k_rom.ld @@ -1,167 +1,173 @@ -/* - * C++ enabled linker script for stm32 (512K FLASH, 64K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 64KB microcontrollers */ -_heap_end = 0x20010000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - /* First 10K taken up by bootloader */ - flash(rx) : ORIGIN = 0x2800, LENGTH = 512K-10K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 64K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (512K FLASH, 64K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 64KB microcontrollers */ +_heap_end = 0x20010000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + /* First 10K taken up by bootloader */ + flash(rx) : ORIGIN = 0x2800, LENGTH = 512K-10K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 64K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/core/stage_1_boot.cpp index 4e4bb0b3..2c3e2165 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -11,10 +12,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/stm32_512k+64k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/stm32_512k+64k_rom.ld index 57905267..53ff2940 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/stm32_512k+64k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/stm32_512k+64k_rom.ld @@ -90,6 +90,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/core/stage_1_boot.cpp index 946bb0e5..a14d50ad 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -11,10 +12,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/stm32_512k+64k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/stm32_512k+64k_rom.ld index 57905267..53ff2940 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/stm32_512k+64k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/stm32_512k+64k_rom.ld @@ -90,6 +90,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/core/stage_1_boot.cpp index a33ff9b6..4395fba0 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -11,10 +12,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_all_in_xram.ld b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_all_in_xram.ld index 36e3e2d1..1f213d41 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_all_in_xram.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_all_in_xram.ld @@ -63,6 +63,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_rom.ld b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_rom.ld index 7191e45f..4fbecb9b 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_rom.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (512K FLASH, 64K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 64KB microcontrollers */ -_heap_end = 0x20010000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 512K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 64K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (512K FLASH, 64K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 64KB microcontrollers */ +_heap_end = 0x20010000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 512K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 64K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_xram.ld b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_xram.ld index e33c352d..efe4c0a4 100644 --- a/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_xram.ld +++ b/miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/stm32_512k+64k_xram.ld @@ -1,167 +1,173 @@ -/* - * C++ enabled linker script for stm32 (512K FLASH, 64K RAM) + 1MB xram - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stack for interrupt handling, sections .data and .bss in the internal ram - * - heap and stack of threads in the external ram - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* Mapping the heap into external RAM (1MB) */ -_end = 0x68000000; -_heap_end = 0x68100000; - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 512K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 64K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - /*_end = .;*/ - /*PROVIDE(end = .);*/ -} +/* + * C++ enabled linker script for stm32 (512K FLASH, 64K RAM) + 1MB xram + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stack for interrupt handling, sections .data and .bss in the internal ram + * - heap and stack of threads in the external ram + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into external RAM (1MB) */ +_end = 0x68000000; +_heap_end = 0x68100000; + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 512K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 64K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/core/stage_1_boot.cpp index 7432662d..529b7ec4 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/stm32_512k+128k_rom.ld b/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/stm32_512k+128k_rom.ld index 3261fac6..9f09a9e5 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/stm32_512k+128k_rom.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/stm32_512k+128k_rom.ld @@ -90,6 +90,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/core/stage_1_boot.cpp index cd985ad5..96669146 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/stm32_1M+128k_rom.ld b/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/stm32_1M+128k_rom.ld index 5e927158..587f4e53 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/stm32_1M+128k_rom.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f205rg_sony-newman/stm32_1M+128k_rom.ld @@ -1,198 +1,204 @@ -/* - * C++ enabled linker script for Sony smartwatch - * Developed by Terraneo Federico - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ - -/* - * Taken from underverk's SmartWatch_Toolchain. Doesn't explain why the first - * 3K of RAM can't be used. TODO: try to start from 0x20000000 and see what - * happens. - */ -_ram_base = 0x20000c00; - -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = _ram_base + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* - * End of the heap. Taken from underverk's SmartWatch_Toolchain. Doesn't explain - * why the last 2K of RAM can't be used. TODO: try 0x20020000 and see what - * happens. - */ -_heap_end = 0x2001f800; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - /* - * Taken from underverk's SmartWatch_Toolchain. The DFU bootloader sits - * between 0x08000000 and 0x0800c000, that's 48K. Don't know why the code - * can't be placed directly @ 0x0800c000, but by unpacking the original - * firmware SmartWatch.dfu resulted in five different binary images: - * Base addr | size | - * ------------+---------+-------------------------------------------------- - * 0x0800c000 | 0x5f00 | Seems the bluetooth driver, no interrupt table, - * | | and funnily first 16K are zeros, probably - * | | compiled as non-PIC code at 64K from flash base. - * 0x08020000 | 0x1b578 | Is a firmware as it starts with an interrupt - * | | table, don't know what it does. - * 0x0803fffc | 0x188 | Discarding the first 4 bytes, the rest starts - * | | @ 0x08040000 and is an interrupt table. - * | | Bootloader jumps at this address. The interrupt - * | | points to the next firmware image. - * 0x08040200 | 0xb02b8 | First part is just pictures data, but there's - * | | code at the end, and the lone interrupt table - * | | points into it. - * 0x080ffffc | 0x4 | Some magic number of some sort. - */ - flash(rx) : ORIGIN = 0x08040000, LENGTH = 768K - - /* - * Note, the ram starts at _ram_base but it is necessary to add the size - * of the main stack. - */ - ram(wx) : ORIGIN = 0x20000e00, LENGTH = 123K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for Sony smartwatch + * Developed by Terraneo Federico + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +/* + * Taken from underverk's SmartWatch_Toolchain. Doesn't explain why the first + * 3K of RAM can't be used. TODO: try to start from 0x20000000 and see what + * happens. + */ +_ram_base = 0x20000c00; + +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = _ram_base + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* + * End of the heap. Taken from underverk's SmartWatch_Toolchain. Doesn't explain + * why the last 2K of RAM can't be used. TODO: try 0x20020000 and see what + * happens. + */ +_heap_end = 0x2001f800; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + /* + * Taken from underverk's SmartWatch_Toolchain. The DFU bootloader sits + * between 0x08000000 and 0x0800c000, that's 48K. Don't know why the code + * can't be placed directly @ 0x0800c000, but by unpacking the original + * firmware SmartWatch.dfu resulted in five different binary images: + * Base addr | size | + * ------------+---------+-------------------------------------------------- + * 0x0800c000 | 0x5f00 | Seems the bluetooth driver, no interrupt table, + * | | and funnily first 16K are zeros, probably + * | | compiled as non-PIC code at 64K from flash base. + * 0x08020000 | 0x1b578 | Is a firmware as it starts with an interrupt + * | | table, don't know what it does. + * 0x0803fffc | 0x188 | Discarding the first 4 bytes, the rest starts + * | | @ 0x08040000 and is an interrupt table. + * | | Bootloader jumps at this address. The interrupt + * | | points to the next firmware image. + * 0x08040200 | 0xb02b8 | First part is just pictures data, but there's + * | | code at the end, and the lone interrupt table + * | | points into it. + * 0x080ffffc | 0x4 | Some magic number of some sort. + */ + flash(rx) : ORIGIN = 0x08040000, LENGTH = 768K + + /* + * Note, the ram starts at _ram_base but it is necessary to add the size + * of the main stack. + */ + ram(wx) : ORIGIN = 0x20000e00, LENGTH = 123K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp index cd799411..5c166eef 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld index b0b9eedd..adde25b7 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld @@ -1,140 +1,146 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + 2MB xram - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - all (code, .data, .bss, stacks, heap) in the external ram. - * It is most useful for debugging, since powercycling the board will erase code - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * In this linker script the main stack is placed at the top of the ram since: - * - having 2MB of ram makes the "stack at bottom of ram" optimization useless - * - the interrupt vectors are forwarded at the bottom of the ram - */ -_main_stack_size = 0x00000200; /* main stack size = 512Bytes */ -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the stack */ -_main_stack_top = 0x64200000; /* placed at the top of ram */ -_heap_end = _main_stack_top - _main_stack_size; - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - ram(wx) : ORIGIN = 0x64000000, LENGTH = 2M -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > ram - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > ram - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + 2MB xram + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - all (code, .data, .bss, stacks, heap) in the external ram. + * It is most useful for debugging, since powercycling the board will erase code + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * In this linker script the main stack is placed at the top of the ram since: + * - having 2MB of ram makes the "stack at bottom of ram" optimization useless + * - the interrupt vectors are forwarded at the bottom of the ram + */ +_main_stack_size = 0x00000200; /* main stack size = 512Bytes */ +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the stack */ +_main_stack_top = 0x64200000; /* placed at the top of ram */ +_heap_end = _main_stack_top - _main_stack_size; + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + ram(wx) : ORIGIN = 0x64000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ram + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram_processes.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram_processes.ld index 41cd4964..ed9326cb 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram_processes.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram_processes.ld @@ -73,6 +73,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_rom.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_rom.ld index bc19fe4c..2b5498ed 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_rom.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 128KB microcontrollers */ -_heap_end = 0x20020000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 1M - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 128KB microcontrollers */ +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 1M + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_xram.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_xram.ld index 19f45eff..fb078c63 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_xram.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_xram.ld @@ -1,167 +1,173 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + 2MB xram - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stack for interrupt handling, sections .data and .bss in the internal ram - * - heap and stack of threads in the external ram - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* Mapping the heap into external RAM (2MB) */ -_end = 0x64000000; -_heap_end = 0x64200000; - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 1M - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - /*_end = .;*/ - /*PROVIDE(end = .);*/ -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + 2MB xram + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stack for interrupt handling, sections .data and .bss in the internal ram + * - heap and stack of threads in the external ram + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into external RAM (2MB) */ +_end = 0x64000000; +_heap_end = 0x64200000; + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 1M + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/core/stage_1_boot.cpp index 386b8b61..d251e060 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/stm32_1m+128k_rom.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/stm32_1m+128k_rom.ld index cfbaa194..1c0f9243 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/stm32_1m+128k_rom.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/stm32_1m+128k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (512K FLASH, 128K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 128KB microcontrollers */ -_heap_end = 0x20020000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 512K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (512K FLASH, 128K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 128KB microcontrollers */ +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 512K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/core/stage_1_boot.cpp index 386b8b61..d251e060 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_code_in_xram.ld b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_code_in_xram.ld index 6041276d..5e683c06 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_code_in_xram.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_code_in_xram.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + 512KB XRAM - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in xram - * - stacks, heap and sections .data and .bss in the internal ram - * It is most useful for debugging, since powercycling the board will erase code - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 128KB microcontrollers */ -_heap_end = 0x20020000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - xram(rx) : ORIGIN = 0x60000000, LENGTH = 512K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > xram - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > xram - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > xram - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + 512KB XRAM + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in xram + * - stacks, heap and sections .data and .bss in the internal ram + * It is most useful for debugging, since powercycling the board will erase code + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 128KB microcontrollers */ +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + xram(rx) : ORIGIN = 0x60000000, LENGTH = 512K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > xram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > xram + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > xram + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_rom.ld b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_rom.ld index bc19fe4c..2b5498ed 100644 --- a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_rom.ld +++ b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/stm32_1m+128k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 128KB microcontrollers */ -_heap_end = 0x20020000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 1M - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 128KB microcontrollers */ +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 1M + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/core/stage_1_boot.cpp index 7c986c1f..da7c4362 100644 --- a/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/stm32_64k+10k_rom.ld b/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/stm32_64k+10k_rom.ld index 3f980ff1..2468a791 100644 --- a/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/stm32_64k+10k_rom.ld +++ b/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/stm32_64k+10k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (64K FLASH, 10K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 10KB microcontrollers (minus 2K buffers) */ -_heap_end = 0x20002000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 64K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 8K-0x200 /* upper 2k used for buffering */ -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (64K FLASH, 10K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 10KB microcontrollers (minus 2K buffers) */ +_heap_end = 0x20002000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 64K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 8K-0x200 /* upper 2k used for buffering */ +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/core/stage_1_boot.cpp index 4de7d8f1..1871a51a 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/stm32_256k+64k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/stm32_256k+64k_rom.ld index b24d2081..96c858c7 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/stm32_256k+64k_rom.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/stm32_256k+64k_rom.ld @@ -90,6 +90,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/core/stage_1_boot.cpp index febde445..fe49aab5 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/stm32_1m+192k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/stm32_1m+192k_rom.ld index cde86d24..b83253e1 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/stm32_1m+192k_rom.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/stm32_1m+192k_rom.ld @@ -1,176 +1,182 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 192K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This chip has an unusual quirk that the RAM is divided in two block mapped - * at two non contiguous memory addresses. I don't know why they've done that, - * probably doing the obvious thing would have made writing code too easy... - * Anyway, since hardware can't be changed, we've got to live with that and - * try to make use of both RAMs. - * - * Given the constraints above, this linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in FLASH - * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM - * - stacks and heap in the "large" 128KB RAM. - * - * Unfortunately thread stacks can't be put in the small RAM as Miosix - * allocates them inside the heap. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x10000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* Mapping the heap into the large 128KB RAM */ -_end = 0x20000000; -_heap_end = 0x20020000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M - /* - * Note, the small ram starts at 0x10000000 but it is necessary to add the - * size of the main stack, so it is 0x10000200. - */ - smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 - largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > smallram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > smallram - _bss_end = .; - - /*_end = .;*/ - /*PROVIDE(end = .);*/ -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 192K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 128KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 128KB RAM */ +_end = 0x20000000; +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/core/stage_1_boot.cpp index febde445..5a339790 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. @@ -26,24 +23,24 @@ void program_startup() //Cortex M3 core appears to get out of reset with interrupts already enabled __disable_irq(); - //SystemInit() is called *before* initializing .data and zeroing .bss - //Despite all startup files provided by ST do the opposite, there are three - //good reasons to do so: - //First, the CMSIS specifications say that SystemInit() must not access - //global variables, so it is actually possible to call it before - //Second, when running Miosix with the xram linker scripts .data and .bss - //are placed in the external RAM, so we *must* call SystemInit(), which - //enables xram, before touching .data and .bss - //Third, this is a performance improvement since the loops that initialize - //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + //SystemInit() is called *before* initializing .data and zeroing .bss + //Despite all startup files provided by ST do the opposite, there are three + //good reasons to do so: + //First, the CMSIS specifications say that SystemInit() must not access + //global variables, so it is actually possible to call it before + //Second, when running Miosix with the xram linker scripts .data and .bss + //are placed in the external RAM, so we *must* call SystemInit(), which + //enables xram, before touching .data and .bss + //Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz SystemInit(); - //These are defined in the linker script - extern unsigned char _etext asm("_etext"); - extern unsigned char _data asm("_data"); - extern unsigned char _edata asm("_edata"); - extern unsigned char _bss_start asm("_bss_start"); - extern unsigned char _bss_end asm("_bss_end"); + //These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); //Initialize .data section, clear .bss section unsigned char *etext=&_etext; @@ -54,11 +51,11 @@ void program_startup() memcpy(data, etext, edata-data); memset(bss_start, 0, bss_end-bss_start); - //Move on to stage 2 - _init(); + //Move on to stage 2 + _init(); - //If main returns, reboot - NVIC_SystemReset(); + //If main returns, reboot + NVIC_SystemReset(); for(;;) ; } diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_ram.ld b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_ram.ld index ecb62417..046a7611 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_ram.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_ram.ld @@ -77,6 +77,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom.ld index cde86d24..b83253e1 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom.ld @@ -1,176 +1,182 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 192K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This chip has an unusual quirk that the RAM is divided in two block mapped - * at two non contiguous memory addresses. I don't know why they've done that, - * probably doing the obvious thing would have made writing code too easy... - * Anyway, since hardware can't be changed, we've got to live with that and - * try to make use of both RAMs. - * - * Given the constraints above, this linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in FLASH - * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM - * - stacks and heap in the "large" 128KB RAM. - * - * Unfortunately thread stacks can't be put in the small RAM as Miosix - * allocates them inside the heap. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x10000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* Mapping the heap into the large 128KB RAM */ -_end = 0x20000000; -_heap_end = 0x20020000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M - /* - * Note, the small ram starts at 0x10000000 but it is necessary to add the - * size of the main stack, so it is 0x10000200. - */ - smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 - largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > smallram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > smallram - _bss_end = .; - - /*_end = .;*/ - /*PROVIDE(end = .);*/ -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 192K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 128KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 128KB RAM */ +_end = 0x20000000; +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom_processes.ld b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom_processes.ld index 13962e04..47e71389 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom_processes.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom_processes.ld @@ -1,183 +1,189 @@ -/* - * C++ enabled linker script for stm32 (1M FLASH, 192K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This chip has an unusual quirk that the RAM is divided in two block mapped - * at two non contiguous memory addresses. I don't know why they've done that, - * probably doing the obvious thing would have made writing code too easy... - * Anyway, since hardware can't be changed, we've got to live with that and - * try to make use of both RAMs. - * - * Given the constraints above, this linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in FLASH - * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM - * - stacks and heap in the "large" 128KB RAM. - * - * Unfortunately thread stacks can't be put in the small RAM as Miosix - * allocates them inside the heap. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x10000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* Mapping the heap into the bottom 32KB of the large 128KB RAM */ -_end = 0x20000000; -_heap_end = 0x20008000; -/* Mapping the process pool into the upper 96KB of the large 128KB RAM */ -_process_pool_start = _heap_end; -_process_pool_end = 0x20020000; /* end of available ram */ - -/* TODO: for now, leave the whole FLASH readable by processes */ -_elf_pool_start = 0x08000000; -_elf_pool_end = 0x08000000+1024*1024; - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M - /* - * Note, the small ram starts at 0x10000000 but it is necessary to add the - * size of the main stack, so it is 0x10000200. - */ - smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 - largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > smallram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > smallram - _bss_end = .; - - /*_end = .;*/ - /*PROVIDE(end = .);*/ -} +/* + * C++ enabled linker script for stm32 (1M FLASH, 192K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 128KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the bottom 32KB of the large 128KB RAM */ +_end = 0x20000000; +_heap_end = 0x20008000; +/* Mapping the process pool into the upper 96KB of the large 128KB RAM */ +_process_pool_start = _heap_end; +_process_pool_end = 0x20020000; /* end of available ram */ + +/* TODO: for now, leave the whole FLASH readable by processes */ +_elf_pool_start = 0x08000000; +_elf_pool_end = 0x08000000+1024*1024; + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/core/stage_1_boot.cpp index beadc245..ea380eb4 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/core/stage_1_boot.cpp @@ -1,6 +1,7 @@ #include "interfaces/arch_registers.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -12,10 +13,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/stm32_512k+128k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/stm32_512k+128k_rom.ld index cfbaa194..1c0f9243 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/stm32_512k+128k_rom.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/stm32_512k+128k_rom.ld @@ -1,166 +1,172 @@ -/* - * C++ enabled linker script for stm32 (512K FLASH, 128K RAM) - * Developed by TFT: Terraneo Federico Technologies - * Optimized for use with the Miosix kernel - */ - -/* - * This linker script puts: - * - read only data and code (.text, .rodata, .eh_*) in flash - * - stacks, heap and sections .data and .bss in the internal ram - * - the external ram (if available) is not used. - */ - -/* - * The main stack is used for interrupt handling by the kernel. - * - * *** Readme *** - * This linker script places the main stack (used by the kernel for interrupts) - * at the bottom of the ram, instead of the top. This is done for two reasons: - * - * - as an optimization for microcontrollers with little ram memory. In fact - * the implementation of malloc from newlib requests memory to the OS in 4KB - * block (except the first block that can be smaller). This is probably done - * for compatibility with OSes with an MMU and paged memory. To see why this - * is bad, consider a microcontroller with 8KB of ram: when malloc finishes - * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will - * fail because the top part of the ram is used by the main stack. As a - * result, the top part of the memory will not be used by malloc, even if - * available (and it is nearly *half* the ram on an 8KB mcu). By placing the - * main stack at the bottom of the ram, the upper 4KB block will be entirely - * free and available as heap space. - * - * - In case of main stack overflow the cpu will fault because access to memory - * before the beginning of the ram faults. Instead with the default stack - * placement the main stack will silently collide with the heap. - * Note: if increasing the main stack size also increase the ORIGIN value in - * the MEMORY definitions below accordingly. - */ -_main_stack_size = 0x00000200; /* main stack = 512Bytes */ -_main_stack_top = 0x20000000 + _main_stack_size; -ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); - -/* end of the heap on 128KB microcontrollers */ -_heap_end = 0x20020000; /* end of available ram */ - -/* identify the Entry Point */ -ENTRY(_Z13Reset_Handlerv) - -/* specify the memory areas */ -MEMORY -{ - flash(rx) : ORIGIN = 0, LENGTH = 512K - - /* - * Note, the ram starts at 0x20000000 but it is necessary to add the size - * of the main stack, so it is 0x20000200. - */ - ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 -} - -/* now define the output sections */ -SECTIONS -{ - . = 0; - - /* .text section: code goes to flash */ - .text : - { - /* Startup code must go at address 0 */ - KEEP(*(.isr_vector)) - - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - /* these sections for thumb interwork? */ - *(.glue_7) - *(.glue_7t) - /* these sections for C++? */ - *(.gcc_except_table) - *(.gcc_except_table.*) - *(.ARM.extab*) - *(.gnu.linkonce.armextab.*) - - . = ALIGN(4); - /* .rodata: constant data */ - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - - /* C++ Static constructors/destructors (eabi) */ - . = ALIGN(4); - KEEP(*(.init)) - - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - /* C++ Static constructors/destructors (elf) */ - . = ALIGN(4); - _ctor_start = .; - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - _ctor_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - } > flash - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > flash - __exidx_end = .; - - . = ALIGN(8); - _etext = .; - - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ - .data : ALIGN(8) - { - _data = .; - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - _edata = .; - } > ram AT > flash - - /* .bss section: uninitialized global variables go to ram */ - _bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - . = ALIGN(8); - } > ram - _bss_end = .; - - _end = .; - PROVIDE(end = .); -} +/* + * C++ enabled linker script for stm32 (512K FLASH, 128K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 128KB microcontrollers */ +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 512K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + . = ALIGN(8); + _etext = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/core/stage_1_boot.cpp index 58e52fcf..515049d7 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/core/stage_1_boot.cpp @@ -2,6 +2,7 @@ #include "interfaces/arch_registers.h" #include "interfaces/bsp.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -13,10 +14,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+256k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+256k_rom.ld index 1a5f989d..0924f0d5 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+256k_rom.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+256k_rom.ld @@ -100,6 +100,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+6m_xram.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+6m_xram.ld index d0d52aa3..49d21dba 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+6m_xram.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+6m_xram.ld @@ -103,6 +103,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+8m_xram.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+8m_xram.ld index b58a2355..27db7dd2 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+8m_xram.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/stm32_2m+8m_xram.ld @@ -97,6 +97,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/core/stage_1_boot.cpp index 58e52fcf..515049d7 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/core/stage_1_boot.cpp @@ -2,6 +2,7 @@ #include "interfaces/arch_registers.h" #include "interfaces/bsp.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -13,10 +14,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+256k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+256k_rom.ld index 1a5f989d..0924f0d5 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+256k_rom.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+256k_rom.ld @@ -100,6 +100,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+8m_xram.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+8m_xram.ld index b58a2355..27db7dd2 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+8m_xram.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/stm32_2m+8m_xram.ld @@ -97,6 +97,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/core/stage_1_boot.cpp index 58e52fcf..515049d7 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/core/stage_1_boot.cpp +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/core/stage_1_boot.cpp @@ -2,6 +2,7 @@ #include "interfaces/arch_registers.h" #include "interfaces/bsp.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include "kernel/stage_2_boot.h" #include <string.h> /* @@ -13,10 +14,6 @@ * Additionally modified to boot Miosix. */ -//Will be called at the end of stage 1 of boot, function is implemented in -//stage_2_boot.cpp -extern "C" void _init(); - /** * Called by Reset_Handler, performs initialization and calls main. * Never returns. diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+256k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+256k_rom.ld index 1a5f989d..0924f0d5 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+256k_rom.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+256k_rom.ld @@ -100,6 +100,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+6m_xram.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+6m_xram.ld index d0d52aa3..49d21dba 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+6m_xram.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+6m_xram.ld @@ -103,6 +103,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+8m_xram.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+8m_xram.ld index b58a2355..27db7dd2 100644 --- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+8m_xram.ld +++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/stm32_2m+8m_xram.ld @@ -97,6 +97,12 @@ SECTIONS /* C++ Static constructors/destructors (eabi) */ . = ALIGN(4); KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; . = ALIGN(4); __preinit_array_start = .; diff --git a/miosix/kernel/stage_2_boot.cpp b/miosix/kernel/stage_2_boot.cpp index f25f6f86..7ec0676e 100644 --- a/miosix/kernel/stage_2_boot.cpp +++ b/miosix/kernel/stage_2_boot.cpp @@ -54,43 +54,39 @@ int main(int argc, char *argv[]); namespace miosix { /** + * \internal * Calls C++ global constructors * \param start first function pointer to call * \param end one past the last function pointer to call */ -static void call_constructors(unsigned long *start, unsigned long *end) +static void callConstructors(unsigned long *start, unsigned long *end) { - for(unsigned long *i=start; i<end; i++) - { - void (*funcptr)(); + for(unsigned long *i=start; i<end; i++) + { + void (*funcptr)(); funcptr=reinterpret_cast<void (*)()>(*i); - funcptr(); - } + funcptr(); + } } -/** - * \internal - * Performs the part of initialization that must be done after the kernel is - * started, and finally calls main() - */ void *mainLoader(void *argv) { //If reaches here kernel is started, print Ok bootlog("Ok\n%s\n",getMiosixVersion()); - + //Starting part of bsp that must be started after kernel bspInit2(); - //Initialize C++ global constructors + //Initialize application C++ global constructors (called after boot) extern unsigned long __preinit_array_start asm("__preinit_array_start"); - extern unsigned long __preinit_array_end asm("__preinit_array_end"); - extern unsigned long __init_array_start asm("__init_array_start"); - extern unsigned long __init_array_end asm("__init_array_end"); - extern unsigned long _ctor_start asm("_ctor_start"); - extern unsigned long _ctor_end asm("_ctor_end"); - call_constructors(&__preinit_array_start, &__preinit_array_end); - call_constructors(&__init_array_start, &__init_array_end); - call_constructors(&_ctor_start, &_ctor_end); + extern unsigned long __preinit_array_end asm("__preinit_array_end"); + extern unsigned long __init_array_start asm("__init_array_start"); + extern unsigned long __init_array_end asm("__init_array_end"); + extern unsigned long _ctor_start asm("_ctor_start"); + extern unsigned long _ctor_end asm("_ctor_end"); + callConstructors(&__preinit_array_start, &__preinit_array_end); + callConstructors(&__init_array_start, &__init_array_end); + callConstructors(&_ctor_start, &_ctor_end); bootlog("Available heap %d out of %d Bytes\n", MemoryProfiling::getCurrentFreeHeap(), @@ -117,14 +113,17 @@ void *mainLoader(void *argv) return 0; } -/** - * \internal - * Performs the part of initialization that must be done before the kernel is - * started, and starts the kernel. - * This function is called by the stage 1 boot which is architecture dependent. - */ +} //namespace miosix + extern "C" void _init() { + using namespace miosix; + + //Initialize kernel C++ global constructors (called before boot) + extern unsigned long __miosix_init_array_start asm("__miosix_init_array_start"); + extern unsigned long __miosix_init_array_end asm("__miosix_init_array_end"); + callConstructors(&__miosix_init_array_start, &__miosix_init_array_end); + if(areInterruptsEnabled()) errorHandler(INTERRUPTS_ENABLED_AT_BOOT); IRQbspInit(); //After IRQbspInit() serial port is initialized, so we can use IRQbootlog @@ -132,5 +131,3 @@ extern "C" void _init() startKernel(); //Never reach here (unless startKernel fails) } - -} //namespace miosix \ No newline at end of file diff --git a/miosix/kernel/stage_2_boot.h b/miosix/kernel/stage_2_boot.h index 32cf8b5d..5cff2abc 100644 --- a/miosix/kernel/stage_2_boot.h +++ b/miosix/kernel/stage_2_boot.h @@ -36,6 +36,7 @@ namespace miosix { /** + * \internal * This function will perform the part of system initialization that must be * done after the kernel is started. At the end, it will call main() * \param argv ignored parameter @@ -44,4 +45,12 @@ void *mainLoader(void *argv); } //namespace miosix +/** + * \internal + * Performs the part of initialization that must be done before the kernel is + * started, and starts the kernel. + * This function is called by the stage 1 boot which is architecture dependent. + */ +extern "C" void _init(); + #endif //STAGE_2_BOOT_H diff --git a/miosix/kernel/timeconversion.cpp b/miosix/kernel/timeconversion.cpp index 1571a8d5..0686af7a 100644 --- a/miosix/kernel/timeconversion.cpp +++ b/miosix/kernel/timeconversion.cpp @@ -130,7 +130,7 @@ TimeConversionFactor TimeConversion::floatToFactor(float x) return TimeConversionFactor(i,f); } -//FIXME: uncomment: TimeConversionFactor TimeConversion::toNs, TimeConversion::toTick; +TimeConversionFactor TimeConversion::toNs, TimeConversion::toTick; //Testsuite for multiplication algorithm and factor computation. Compile with: // g++ -std=c++11 -O2 -DTEST_ALGORITHM -o test timeconversion.cpp; ./test diff --git a/miosix/util/version.cpp b/miosix/util/version.cpp index 82571357..01f90239 100644 --- a/miosix/util/version.cpp +++ b/miosix/util/version.cpp @@ -59,7 +59,7 @@ namespace miosix { #define AU #endif -const char AU ver[]="Miosix v2.01 (" _MIOSIX_BOARDNAME ", " __DATE__ " " __TIME__ CV ")"; +const char AU ver[]="Miosix v2.02 (" _MIOSIX_BOARDNAME ", " __DATE__ " " __TIME__ CV ")"; const char *getMiosixVersion() { -- GitLab