From 40442bff4c40bcf2e1d7a4fc19018cef68513ca5 Mon Sep 17 00:00:00 2001
From: Terraneo Federico <fede.tft@hotmail.it>
Date: Fri, 5 Apr 2013 00:34:12 +0200
Subject: [PATCH] Constructors of global objects moved from stage_1_boot to
 stage_2_boot

---
 miosix/Makefile                               |  1 +
 .../lpc2138_miosix_board/core/stage_1_boot.s  | 42 ---------
 .../lpc2138_miosix_board/drivers/serial.cpp   | 87 ++++++++++++-------
 .../cortexM3_stm32/common/drivers/serial.cpp  | 83 ++++++++++++------
 .../board_settings.h                          |  2 +-
 .../core/stage_1_boot.cpp                     | 31 +------
 .../stm32f103ve_mp3v2/core/stage_1_boot.cpp   | 31 +------
 .../interfaces-impl/hwmapping.h               |  2 +-
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/hwmapping.h               |  4 +
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/hwmapping.h               |  4 +
 .../core/stage_1_boot.cpp                     | 33 +------
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/console.cpp               | 44 +++++++---
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/console.cpp               | 44 +++++++---
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/console.cpp               | 44 +++++++---
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/console.cpp               | 45 +++++++---
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/console.cpp               | 44 +++++++---
 .../core/stage_1_boot.cpp                     | 31 +------
 .../interfaces-impl/console.cpp               | 44 +++++++---
 miosix/check_global_objects.pl                | 70 +++++++++++++++
 miosix/compiler/Readme.txt                    |  4 +-
 miosix/config/Makefile.inc                    |  4 +-
 miosix/doc/textdoc/Changelog.txt              | 16 ++++
 miosix/kernel/filesystem/filesystem.cpp       | 37 +++++---
 miosix/kernel/stage_2_boot.cpp                | 26 ++++++
 miosix/testsuite/testsuite.cpp                | 12 +++
 miosix/util/version.cpp                       |  2 +-
 miosix_np_2/nbproject/private/private.xml     |  2 +-
 34 files changed, 472 insertions(+), 534 deletions(-)
 create mode 100644 miosix/check_global_objects.pl

diff --git a/miosix/Makefile b/miosix/Makefile
index d5c6e82a..7944924a 100644
--- a/miosix/Makefile
+++ b/miosix/Makefile
@@ -46,6 +46,7 @@ AFLAGS   :=  $(AFLAGS_BASE)
 ## The file stage_1_boot.o is compiled separately because
 ## it must not end up in libmiosix.a
 all: $(OBJ) $(BOOT_FILE)
+	perl check_global_objects.pl $(OBJ)
 	$(AR) rcs libmiosix.a $(OBJ)
 
 clean:
diff --git a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/core/stage_1_boot.s b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/core/stage_1_boot.s
index 348783b5..6aeaaf06 100644
--- a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/core/stage_1_boot.s
+++ b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/core/stage_1_boot.s
@@ -83,16 +83,6 @@ Reset_Handler:
 2:  cmp	    r1, r2
     strlo    r0, [r1], #4
     blo	    2b
-    /* call static constructors. Supports both eabi and elf binary formats */
-    ldr	    r0, =__preinit_array_start
-    ldr	    r1, =__preinit_array_end
-    bl	    _call_constructors
-    ldr	    r0, =_ctor_start
-    ldr	    r1, =_ctor_end
-    bl	    _call_constructors
-    ldr	    r0, =__init_array_start
-    ldr	    r1, =__init_array_end
-    bl	    _call_constructors
     /* enter stage_2_boot. the lr (return address) is set to 0x00000000, so
     if main returns, it will jump to the reset vector, rebooting the system.
     Using bx instead of b to support thumb mode */
@@ -101,37 +91,5 @@ Reset_Handler:
     bx      r12
 
 .endfunc
-
-/*
-Some info about static constructors: by reading newlib and gcc sources, and by
-searching on the web it looks like static constructors are handled in a
-different way in every binary format. The common part is this: the compiler
-creates an array of function pointers, in a particular section. The startup
-code, before calling main(), calls every function in the array, initializing
-all static and global objets. But the name of the section is diferent: eabi
-compilers (like codesourcery gcc) place the array in .preinit_array,
-.init_array (for constructors) and .fini_array (for destructors) while elf
-compilers (like arm-elf-g++) place the array in .ctor (for constructors) and
-.dtor (for destructors). Constructors in .preinit_array and .init_array
-sections are called by the function __libc_init_array (defined in
-newlib-1.16.0/newlib/libc/misc/init.c). This function also calls _init, which
-is supposed to call constructors in .ctor section.
-By callng all constructors in .preint_array, .ctor and .init_array all
-consructors will be called regardless of the binary format (elf or eabi).
-This file has been used for over a year, so it is believed to be accurate.
-*/
-.func    _call_constructors
-_call_constructors:
-    stmfd   sp!, {lr}
-4:  cmp	    r0,r1
-    beq	    5f              /* 5f = forward reference to label  */
-    ldr	    r2, [r0], #4
-    stmfd   sp!, {r0-r1}
-    mov     lr, pc
-    bx      r2
-    ldmfd   sp!, {r0-r1}
-    b       4b              /* 4b = backward reference to label */
-5:  ldmfd   sp!, {pc}
-.endfunc
 	
 .end
diff --git a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/drivers/serial.cpp b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/drivers/serial.cpp
index 17e7703e..76cb5a75 100644
--- a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/drivers/serial.cpp
+++ b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/drivers/serial.cpp
@@ -34,20 +34,35 @@
 
 namespace miosix {
 
-//Configure the software queue here
-const int SOFTWARE_TX_QUEUE=32;///<\internal Size of tx software queue
-const int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
+class SerialData
+{
+public:
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    //Configure the software queue here
+    static const int SOFTWARE_TX_QUEUE=32;///<\internal Size of tx software queue
+    static const int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
 
-//The hardware queues cannot be modified, since their length is hardware-specific
-const int HARDWARE_TX_QUEUE_LENGTH=16;
-const int HARDWARE_RX_QUEUE_LENGTH=8;
+    //The hardware queues cannot be modified, since their length is hardware-specific
+    static const int HARDWARE_TX_QUEUE_LENGTH=16;
+    static const int HARDWARE_RX_QUEUE_LENGTH=8;
 
-//Static (local) variables
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    //Static (local) variables
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
 
-static Queue<char,SOFTWARE_TX_QUEUE> tx_queue;///<\internal Tx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    Queue<char,SOFTWARE_TX_QUEUE> txQueue;///<\internal Tx software queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 ///\internal True if a rx character found the queue full
 static volatile bool rxLostFlag=false;
@@ -63,6 +78,7 @@ static bool serialEnabled=false;///<\internal True if serial port is enabled
 void serial_irq_impl() __attribute__((noinline));
 void serial_irq_impl()
 {
+    SerialData& s=SerialData::instance();
     char c;
     int i;
     bool hppw=false;
@@ -73,21 +89,21 @@ void serial_irq_impl()
             c=U0RBR;//Read U0RBR to discard char that caused error
             break;
         case 0x4: //RDA
-            for(i=0;i<HARDWARE_RX_QUEUE_LENGTH;i++)
+            for(i=0;i<SerialData::HARDWARE_RX_QUEUE_LENGTH;i++)
             {
-                if(rxQueue.IRQput(U0RBR,hppw)==false) rxLostFlag=true;
+                if(s.rxQueue.IRQput(U0RBR,hppw)==false) rxLostFlag=true;
             }
         case 0xc: //CTI
             while(U0LSR & (1<<0))
             {
-                if(rxQueue.IRQput(U0RBR,hppw)==false) rxLostFlag=true;
+                if(s.rxQueue.IRQput(U0RBR,hppw)==false) rxLostFlag=true;
             }
             break;
         case 0x2: //THRE
-            for(i=0;i<HARDWARE_TX_QUEUE_LENGTH;i++)
+            for(i=0;i<SerialData::HARDWARE_TX_QUEUE_LENGTH;i++)
             {
                 //If software queue empty, stop
-                if(tx_queue.IRQget(c,hppw)==false) break;
+                if(s.txQueue.IRQget(c,hppw)==false) break;
                 U0THR=c;
             }
             break;
@@ -115,8 +131,9 @@ void serial_IRQ_Routine()
 
 void IRQserialInit(unsigned int div)
 {
-    tx_queue.IRQreset();
-    rxQueue.IRQreset();
+    SerialData& s=SerialData::instance();
+    s.txQueue.IRQreset();
+    s.rxQueue.IRQreset();
     PCONP|=(1<<3);//Enable UART0 peripheral
     U0LCR=0x3;//DLAB disabled
     //0x07= fifo enabled, reset tx and rx hardware fifos
@@ -141,8 +158,9 @@ void IRQserialInit(unsigned int div)
 
 void IRQserialDisable()
 {
+    SerialData& s=SerialData::instance();
     serialEnabled=false;
-    while(!(tx_queue.isEmpty() && IRQserialTxFifoEmpty())) ; //wait
+    while(!(s.txQueue.isEmpty() && IRQserialTxFifoEmpty())) ; //wait
     //Disable VIC
     VICIntEnClr=(1<<6);
     //Disable UART0
@@ -159,9 +177,10 @@ bool IRQisSerialEnabled()
 
 void serialWrite(const char *str, unsigned int len)
 {
+    SerialData& s=SerialData::instance();
     if(!serialEnabled) return;
     int i;
-    Lock<Mutex> l(txMutex);
+    Lock<Mutex> l(s.txMutex);
     {
         FastInterruptDisableLock dLock;
         while(len>0)
@@ -169,10 +188,10 @@ void serialWrite(const char *str, unsigned int len)
             //If somebody disables serial port while we are transmitting
             if(!serialEnabled) break;
             //If no data in software and hardware queue
-            if((U0LSR & (1<<5))&&(tx_queue.isEmpty()))
+            if((U0LSR & (1<<5))&&(s.txQueue.isEmpty()))
             {
                 //Fill hardware queue first
-                for(i=0;i<HARDWARE_TX_QUEUE_LENGTH;i++)
+                for(i=0;i<SerialData::HARDWARE_TX_QUEUE_LENGTH;i++)
                 {
                     U0THR=*str;
                     str++;
@@ -180,13 +199,13 @@ void serialWrite(const char *str, unsigned int len)
                     if(len==0) break;
                 }
             } else {
-                if(tx_queue.IRQput(*str)==true)
+                if(s.txQueue.IRQput(*str)==true)
                 {
                     str++;
                     len--;
                 } else {
                     FastInterruptEnableLock eLock(dLock);
-                    tx_queue.waitUntilNotFull();
+                    s.txQueue.waitUntilNotFull();
                 }
             }
         }
@@ -196,28 +215,30 @@ void serialWrite(const char *str, unsigned int len)
 bool serialTxComplete()
 {
     //If both hardware and software queue are empty, tx is complete.
-    return tx_queue.isEmpty() && IRQserialTxFifoEmpty();
+    return SerialData::instance().txQueue.isEmpty() && IRQserialTxFifoEmpty();
 }
 
 char serialReadChar()
 {
     char result;
-    rxMutex.lock();
-    rxQueue.get(result);
-    rxMutex.unlock();
+    SerialData& s=SerialData::instance();
+    s.rxMutex.lock();
+    s.rxQueue.get(result);
+    s.rxMutex.unlock();
     return result;
 }
 
 bool serialReadCharNonblocking(char& c)
 {
     bool result=false;
-    rxMutex.lock();
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    s.rxMutex.lock();
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         result=true;
     }
-    rxMutex.unlock();
+    s.rxMutex.unlock();
     return result;
 }
 
@@ -230,7 +251,7 @@ bool serialRxLost()
 
 void serialRxFlush()
 {
-    rxQueue.reset();
+    SerialData::instance().rxQueue.reset();
 }
 
 void IRQserialWriteString(const char *str)
diff --git a/miosix/arch/cortexM3_stm32/common/drivers/serial.cpp b/miosix/arch/cortexM3_stm32/common/drivers/serial.cpp
index 77b7e842..469ebab3 100644
--- a/miosix/arch/cortexM3_stm32/common/drivers/serial.cpp
+++ b/miosix/arch/cortexM3_stm32/common/drivers/serial.cpp
@@ -81,11 +81,38 @@ void DMA1_Channel4_IRQHandler()
 }
 #endif //__ENABLE_XRAM
 
-namespace miosix {
+namespace miosix { 
 
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
-const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+/**
+ * Groups objects used by the serial driver
+ */
+class SerialData
+{
+public:
+    /**
+     * \return an instance of this class (singleton) 
+     */
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    static const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    #ifndef __ENABLE_XRAM
+    static const unsigned int SOFTWARE_TX_QUEUE=32;///<\internal Size of tx queue
+    char tx_dma_buffer[SOFTWARE_TX_QUEUE];///<\internal Tx dma buffer
+    Queue<char,1> tx_queue;///<\internal Tx queue. Size is 1 because of dma
+    #endif //__ENABLE_XRAM
+
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 ///\internal True if a rx character found the queue full
 static volatile bool rxLostFlag=false;
@@ -101,6 +128,7 @@ static bool serialEnabled=false;///<\internal True if serial port is enabled
 void serial_irq_impl() __attribute__((noinline));
 void serial_irq_impl()
 {
+    SerialData& s=SerialData::instance();
     bool hppw=false;
     unsigned int status=USART1->SR;
     if(status & USART_SR_ORE) //Receiver overrun
@@ -108,24 +136,19 @@ void serial_irq_impl()
         rxLostFlag=true;
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & USART_SR_RXNE) && ((status & 0x7)==0))
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
     } else if(status & USART_SR_RXNE) //Receiver data available
     {
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & 0x7)==0) //If no noise nor framing nor parity error
         {
-            if(rxQueue.IRQput(c,hppw)==false) rxLostFlag=true;
+            if(s.rxQueue.IRQput(c,hppw)==false) rxLostFlag=true;
         }
     }
     if(hppw) Scheduler::IRQfindNextThread();
 }
 
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-
 #ifndef __ENABLE_XRAM
-const unsigned int SOFTWARE_TX_QUEUE=32;///<\internal Size of tx software queue
-static char tx_dma_buffer[SOFTWARE_TX_QUEUE];///<\internal Tx dma buffer
-static Queue<char,1> tx_queue;///<\internal Tx queue. Size is 1 because of dma
 
 /**
  * \internal
@@ -142,14 +165,15 @@ void serial_dma_impl()
     //Wake eventual waiting thread, and do context switch if priority is higher
     char useless;
     bool hppw=false;
-    tx_queue.IRQget(useless,hppw);
+    SerialData::instance().tx_queue.IRQget(useless,hppw);
     if(hppw) Scheduler::IRQfindNextThread();
 }
 
 void IRQserialInit()
 {
-    tx_queue.IRQreset();
-    rxQueue.IRQreset();
+    SerialData& s=SerialData::instance();
+    s.tx_queue.IRQreset();
+    s.rxQueue.IRQreset();
     //Enable clock to GPIOA, AFIO and USART1
     RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN |
             RCC_APB2ENR_USART1EN;
@@ -192,20 +216,21 @@ void IRQserialDisable()
     serialEnabled=false;
     while(!IRQserialTxFifoEmpty()) ; //wait
     USART1->CR1=0;
-    tx_queue.IRQreset(); //Wake eventual thread waiting
+    SerialData::instance().tx_queue.IRQreset(); //Wake eventual thread waiting
 }
 
 void serialWrite(const char *str, unsigned int len)
 {
     if(!serialEnabled) return;
-    Lock<Mutex> l(txMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.txMutex);
     for(;len>0;)
     {
         // This will block if the buffer is currently being handled by the dma.
         // The advantage of using a queue is that if the dma tranfer ends while
         // a thread with lower priority than the one that is waiting, a context
         // switch will happen.
-        tx_queue.put(0);
+        s.tx_queue.put(0);
 
         {
             FastInterruptDisableLock lock;
@@ -213,11 +238,11 @@ void serialWrite(const char *str, unsigned int len)
             if(!serialEnabled) return;
 
             // If we get here, the dma buffer is ready
-            unsigned int transferSize=std::min(len,SOFTWARE_TX_QUEUE);
-            memcpy(tx_dma_buffer,str,transferSize);
+            unsigned int transferSize=std::min(len,SerialData::SOFTWARE_TX_QUEUE);
+            memcpy(s.tx_dma_buffer,str,transferSize);
             // Setup DMA xfer
             DMA1_Channel4->CPAR=reinterpret_cast<unsigned int>(&USART1->DR);
-            DMA1_Channel4->CMAR=reinterpret_cast<unsigned int>(tx_dma_buffer);
+            DMA1_Channel4->CMAR=reinterpret_cast<unsigned int>(s.tx_dma_buffer);
             DMA1_Channel4->CNDTR=transferSize;
             DMA1_Channel4->CCR=DMA_CCR4_MINC | DMA_CCR4_DIR | DMA_CCR4_TEIE |
                     DMA_CCR4_TCIE | DMA_CCR4_EN;
@@ -262,7 +287,7 @@ void IRQserialWriteString(const char *str)
 
 void IRQserialInit()
 {
-    rxQueue.IRQreset();
+    SerialData::instance().rxQueue.IRQreset();
     //Enable clock to GPIOA, AFIO and USART1
     RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN |
             RCC_APB2ENR_USART1EN;
@@ -306,7 +331,7 @@ void serialWrite(const char *str, unsigned int len)
 {
     if(!serialEnabled) return;
     {
-        Lock<Mutex> l(txMutex);
+        Lock<Mutex> l(SerialData::instance().txMutex);
         for(unsigned int i=0;i<len;i++)
         {
             while((USART1->SR & USART_SR_TXE)==0)
@@ -345,18 +370,20 @@ bool serialTxComplete()
 
 char serialReadChar()
 {
-    Lock<Mutex> l(rxMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
     char result;
-    rxQueue.get(result);
+    s.rxQueue.get(result);
     return result;
 }
 
 bool serialReadCharNonblocking(char& c)
 {
-    Lock<Mutex> l(rxMutex);
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         return true;
     }
     return false;
@@ -371,7 +398,7 @@ bool serialRxLost()
 
 void serialRxFlush()
 {
-    rxQueue.reset();
+    SerialData::instance().rxQueue.reset();
 }
 
 bool IRQserialTxFifoEmpty()
diff --git a/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/board_settings.h b/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/board_settings.h
index 24b0175b..0239dfbc 100644
--- a/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/board_settings.h
+++ b/miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/board_settings.h
@@ -58,7 +58,7 @@ const unsigned int AUX_TIMER_MAX=0xffff; ///<\internal Aux timer is 16 bits
 ///If defined, stdout is redirected to the debug communication channel, and
 ///will be printed if OpenOCD is connected. If not defined, stdout will be
 ///redirected throug USART1, as usual.
-#define STDOUT_REDIRECTED_TO_DCC
+//#define STDOUT_REDIRECTED_TO_DCC
 
 /**
  * \}
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 7aed737c..ec923e72 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
@@ -7,8 +7,7 @@
  * startup.cpp
  * STM32 C++ startup.
  * NOTE: for stm32 medium density value line devices ONLY (64 and 128KB devices).
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -17,23 +16,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -62,12 +44,6 @@ void program_startup()
 	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");
-	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");
 
     //Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -78,11 +54,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
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 6d860a64..2c841de6 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
@@ -6,8 +6,7 @@
 /*
  * startup.cpp
  * STM32 C++ startup.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -16,23 +15,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -53,12 +35,6 @@ void program_startup()
 	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");
-	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");
 
 	//Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -69,11 +45,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/interfaces-impl/hwmapping.h b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/interfaces-impl/hwmapping.h
index 8c366402..fef4cd8f 100644
--- a/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/interfaces-impl/hwmapping.h
+++ b/miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/interfaces-impl/hwmapping.h
@@ -186,6 +186,6 @@ typedef Gpio<GPIOB_BASE,8>  pb8; //used to be Charger::en
 
 #ifdef _MIOSIX
 } //namespace miosix
-#else //_MIOSIX
+#endif //_MIOSIX
 
 #endif //HWMAPPING_H
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 5f4cc399..4e4bb0b3 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
@@ -6,8 +6,7 @@
 /*
  * startup.cpp
  * STM32 C++ startup.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -16,23 +15,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -61,12 +43,6 @@ void program_startup()
 	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");
-	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");
 
 	//Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -77,11 +53,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/interfaces-impl/hwmapping.h b/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/interfaces-impl/hwmapping.h
index 016c9c81..5d4babe9 100644
--- a/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/interfaces-impl/hwmapping.h
+++ b/miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/interfaces-impl/hwmapping.h
@@ -29,6 +29,7 @@
 #define HWMAPPING_H
 
 #include "interfaces/gpio.h"
+namespace miosix {
 
 //
 // All GPIOs are mapped here
@@ -103,4 +104,7 @@ typedef Gpio<GPIOA_BASE,10> rx;     //Handled by hardware (USART1)
 namespace buttons {
     typedef Gpio<GPIOB_BASE,15> button1;
 }
+
+} //namespace miosix
+
 #endif //HWMAPPING_H
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 dbd9d18b..946bb0e5 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
@@ -6,8 +6,7 @@
 /*
  * startup.cpp
  * STM32 C++ startup.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -16,23 +15,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -61,12 +43,6 @@ void program_startup()
 	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");
-	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");
 
 	//Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -83,11 +59,6 @@ void program_startup()
     #endif //__CODE_IN_XRAM
     memset(bss_start, 0, bss_end-bss_start);
 
-	//Initialize C++ global constructors
-	call_constructors(&__preinit_array_start, &__preinit_array_end);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/interfaces-impl/hwmapping.h b/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/interfaces-impl/hwmapping.h
index 8501789a..69cb8a01 100644
--- a/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/interfaces-impl/hwmapping.h
+++ b/miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/interfaces-impl/hwmapping.h
@@ -30,6 +30,8 @@
 
 #include "interfaces/gpio.h"
 
+namespace miosix {
+
 //
 // All GPIOs are mapped here
 //
@@ -135,4 +137,6 @@ namespace buttons {
     typedef Gpio<GPIOD_BASE,3> user2;
 }
 
+} //namespace miosix
+
 #endif //HWMAPPING_H
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 d9c12a0b..a33ff9b6 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
@@ -6,8 +6,7 @@
 /*
  * startup.cpp
  * STM32 C++ startup.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -16,23 +15,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -49,13 +31,7 @@ void program_startup()
 	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");
-	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");
-
+	
 	//Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
     unsigned char *data=&_data;
@@ -71,11 +47,6 @@ void program_startup()
     #endif //__CODE_IN_XRAM
     memset(bss_start, 0, bss_end-bss_start);
 
-	//Initialize C++ global constructors
-	call_constructors(&__preinit_array_start, &__preinit_array_end);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
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 18663fb1..cd799411 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
@@ -7,8 +7,7 @@
  * startup.cpp
  * STM32 C++ startup.
  * NOTE: for stm32f2 devices ONLY.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -17,23 +16,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -50,12 +32,6 @@ void program_startup()
 	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");
-	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");
 
     //Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -72,11 +48,6 @@ void program_startup()
     #endif //__CODE_IN_XRAM
     memset(bss_start, 0, bss_end-bss_start);
 
-	//Initialize C++ global constructors
-	call_constructors(&__preinit_array_start, &__preinit_array_end);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/console.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/console.cpp
index 56d69a98..72a957df 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/console.cpp
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/console.cpp
@@ -64,10 +64,25 @@ void USART3_IRQHandler()
 
 namespace miosix {
 
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+class SerialData
+{
+public:
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    static const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 /**
  * \internal
@@ -79,19 +94,20 @@ static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
 void serialIrqImpl() __attribute__((noinline));
 void serialIrqImpl()
 {
+    SerialData& s=SerialData::instance();
     bool hppw=false;
     unsigned int status=USART3->SR;
     if(status & USART_SR_ORE) //Receiver overrun
     {
         char c=USART3->DR; //Always read data, since this clears interrupt flags
         if((status & USART_SR_RXNE) && ((status & 0x7)==0))
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
     } else if(status & USART_SR_RXNE) //Receiver data available
     {
         char c=USART3->DR; //Always read data, since this clears interrupt flags
         if((status & 0x7)==0) //If no noise nor framing nor parity error
         {
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
         }
     }
     if(hppw) Scheduler::IRQfindNextThread();
@@ -99,7 +115,7 @@ void serialIrqImpl()
 
 void IRQstm32f2serialPortInit()
 {
-    rxQueue.IRQreset();
+    SerialData::instance().rxQueue.IRQreset();
     //Enable clock to GPIOC and USART3
     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
     RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
@@ -130,7 +146,7 @@ void IRQstm32f2serialPortInit()
 static void serialWriteImpl(const char *str, unsigned int len)
 {
     {
-        Lock<Mutex> l(txMutex);
+        Lock<Mutex> l(SerialData::instance().txMutex);
         for(unsigned int i=0;i<len;i++)
         {
             while((USART3->SR & USART_SR_TXE)==0) ;
@@ -171,18 +187,20 @@ bool Console::IRQtxComplete()
 
 char Console::readChar()
 {
-    Lock<Mutex> l(rxMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
     char result;
-    rxQueue.get(result);
+    s.rxQueue.get(result);
     return result;
 }
 
 bool Console::readCharNonBlocking(char& c)
 {
-    Lock<Mutex> l(rxMutex);
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         return true;
     }
     return false;
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 16c8c7af..386b8b61 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
@@ -7,8 +7,7 @@
  * startup.cpp
  * STM32 C++ startup.
  * NOTE: for stm32f2 devices ONLY.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -17,23 +16,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -50,12 +32,6 @@ void program_startup()
 	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");
-	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");
 
     //Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -70,11 +46,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/interfaces-impl/console.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/interfaces-impl/console.cpp
index 04ef0d7f..e75ca2b0 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/interfaces-impl/console.cpp
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207ze_als_camboard/interfaces-impl/console.cpp
@@ -57,10 +57,25 @@ void USART1_IRQHandler()
 
 namespace miosix {
 
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+class SerialData
+{
+public:
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    static const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 /**
  * \internal
@@ -72,19 +87,20 @@ static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
 void serialIrqImpl() __attribute__((noinline));
 void serialIrqImpl()
 {
+    SerialData& s=SerialData::instance();
     bool hppw=false;
     unsigned int status=USART1->SR;
     if(status & USART_SR_ORE) //Receiver overrun
     {
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & USART_SR_RXNE) && ((status & 0x7)==0))
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
     } else if(status & USART_SR_RXNE) //Receiver data available
     {
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & 0x7)==0) //If no noise nor framing nor parity error
         {
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
         }
     }
     if(hppw) Scheduler::IRQfindNextThread();
@@ -92,7 +108,7 @@ void serialIrqImpl()
 
 void IRQstm32f2serialPortInit()
 {
-    rxQueue.IRQreset();
+    SerialData::instance().rxQueue.IRQreset();
     //Enable clock to GPIOA and USART1
     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
     RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
@@ -123,7 +139,7 @@ void IRQstm32f2serialPortInit()
 static void serialWriteImpl(const char *str, unsigned int len)
 {
     {
-        Lock<Mutex> l(txMutex);
+        Lock<Mutex> l(SerialData::instance().txMutex);
         for(unsigned int i=0;i<len;i++)
         {
             while((USART1->SR & USART_SR_TXE)==0) ;
@@ -164,18 +180,20 @@ bool Console::IRQtxComplete()
 
 char Console::readChar()
 {
-    Lock<Mutex> l(rxMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
     char result;
-    rxQueue.get(result);
+    s.rxQueue.get(result);
     return result;
 }
 
 bool Console::readCharNonBlocking(char& c)
 {
-    Lock<Mutex> l(rxMutex);
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         return true;
     }
     return false;
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 16c8c7af..386b8b61 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
@@ -7,8 +7,7 @@
  * startup.cpp
  * STM32 C++ startup.
  * NOTE: for stm32f2 devices ONLY.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -17,23 +16,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -50,12 +32,6 @@ void program_startup()
 	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");
-	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");
 
     //Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -70,11 +46,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/console.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/console.cpp
index 04ef0d7f..e75ca2b0 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/console.cpp
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/console.cpp
@@ -57,10 +57,25 @@ void USART1_IRQHandler()
 
 namespace miosix {
 
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+class SerialData
+{
+public:
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    static const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 /**
  * \internal
@@ -72,19 +87,20 @@ static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
 void serialIrqImpl() __attribute__((noinline));
 void serialIrqImpl()
 {
+    SerialData& s=SerialData::instance();
     bool hppw=false;
     unsigned int status=USART1->SR;
     if(status & USART_SR_ORE) //Receiver overrun
     {
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & USART_SR_RXNE) && ((status & 0x7)==0))
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
     } else if(status & USART_SR_RXNE) //Receiver data available
     {
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & 0x7)==0) //If no noise nor framing nor parity error
         {
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
         }
     }
     if(hppw) Scheduler::IRQfindNextThread();
@@ -92,7 +108,7 @@ void serialIrqImpl()
 
 void IRQstm32f2serialPortInit()
 {
-    rxQueue.IRQreset();
+    SerialData::instance().rxQueue.IRQreset();
     //Enable clock to GPIOA and USART1
     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
     RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
@@ -123,7 +139,7 @@ void IRQstm32f2serialPortInit()
 static void serialWriteImpl(const char *str, unsigned int len)
 {
     {
-        Lock<Mutex> l(txMutex);
+        Lock<Mutex> l(SerialData::instance().txMutex);
         for(unsigned int i=0;i<len;i++)
         {
             while((USART1->SR & USART_SR_TXE)==0) ;
@@ -164,18 +180,20 @@ bool Console::IRQtxComplete()
 
 char Console::readChar()
 {
-    Lock<Mutex> l(rxMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
     char result;
-    rxQueue.get(result);
+    s.rxQueue.get(result);
     return result;
 }
 
 bool Console::readCharNonBlocking(char& c)
 {
-    Lock<Mutex> l(rxMutex);
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         return true;
     }
     return false;
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 cc404ea5..7c986c1f 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
@@ -7,8 +7,7 @@
  * startup.cpp
  * STM32 C++ startup.
  * NOTE: for stm32l medium density devices ONLY.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -17,23 +16,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -50,12 +32,6 @@ void program_startup()
 	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");
-	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");
 
     //Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -70,11 +46,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/interfaces-impl/console.cpp b/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/interfaces-impl/console.cpp
index 75b059e9..deb89fc8 100644
--- a/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/interfaces-impl/console.cpp
+++ b/miosix/arch/cortexM3_stm32l1/stm32l151c8_als_mainboard/interfaces-impl/console.cpp
@@ -57,10 +57,26 @@ void USART1_IRQHandler()
 
 namespace miosix {
 
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+
+class SerialData
+{
+public:
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    static const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 /**
  * \internal
@@ -72,19 +88,20 @@ static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
 void serialIrqImpl() __attribute__((noinline));
 void serialIrqImpl()
 {
+    SerialData& s=SerialData::instance();
     bool hppw=false;
     unsigned int status=USART1->SR;
     if(status & USART_SR_ORE) //Receiver overrun
     {
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & USART_SR_RXNE) && ((status & 0x7)==0))
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
     } else if(status & USART_SR_RXNE) //Receiver data available
     {
         char c=USART1->DR; //Always read data, since this clears interrupt flags
         if((status & 0x7)==0) //If no noise nor framing nor parity error
         {
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
         }
     }
     if(hppw) Scheduler::IRQfindNextThread();
@@ -92,7 +109,7 @@ void serialIrqImpl()
 
 void IRQstm32f2serialPortInit()
 {
-    rxQueue.IRQreset();
+    SerialData::instance().rxQueue.IRQreset();
     //Enable clock to USART1
     RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
     //Enabled, 8 data bit, no parity, interrupt on character rx
@@ -118,7 +135,7 @@ void IRQstm32f2serialPortInit()
 static void serialWriteImpl(const char *str, unsigned int len)
 {
     {
-        Lock<Mutex> l(txMutex);
+        Lock<Mutex> l(SerialData::instance().txMutex);
         for(unsigned int i=0;i<len;i++)
         {
             while((USART1->SR & USART_SR_TXE)==0) ;
@@ -159,18 +176,20 @@ bool Console::IRQtxComplete()
 
 char Console::readChar()
 {
-    Lock<Mutex> l(rxMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
     char result;
-    rxQueue.get(result);
+    s.rxQueue.get(result);
     return result;
 }
 
 bool Console::readCharNonBlocking(char& c)
 {
-    Lock<Mutex> l(rxMutex);
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         return true;
     }
     return false;
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 18bbad62..febde445 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
@@ -7,8 +7,7 @@
  * startup.cpp
  * STM32 C++ startup.
  * NOTE: for stm32f4 devices ONLY.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -17,23 +16,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -62,12 +44,6 @@ void program_startup()
 	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");
-	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");
 
     //Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -78,11 +54,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/console.cpp b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/console.cpp
index 050175fe..1ab9ea51 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/console.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/console.cpp
@@ -64,10 +64,25 @@ void USART3_IRQHandler()
 
 namespace miosix {
 
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+class SerialData
+{
+public:
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    static const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 /**
  * \internal
@@ -79,19 +94,20 @@ static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
 void serialIrqImpl() __attribute__((noinline));
 void serialIrqImpl()
 {
+    SerialData& s=SerialData::instance();
     bool hppw=false;
     unsigned int status=USART3->SR;
     if(status & USART_SR_ORE) //Receiver overrun
     {
         char c=USART3->DR; //Always read data, since this clears interrupt flags
         if((status & USART_SR_RXNE) && ((status & 0x7)==0))
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
     } else if(status & USART_SR_RXNE) //Receiver data available
     {
         char c=USART3->DR; //Always read data, since this clears interrupt flags
         if((status & 0x7)==0) //If no noise nor framing nor parity error
         {
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
         }
     }
     if(hppw) Scheduler::IRQfindNextThread();
@@ -99,7 +115,7 @@ void serialIrqImpl()
 
 void IRQBitsBoardSerialPortInit()
 {
-    rxQueue.IRQreset();
+    SerialData::instance().rxQueue.IRQreset();
     //Enable clock to USART3
     RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
     //Enabled, 8 data bit, no parity, interrupt on character rx
@@ -129,7 +145,7 @@ void IRQBitsBoardSerialPortInit()
 static void serialWriteImpl(const char *str, unsigned int len)
 {
     {
-        Lock<Mutex> l(txMutex);
+        Lock<Mutex> l(SerialData::instance().txMutex);
         for(unsigned int i=0;i<len;i++)
         {
             while((USART3->SR & USART_SR_TXE)==0) ;
@@ -170,18 +186,20 @@ bool Console::IRQtxComplete()
 
 char Console::readChar()
 {
-    Lock<Mutex> l(rxMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
     char result;
-    rxQueue.get(result);
+    s.rxQueue.get(result);
     return result;
 }
 
 bool Console::readCharNonBlocking(char& c)
 {
-    Lock<Mutex> l(rxMutex);
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         return true;
     }
     return false;
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 18bbad62..febde445 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
@@ -7,8 +7,7 @@
  * startup.cpp
  * STM32 C++ startup.
  * NOTE: for stm32f4 devices ONLY.
- * - supports interrupt handlers in C++ without extern "C"
- * - global constructors are correctly called before main()
+ * Supports interrupt handlers in C++ without extern "C"
  * Developed by Terraneo Federico, based on ST startup code.
  * Additionally modified to boot Miosix.
  */
@@ -17,23 +16,6 @@
 //stage_2_boot.cpp
 extern "C" void _init();
 
-/**
- * Calls C++ global constructors
- * \param start first function pointer to call
- * \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)
-{
-	for(unsigned long *i=start; i<end; i++)
-	{
-		void (*funcptr)();
-        funcptr=reinterpret_cast<void (*)()>(*i);
-		funcptr();
-	}
-}
-
 /**
  * Called by Reset_Handler, performs initialization and calls main.
  * Never returns.
@@ -62,12 +44,6 @@ void program_startup()
 	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");
-	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");
 
     //Initialize .data section, clear .bss section
     unsigned char *etext=&_etext;
@@ -78,11 +54,6 @@ void program_startup()
     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);
-	call_constructors(&__init_array_start, &__init_array_end);
-	call_constructors(&_ctor_start, &_ctor_end);
-
 	//Move on to stage 2
 	_init();
 
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/console.cpp b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/console.cpp
index 4874d317..3147ad92 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/console.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/console.cpp
@@ -64,10 +64,25 @@ void USART2_IRQHandler()
 
 namespace miosix {
 
-static Mutex rxMutex;///<\internal Mutex used to guard the rx queue
-static Mutex txMutex;///<\internal Mutex used to guard the tx queue
-const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx software queue
-static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+class SerialData
+{
+public:
+    static SerialData& instance()
+    {
+        static SerialData s;
+        return s;
+    }
+    
+    Mutex rxMutex;///<\internal Mutex used to guard the rx queue
+    Mutex txMutex;///<\internal Mutex used to guard the tx queue
+    static const unsigned int SOFTWARE_RX_QUEUE=32;///<\internal Size of rx queue
+    Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
+    
+private:
+    SerialData() {}
+    SerialData(const SerialData&);
+    SerialData& operator= (const SerialData&);
+};
 
 /**
  * \internal
@@ -79,19 +94,20 @@ static Queue<char,SOFTWARE_RX_QUEUE> rxQueue;///<\internal Rx software queue
 void serialIrqImpl() __attribute__((noinline));
 void serialIrqImpl()
 {
+    SerialData& s=SerialData::instance();
     bool hppw=false;
     unsigned int status=USART2->SR;
     if(status & USART_SR_ORE) //Receiver overrun
     {
         char c=USART2->DR; //Always read data, since this clears interrupt flags
         if((status & USART_SR_RXNE) && ((status & 0x7)==0))
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
     } else if(status & USART_SR_RXNE) //Receiver data available
     {
         char c=USART2->DR; //Always read data, since this clears interrupt flags
         if((status & 0x7)==0) //If no noise nor framing nor parity error
         {
-            rxQueue.IRQput(c,hppw);
+            s.rxQueue.IRQput(c,hppw);
         }
     }
     if(hppw) Scheduler::IRQfindNextThread();
@@ -99,7 +115,7 @@ void serialIrqImpl()
 
 void IRQstm32f4serialPortInit()
 {
-    rxQueue.IRQreset();
+    SerialData::instance().rxQueue.IRQreset();
     //Enable clock to GPIOA and USART2
     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
     RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
@@ -133,7 +149,7 @@ void IRQstm32f4serialPortInit()
 static void serialWriteImpl(const char *str, unsigned int len)
 {
     {
-        Lock<Mutex> l(txMutex);
+        Lock<Mutex> l(SerialData::instance().txMutex);
         for(unsigned int i=0;i<len;i++)
         {
             while((USART2->SR & USART_SR_TXE)==0) ;
@@ -174,18 +190,20 @@ bool Console::IRQtxComplete()
 
 char Console::readChar()
 {
-    Lock<Mutex> l(rxMutex);
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(SerialData::instance().rxMutex);
     char result;
-    rxQueue.get(result);
+    SerialData::instance().rxQueue.get(result);
     return result;
 }
 
 bool Console::readCharNonBlocking(char& c)
 {
-    Lock<Mutex> l(rxMutex);
-    if(rxQueue.isEmpty()==false)
+    SerialData& s=SerialData::instance();
+    Lock<Mutex> l(s.rxMutex);
+    if(s.rxQueue.isEmpty()==false)
     {
-        rxQueue.get(c);
+        s.rxQueue.get(c);
         return true;
     }
     return false;
diff --git a/miosix/check_global_objects.pl b/miosix/check_global_objects.pl
new file mode 100644
index 00000000..82c86539
--- /dev/null
+++ b/miosix/check_global_objects.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+#
+# This program checks that there are no global objects in the kernel code.
+# usage: perl check_global_objects.pl <list of .o files to check>
+# returns 0 on success, 1 on failure. In this case the list of files with
+# global objects will be printed.
+#
+# This program is useful to prevent the use of global constructors.
+# This is because the use of global constructors in a kernel creates the
+# problem of when to call those constructors.
+# 
+# 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, global constructors are called as late as
+# possible, right before calling main(), when the kernel is already started.
+# However by doing so it is important that global constructors are never used
+# inside the kernel itself, as this creates the possibility of accessing an
+# object before its constructor is called. To be sure that this does not happen
+# a way is needed to automatically check that no global constructors are used
+# in the kernel code. Fortunately, this is possible, and this program does
+# just that.
+#
+
+use warnings;
+use strict;
+
+my @broken_files;
+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+) /);
+		$sections++;
+
+		# Look for .preinit_array* .init_array* .fini_array* .ctors* .dtors*
+		# sections. These are the sign that the file has global constructors.
+		if($1=~/^\.preinit_array|^\.init_array|^\.ctors|^\.fini_array|^\.dtors/)
+		{
+			push(@broken_files,$filename);
+		}
+	}
+
+	# Sanity check, if a file has no sections probably something is wrong
+	die "$filename has no sections. Something is wrong." unless $sections>0;
+}
+
+if(@broken_files!=0)
+{
+	print("check_global_objects.pl: Error: @broken_files contain global constructors\n");
+	exit(1);
+}
diff --git a/miosix/compiler/Readme.txt b/miosix/compiler/Readme.txt
index 70ae37e6..9f949c86 100644
--- a/miosix/compiler/Readme.txt
+++ b/miosix/compiler/Readme.txt
@@ -19,10 +19,10 @@ Install the following dependencies:
 gcc, g++, make, ncurses, byacc, flex, texinfo, patch, gmp, mpfr, mpc, tar, unzip, libelf
 
 For example, for Ubuntu/Kubuntu open a shell and type:
-sudo apt-get install gcc g++ make libncurses5-dev byacc flex texinfo patch libgmp3-dev libmpfr-dev libmpc-dev tar unzip libelf-dev
+sudo apt-get install gcc g++ make libncurses5-dev byacc flex texinfo patch libgmp3-dev libmpfr-dev libmpc-dev tar unzip libelf-dev perl
 
 While on Fedora:
-sudo yum intall gcc gcc-c++ make ncurses-devel byacc flex texinfo patch gmp-devel mpfr-devel libmpc-devel tar unzip elfutils-libelf-devel
+sudo yum intall gcc gcc-c++ make ncurses-devel byacc flex texinfo patch gmp-devel mpfr-devel libmpc-devel tar unzip elfutils-libelf-devel perl
 
 Note: these scripts require "sudo". If you use a distro like Fedora where sudo
 is not enabled by default, use "visudo" to enable sudo for your account. You
diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc
index 7dddd530..56ee2d60 100644
--- a/miosix/config/Makefile.inc
+++ b/miosix/config/Makefile.inc
@@ -259,8 +259,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_BOARDNAME=\"$(OPT_BOARD)\"
-CXXFLAGS_BASE := -D_MIOSIX_BOARDNAME=\"$(OPT_BOARD)\"
+CFLAGS_BASE   := -D_MIOSIX_BOARDNAME=\"$(OPT_BOARD)\" -Wno-unused-but-set-variable
+CXXFLAGS_BASE := -D_MIOSIX_BOARDNAME=\"$(OPT_BOARD)\" -Wno-unused-but-set-variable
 
 ##
 ## 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 9b10e870..50539f50 100644
--- a/miosix/doc/textdoc/Changelog.txt
+++ b/miosix/doc/textdoc/Changelog.txt
@@ -1,5 +1,21 @@
 Changelog for Miosix np embedded OS
 
+- Changed version number from v1.61 to v20.alpha1 in version.cpp.
+- Added -Wno-unused-but-set-variable to Makefile.
+- Added testsuite check for global objects support outside of the kernel.
+- Removed the use of global objects in the serial port drivers.
+- Breaking change regarding constructors of global objects. Up to Miosix v1.61
+  they were called during stage_1_boot, therefore before the kernel was
+  started. They are now called in stage_2_boot, right before calling main.
+  This results in a more intuitive behaviour, as it is now possible to
+  write on stdout, access the filesystem, create threads, etc. within
+  constructors of global objects. On the downside it is no longer possible to
+  instantiate global objects withing the kernel itself, as this would cause
+  the risk of accessing objects before their constructor has run. The lack of
+  global objects is actively check by check_global_objects.pl at compile time
+  to prevent errors.
+- Changed stm32vldiscovery default stdio redirection from the DCC to the
+  serial port.
 - Added stm32f4 sdio driver, tested on stm32f4discovery.
 - Improved the SDIO drivers for both stm32f1 and stm32f2. It now uses
   DMA transfers whenever possible. In the stm32f2 it is always possible,
diff --git a/miosix/kernel/filesystem/filesystem.cpp b/miosix/kernel/filesystem/filesystem.cpp
index 3133163e..66785d8d 100644
--- a/miosix/kernel/filesystem/filesystem.cpp
+++ b/miosix/kernel/filesystem/filesystem.cpp
@@ -36,7 +36,16 @@
 
 namespace miosix {
 
-static Mutex fsMutex;///\internal This Mutex is used to guard access to the fs.
+/**
+ * \internal
+ * \return the Mutex that is used to guard access to the fs.
+ */
+Mutex& getFsMutex()
+{
+    static Mutex fsMutex;
+    return fsMutex;
+}
+
 
 //
 // class Filesystem
@@ -54,7 +63,7 @@ char Filesystem::mount()
     if(mounted==true) return 3; //If filesystem already mounted, return error
     char result=0;
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
         //Mount filesystem
         if(f_mount(0,&filesystem)!=FR_OK) result=1;
         //Fatfs will delay actual filesystem mount until the first request is
@@ -68,7 +77,7 @@ char Filesystem::mount()
 
 void Filesystem::umount()
 {
-    Lock<Mutex> l(fsMutex);
+    Lock<Mutex> l(getFsMutex());
     if(mounted==false) return;
     mounted=false;
 
@@ -92,7 +101,7 @@ int Filesystem::openFile(const char *name, int flags, int mode)
     if(isMounted()==false) return -1;
 
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
         
         int index=findAndFillEmptySlot();//Also fills in the file descriptor
         if(index==-1) return -1;
@@ -160,7 +169,7 @@ int Filesystem::readFile(int fd, void *buffer, int bufSize)
     if(isMounted()==false) return -1;
 
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
 
         //Find file from descriptor
         int index=findSlot(fd);
@@ -179,7 +188,7 @@ int Filesystem::writeFile(int fd, const void *buffer, int bufSize)
     if(isMounted()==false) return -1;
 
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
 
         //Find file from descriptor
         int index=findSlot(fd);
@@ -203,7 +212,7 @@ int Filesystem::lseekFile(int fd, int pos, int whence)
     if(isMounted()==false) return -1;
 
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
 
         //Find file from descriptor
         int index=findSlot(fd);
@@ -236,7 +245,7 @@ int Filesystem::fstatFile(int fd, struct stat *pstat)
     if(isMounted()==false) return -1;
 
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
 
         //Find file from descriptor
         int index=findSlot(fd);
@@ -256,7 +265,7 @@ int Filesystem::statFile(const char *file, struct stat *pstat)
     if(isMounted()==false) return -1;
     FILINFO info;
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
         if(f_stat(file,&info)!=FR_OK) return -1;
     }
     memset(pstat,0,sizeof(struct stat));
@@ -272,7 +281,7 @@ int Filesystem::closeFile(int fd)
     if(isMounted()==false) return -1;
 
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
 
         //Find file from descriptor
         int index=findSlot(fd);
@@ -297,7 +306,7 @@ int Filesystem::mkdir(const char *path, int mode)
     if(isMounted()==false) return -1;
     
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
         switch(f_mkdir(path))
         {
             case FR_OK:
@@ -315,7 +324,7 @@ int Filesystem::unlink(const char *path)
     if(isMounted()==false) return -1;
 
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
         if(f_unlink(path)!=FR_OK) return -1;
         return 0;
     }
@@ -416,7 +425,7 @@ char Directory::open(const char *name)
     if(Filesystem::instance().isMounted()==false) return 3;
     
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
         if(f_opendir(&d,name)!=FR_OK) return 1;
         return 0;
     }
@@ -426,7 +435,7 @@ bool Directory::next(char *name, unsigned int& size, unsigned char& attrib)
 {
     FILINFO fi;
     {
-        Lock<Mutex> l(fsMutex);
+        Lock<Mutex> l(getFsMutex());
         if(f_readdir(&d,&fi)!=FR_OK) return false;
     }
     
diff --git a/miosix/kernel/stage_2_boot.cpp b/miosix/kernel/stage_2_boot.cpp
index c38d434a..afa2a5b2 100644
--- a/miosix/kernel/stage_2_boot.cpp
+++ b/miosix/kernel/stage_2_boot.cpp
@@ -53,6 +53,21 @@ extern int main(int argc, char *argv[]);
 
 namespace miosix {
 
+/**
+ * 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)
+{
+	for(unsigned long *i=start; i<end; i++)
+	{
+		void (*funcptr)();
+        funcptr=reinterpret_cast<void (*)()>(*i);
+		funcptr();
+	}
+}
+
 /**
  * \internal
  * Performs the part of initialization that must be done after the kernel is
@@ -96,6 +111,17 @@ static void mainLoader(void *argv)
             MemoryProfiling::getHeapSize());
     #endif
 
+    //Initialize C++ global constructors
+    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);
+    
     //Run application code
     #ifdef __NO_EXCEPTIONS
     main(0,NULL);
diff --git a/miosix/testsuite/testsuite.cpp b/miosix/testsuite/testsuite.cpp
index 6950a9cc..80ecfa70 100644
--- a/miosix/testsuite/testsuite.cpp
+++ b/miosix/testsuite/testsuite.cpp
@@ -2233,6 +2233,8 @@ tests:
 C++ static constructors
 */
 
+static unsigned char t17_v1=0;
+
 class TestStaticConstructor
 {
 public:
@@ -2252,6 +2254,14 @@ static TestStaticConstructor& instance()
     return singleton;
 }
 
+class TestOneCallToStaticConstructor
+{
+public:
+    TestOneCallToStaticConstructor() { t17_v1++; }
+};
+
+TestOneCallToStaticConstructor t17_v2;
+
 static void test_17()
 {
     test_name("static constructors");
@@ -2260,6 +2270,8 @@ static void test_17()
         iprintf("a=0x%x, b=0x%x\n",instance().a, instance().b);
         fail("constructor fail");
     }
+    // Fails both if never called or if called multiple times 
+    if(t17_v1!=1) fail("Constructor error");
     pass();
 }
 
diff --git a/miosix/util/version.cpp b/miosix/util/version.cpp
index 25a5d730..0f29366d 100644
--- a/miosix/util/version.cpp
+++ b/miosix/util/version.cpp
@@ -37,7 +37,7 @@ namespace miosix {
 #define AU
 #endif
 
-const char AU ver[]="Miosix v1.61 (" _MIOSIX_BOARDNAME ", " __DATE__ " " __TIME__ CV ")";
+const char AU ver[]="Miosix v2.0alpha1 (" _MIOSIX_BOARDNAME ", " __DATE__ " " __TIME__ CV ")";
 
 const char *getMiosixVersion()
 {
diff --git a/miosix_np_2/nbproject/private/private.xml b/miosix_np_2/nbproject/private/private.xml
index e67bac43..2bcf1ef4 100644
--- a/miosix_np_2/nbproject/private/private.xml
+++ b/miosix_np_2/nbproject/private/private.xml
@@ -5,7 +5,7 @@
     </code-assistance-data>
     <data xmlns="http://www.netbeans.org/ns/make-project-private/1">
         <activeConfTypeElem>0</activeConfTypeElem>
-        <activeConfIndexElem>9</activeConfIndexElem>
+        <activeConfIndexElem>2</activeConfIndexElem>
     </data>
     <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
 </project-private>
-- 
GitLab