From 0acd008184270a5dc18c7cb23aac41054aa7471f Mon Sep 17 00:00:00 2001 From: Terraneo Federico <fede.tft@hotmail.it> Date: Sun, 30 Oct 2011 16:30:17 +0100 Subject: [PATCH] Faster boot, changed getMiosixVersion() --- .../core/stage_1_boot.cpp | 42 ++++++++---------- .../stm32f103ve_mp3v2/core/stage_1_boot.cpp | 42 ++++++++---------- .../stm32f103ve_mp3v2/stm32_512k+64k_ram.ld | 3 +- .../core/stage_1_boot.cpp | 44 +++++++++---------- .../stm32_512k+64k_all_in_xram.ld | 3 +- miosix/config/Makefile.inc | 4 +- miosix/doc/textdoc/Changelog.txt | 4 ++ miosix/kernel/kernel.cpp | 39 ++++++---------- miosix/util/version.cpp | 17 ++++--- miosix/util/version.h | 6 ++- 10 files changed, 94 insertions(+), 110 deletions(-) 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 433920d1..5f663809 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 "CMSIS/stm32f10x.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include <string.h> /* * startup.cpp @@ -22,16 +23,13 @@ extern "C" void _init(); * \param end one past the last function pointer to call * Declared "noinline" to optimize code size */ -static void call_constructors(unsigned long *start, unsigned long *end) - __attribute__((noinline)); +static void call_constructors(unsigned long *start, unsigned long *end) __attribute__((noinline)); static void call_constructors(unsigned long *start, unsigned long *end) { - unsigned long *i; - void (*funcptr)(); - - for(i=start; i<end; i++) + for(unsigned long *i=start; i<end; i++) { - funcptr=reinterpret_cast<void (*)()>(*i); + void (*funcptr)(); + funcptr=reinterpret_cast<void (*)()>(*i); funcptr(); } } @@ -59,11 +57,11 @@ void program_startup() SystemInit(); //These are defined in the linker script - extern unsigned long _etext asm("_etext"); - extern unsigned long _data asm("_data"); - extern unsigned long _edata asm("_edata"); - extern unsigned long _bss_start asm("_bss_start"); - extern unsigned long _bss_end asm("_bss_end"); + 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"); 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"); @@ -71,18 +69,14 @@ void program_startup() extern unsigned long _ctor_start asm("_ctor_start"); extern unsigned long _ctor_end asm("_ctor_end"); - unsigned long *src, *dest; - - //Initialize .data section - for(src=&_etext, dest=&_data; dest<&_edata; src++, dest++) - { - *dest=*src; - } - //Clear .bss section - for(dest=&_bss_start; dest<&_bss_end; dest++) - { - *dest=0; - } + //Initialize .data section, clear .bss section + unsigned char *etext=&_etext; + unsigned char *data=&_data; + unsigned char *edata=&_edata; + unsigned char *bss_start=&_bss_start; + unsigned char *bss_end=&_bss_end; + memcpy(data, etext, edata-data); + memset(bss_start, 0, bss_end-bss_start); //Initialize C++ global constructors call_constructors(&__preinit_array_start, &__preinit_array_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 6f3c00e0..d7e0fc4d 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 "CMSIS/stm32f10x.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include <string.h> /* * startup.cpp @@ -21,16 +22,13 @@ extern "C" void _init(); * \param end one past the last function pointer to call * Declared "noinline" to optimize code size */ -static void call_constructors(unsigned long *start, unsigned long *end) - __attribute__((noinline)); +static void call_constructors(unsigned long *start, unsigned long *end) __attribute__((noinline)); static void call_constructors(unsigned long *start, unsigned long *end) { - unsigned long *i; - void (*funcptr)(); - - for(i=start; i<end; i++) + for(unsigned long *i=start; i<end; i++) { - funcptr=reinterpret_cast<void (*)()>(*i); + void (*funcptr)(); + funcptr=reinterpret_cast<void (*)()>(*i); funcptr(); } } @@ -50,11 +48,11 @@ void program_startup() //SystemInit(); //These are defined in the linker script - extern unsigned long _etext asm("_etext"); - extern unsigned long _data asm("_data"); - extern unsigned long _edata asm("_edata"); - extern unsigned long _bss_start asm("_bss_start"); - extern unsigned long _bss_end asm("_bss_end"); + 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"); 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"); @@ -62,18 +60,14 @@ void program_startup() extern unsigned long _ctor_start asm("_ctor_start"); extern unsigned long _ctor_end asm("_ctor_end"); - unsigned long *src, *dest; - - //Initialize .data section - for(src=&_etext, dest=&_data; dest<&_edata; src++, dest++) - { - *dest=*src; - } - //Clear .bss section - for(dest=&_bss_start; dest<&_bss_end; dest++) - { - *dest=0; - } + //Initialize .data section, clear .bss section + unsigned char *etext=&_etext; + unsigned char *data=&_data; + unsigned char *edata=&_edata; + unsigned char *bss_start=&_bss_start; + unsigned char *bss_end=&_bss_end; + memcpy(data, etext, edata-data); + memset(bss_start, 0, bss_end-bss_start); //Initialize C++ global constructors call_constructors(&__preinit_array_start, &__preinit_array_end); 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 54e2453c..d0ae2edc 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 @@ -110,8 +110,7 @@ SECTIONS . = ALIGN(8); _etext = .; - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ + /* .data section: global variables go to ram */ .data : ALIGN(8) { _data = .; 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 ec3d4160..55f1073c 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 "CMSIS/stm32f10x.h" #include "core/interrupts.h" //For the unexpected interrupt call +#include <string.h> /* * startup.cpp @@ -21,16 +22,13 @@ extern "C" void _init(); * \param end one past the last function pointer to call * Declared "noinline" to optimize code size */ -static void call_constructors(unsigned long *start, unsigned long *end) - __attribute__((noinline)); +static void call_constructors(unsigned long *start, unsigned long *end) __attribute__((noinline)); static void call_constructors(unsigned long *start, unsigned long *end) { - unsigned long *i; - void (*funcptr)(); - - for(i=start; i<end; i++) + for(unsigned long *i=start; i<end; i++) { - funcptr=reinterpret_cast<void (*)()>(*i); + void (*funcptr)(); + funcptr=reinterpret_cast<void (*)()>(*i); funcptr(); } } @@ -58,11 +56,11 @@ void program_startup() SystemInit(); //These are defined in the linker script - extern unsigned long _etext asm("_etext"); - extern unsigned long _data asm("_data"); - extern unsigned long _edata asm("_edata"); - extern unsigned long _bss_start asm("_bss_start"); - extern unsigned long _bss_end asm("_bss_end"); + 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"); 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"); @@ -70,18 +68,16 @@ void program_startup() extern unsigned long _ctor_start asm("_ctor_start"); extern unsigned long _ctor_end asm("_ctor_end"); - unsigned long *src, *dest; - - //Initialize .data section - for(src=&_etext, dest=&_data; dest<&_edata; src++, dest++) - { - *dest=*src; - } - //Clear .bss section - for(dest=&_bss_start; dest<&_bss_end; dest++) - { - *dest=0; - } + //Initialize .data section, clear .bss section + unsigned char *etext=&_etext; + unsigned char *data=&_data; + unsigned char *edata=&_edata; + unsigned char *bss_start=&_bss_start; + unsigned char *bss_end=&_bss_end; + #ifndef __CODE_IN_XRAM + memcpy(data, etext, edata-data); + #endif //__CODE_IN_XRAM + memset(bss_start, 0, bss_end-bss_start); //Initialize C++ global constructors call_constructors(&__preinit_array_start, &__preinit_array_end); 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 8429fdc8..36e3e2d1 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 @@ -111,8 +111,7 @@ SECTIONS . = ALIGN(8); _etext = .; - /* .data section: global variables go to ram, but also store a copy to - flash to initialize them */ + /* .data section: global variables go to ram */ .data : ALIGN(8) { _data = .; diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc index e6636563..c8a53075 100644 --- a/miosix/config/Makefile.inc +++ b/miosix/config/Makefile.inc @@ -130,8 +130,8 @@ endif ## Then, initialize C/C++ flags with -D_MIOSIX so that application code can ## know if the OS is MIOSIX ## -CFLAGS_BASE := -D_MIOSIX -CXXFLAGS_BASE := -D_MIOSIX +CFLAGS_BASE := -D_MIOSIX="\"$(OPT_BOARD)\"" +CXXFLAGS_BASE := -D_MIOSIX="\"$(OPT_BOARD)\"" ## ## Now two big switch-like constructs nested. The first lists all possible diff --git a/miosix/doc/textdoc/Changelog.txt b/miosix/doc/textdoc/Changelog.txt index 271edd73..5d5e4bd9 100644 --- a/miosix/doc/textdoc/Changelog.txt +++ b/miosix/doc/textdoc/Changelog.txt @@ -1,6 +1,10 @@ Changelog for Miosix np embedded OS v1.59 +- Improved boot speed by replacing for loops to initialize .data, .bss and + to initialize the stack of threads with memset/memcpy. +- Improved getMiosixVersion(), new format contains more information, including + board name, build date and compiler version. - The files binutils-2.21.tar.bz2 and gdb-7.0.tar.bz2 no longer exist on the ftp.gnu.org and mirrors.kernel.org, and this broke the compiler installation script. Fixed by downloading binutils-2.21.1 and gdb-7.0.1a. diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp index a2431cef..681d8c21 100644 --- a/miosix/kernel/kernel.cpp +++ b/miosix/kernel/kernel.cpp @@ -35,6 +35,7 @@ #include "kernel/scheduler/scheduler.h" #include <stdexcept> #include <algorithm> +#include <string.h> /* Used by assembler context switch macros @@ -166,19 +167,12 @@ void startKernel() void *threadClass=base+((STACK_IDLE+CTXSAVE_ON_STACK+WATERMARK_LEN)/ sizeof(unsigned int)); Thread *idle=new (threadClass) Thread(base,STACK_IDLE); - //Fill watermark - for(unsigned int i=0;i<(WATERMARK_LEN/sizeof(unsigned int));i++) - { - *base=WATERMARK_FILL; - base++; - } - //Fill stack - for(unsigned int i=0; - i<((STACK_IDLE+CTXSAVE_ON_STACK)/sizeof(unsigned int));i++) - { - *base=STACK_FILL; - base++; - } + + //Fill watermark and stack + memset(base, WATERMARK_FILL, WATERMARK_LEN); + base+=WATERMARK_LEN/sizeof(unsigned int); + memset(base, STACK_FILL, STACK_IDLE); + //On some architectures some registers are saved on the stack, therefore //initCtxsave *must* be called after filling the stack. miosix_private::initCtxsave(idle->ctxsave,idleThread, @@ -312,19 +306,12 @@ Thread *Thread::create(void *(*startfunc)(void *), unsigned int stacksize, void *threadClass=base+((stacksize+WATERMARK_LEN+CTXSAVE_ON_STACK)/ sizeof(unsigned int)); Thread *thread=new (threadClass) Thread(base,stacksize); - //Fill watermark - for(unsigned int i=0;i<(WATERMARK_LEN/sizeof(unsigned int));i++) - { - *base=WATERMARK_FILL; - base++; - } - //Fill stack - for(unsigned int i=0; - i<((stacksize+CTXSAVE_ON_STACK)/sizeof(unsigned int));i++) - { - *base=STACK_FILL; - base++; - } + + //Fill watermark and stack + memset(base, WATERMARK_FILL, WATERMARK_LEN); + base+=WATERMARK_LEN/sizeof(unsigned int); + memset(base, STACK_FILL, stacksize); + //On some architectures some registers are saved on the stack, therefore //initCtxsave *must* be called after filling the stack. miosix_private::initCtxsave(thread->ctxsave,startfunc, diff --git a/miosix/util/version.cpp b/miosix/util/version.cpp index 134b69a3..10b7bce9 100644 --- a/miosix/util/version.cpp +++ b/miosix/util/version.cpp @@ -1,14 +1,21 @@ namespace miosix { -/** - * Kernel verision is stored in this string. - */ -const char *const versionString="Miosix v1.59"; +#ifdef __GNUC__ +#define tts(x) #x +#define ts(x) tts(x) +#define CV ", gcc "ts(__GNUC__)"."ts(__GNUC_MINOR__)"."ts(__GNUC_PATCHLEVEL__) +#define AU __attribute__((used)) +#else +#define CV +#define AU +#endif + +const char AU ver[]="Miosix v1.59 (" _MIOSIX ", " __DATE__ " " __TIME__ CV ")"; const char *getMiosixVersion() { - return versionString; + return ver; } } //namespace miosix diff --git a/miosix/util/version.h b/miosix/util/version.h index 715264d8..96d4b02d 100644 --- a/miosix/util/version.h +++ b/miosix/util/version.h @@ -38,7 +38,11 @@ namespace miosix { /** * Allows to know the version of the kernel at runtime. * \return a string with the kernel version. - * The format is "Miosix vX.XX" where X.XX is the version number + * The format is "Miosix vX.XX (board, builddate, compiler)" where + * vX.XX is the kernel version number, like "v1.59" + * board is the board name, like "stm32f103ze_stm3210e-eval" + * builddate is the date the kernel was built, like "Oct 30 2011 00:58:10" + * compiler is the compiler version, like "gcc 4.5.2" */ const char *getMiosixVersion(); -- GitLab