diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/core/stage_1_boot.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/core/stage_1_boot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6c5eb89a8198d1b2754ca2be9c8ee3531d00cc69
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/core/stage_1_boot.cpp
@@ -0,0 +1,413 @@
+
+#include "interfaces/arch_registers.h"
+#include "interfaces/bsp.h"
+#include "core/interrupts.h" //For the unexpected interrupt call
+#include "kernel/stage_2_boot.h"
+#include <string.h>
+
+/*
+ * startup.cpp
+ * STM32 C++ startup.
+ * NOTE: for stm32f42x devices ONLY.
+ * Supports interrupt handlers in C++ without extern "C"
+ * Developed by Terraneo Federico, based on ST startup code.
+ * Additionally modified to boot Miosix.
+ */
+
+/**
+ * Called by Reset_Handler, performs initialization and calls main.
+ * Never returns.
+ */
+void program_startup() __attribute__((noreturn));
+void program_startup()
+{
+    //Cortex M3 core appears to get out of reset with interrupts already enabled
+    __disable_irq();
+
+	//These are defined in the linker script
+	extern unsigned char _etext asm("_etext");
+	extern unsigned char _data asm("_data");
+	extern unsigned char _edata asm("_edata");
+	extern unsigned char _bss_start asm("_bss_start");
+	extern unsigned char _bss_end asm("_bss_end");
+
+    //Initialize .data section, clear .bss section
+    unsigned char *etext=&_etext;
+    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);
+
+	//Move on to stage 2
+	_init();
+
+	//If main returns, reboot
+	NVIC_SystemReset();
+    for(;;) ;
+}
+
+/**
+ * Reset handler, called by hardware immediately after reset
+ */
+void Reset_Handler() __attribute__((__interrupt__, noreturn));
+void Reset_Handler()
+{
+    //SystemInit() is called *before* initializing .data and zeroing .bss
+	//Despite all startup files provided by ST do the opposite, there are three
+	//good reasons to do so:
+	//First, the CMSIS specifications say that SystemInit() must not access
+	//global variables, so it is actually possible to call it before
+	//Second, when running Miosix with the xram linker scripts .data and .bss
+	//are placed in the external RAM, so we *must* call SystemInit(), which
+	//enables xram, before touching .data and .bss
+	//Third, this is a performance improvement since the loops that initialize
+	//.data and zeros .bss now run with the CPU at full speed instead of 8MHz
+    SystemInit();
+    //ST does not provide code to initialize the stm32f429-disco SDRAM at boot.
+    //Put after SystemInit() as SDRAM is timing-sensitive and needs the full
+    //clock speed.
+    #ifdef __ENABLE_XRAM
+    miosix::configureSdram();
+    #endif //__ENABLE_XRAM
+    
+    /*
+     * Initialize process stack and switch to it.
+     * This is required for booting Miosix, a small portion of the top of the
+     * heap area will be used as stack until the first thread starts. After,
+     * this stack will be abandoned and the process stack will point to the
+     * current thread's stack.
+     */
+    asm volatile("ldr r0,  =_heap_end          \n\t"
+                 "msr psp, r0                  \n\t"
+                 "movw r0, #2                  \n\n" //Privileged, process stack
+                 "msr control, r0              \n\t"
+                 "isb                          \n\t":::"r0");
+
+    program_startup();
+}
+
+/**
+ * All unused interrupts call this function.
+ */
+extern "C" void Default_Handler() 
+{
+    unexpectedInterrupt();
+}
+
+//System handlers
+void /*__attribute__((weak))*/ Reset_Handler();     //These interrupts are not
+void /*__attribute__((weak))*/ NMI_Handler();       //weak because they are
+void /*__attribute__((weak))*/ HardFault_Handler(); //surely defined by Miosix
+void /*__attribute__((weak))*/ MemManage_Handler();
+void /*__attribute__((weak))*/ BusFault_Handler();
+void /*__attribute__((weak))*/ UsageFault_Handler();
+void /*__attribute__((weak))*/ SVC_Handler();
+void /*__attribute__((weak))*/ DebugMon_Handler();
+void /*__attribute__((weak))*/ PendSV_Handler();
+void /*__attribute__((weak))*/ SysTick_Handler();
+
+//Interrupt handlers
+void __attribute__((weak))  WWDG_IRQHandler();
+void __attribute__((weak))  PVD_IRQHandler();
+void __attribute__((weak))  TAMP_STAMP_IRQHandler();
+void __attribute__((weak))  RTC_WKUP_IRQHandler();
+void __attribute__((weak))  FLASH_IRQHandler();
+void __attribute__((weak))  RCC_IRQHandler();
+void __attribute__((weak))  EXTI0_IRQHandler();
+void __attribute__((weak))  EXTI1_IRQHandler();
+void __attribute__((weak))  EXTI2_IRQHandler();
+void __attribute__((weak))  EXTI3_IRQHandler();
+void __attribute__((weak))  EXTI4_IRQHandler();
+void __attribute__((weak))  DMA1_Stream0_IRQHandler();
+void __attribute__((weak))  DMA1_Stream1_IRQHandler();
+void __attribute__((weak))  DMA1_Stream2_IRQHandler();
+void __attribute__((weak))  DMA1_Stream3_IRQHandler();
+void __attribute__((weak))  DMA1_Stream4_IRQHandler();
+void __attribute__((weak))  DMA1_Stream5_IRQHandler();
+void __attribute__((weak))  DMA1_Stream6_IRQHandler();
+void __attribute__((weak))  ADC_IRQHandler();
+void __attribute__((weak))  CAN1_TX_IRQHandler();
+void __attribute__((weak))  CAN1_RX0_IRQHandler();
+void __attribute__((weak))  CAN1_RX1_IRQHandler();
+void __attribute__((weak))  CAN1_SCE_IRQHandler();
+void __attribute__((weak))  EXTI9_5_IRQHandler();
+void __attribute__((weak))  TIM1_BRK_TIM9_IRQHandler();
+void __attribute__((weak))  TIM1_UP_TIM10_IRQHandler();
+void __attribute__((weak))  TIM1_TRG_COM_TIM11_IRQHandler();
+void __attribute__((weak))  TIM1_CC_IRQHandler();
+void __attribute__((weak))  TIM2_IRQHandler();
+void __attribute__((weak))  TIM3_IRQHandler();
+void __attribute__((weak))  TIM4_IRQHandler();
+void __attribute__((weak))  I2C1_EV_IRQHandler();
+void __attribute__((weak))  I2C1_ER_IRQHandler();
+void __attribute__((weak))  I2C2_EV_IRQHandler();
+void __attribute__((weak))  I2C2_ER_IRQHandler();
+void __attribute__((weak))  SPI1_IRQHandler();
+void __attribute__((weak))  SPI2_IRQHandler();
+void __attribute__((weak))  USART1_IRQHandler();
+void __attribute__((weak))  USART2_IRQHandler();
+void __attribute__((weak))  USART3_IRQHandler();
+void __attribute__((weak))  EXTI15_10_IRQHandler();
+void __attribute__((weak))  RTC_Alarm_IRQHandler();
+void __attribute__((weak))  OTG_FS_WKUP_IRQHandler();
+void __attribute__((weak))  TIM8_BRK_TIM12_IRQHandler();
+void __attribute__((weak))  TIM8_UP_TIM13_IRQHandler();
+void __attribute__((weak))  TIM8_TRG_COM_TIM14_IRQHandler();
+void __attribute__((weak))  TIM8_CC_IRQHandler();
+void __attribute__((weak))  DMA1_Stream7_IRQHandler();
+void __attribute__((weak))  FMC_IRQHandler();
+void __attribute__((weak))  SDIO_IRQHandler();
+void __attribute__((weak))  TIM5_IRQHandler();
+void __attribute__((weak))  SPI3_IRQHandler();
+void __attribute__((weak))  UART4_IRQHandler();
+void __attribute__((weak))  UART5_IRQHandler();
+void __attribute__((weak))  TIM6_DAC_IRQHandler();
+void __attribute__((weak))  TIM7_IRQHandler();
+void __attribute__((weak))  DMA2_Stream0_IRQHandler();
+void __attribute__((weak))  DMA2_Stream1_IRQHandler();
+void __attribute__((weak))  DMA2_Stream2_IRQHandler();
+void __attribute__((weak))  DMA2_Stream3_IRQHandler();
+void __attribute__((weak))  DMA2_Stream4_IRQHandler();
+void __attribute__((weak))  ETH_IRQHandler();
+void __attribute__((weak))  ETH_WKUP_IRQHandler();
+void __attribute__((weak))  CAN2_TX_IRQHandler();
+void __attribute__((weak))  CAN2_RX0_IRQHandler();
+void __attribute__((weak))  CAN2_RX1_IRQHandler();
+void __attribute__((weak))  CAN2_SCE_IRQHandler();
+void __attribute__((weak))  OTG_FS_IRQHandler();
+void __attribute__((weak))  DMA2_Stream5_IRQHandler();
+void __attribute__((weak))  DMA2_Stream6_IRQHandler();
+void __attribute__((weak))  DMA2_Stream7_IRQHandler();
+void __attribute__((weak))  USART6_IRQHandler();
+void __attribute__((weak))  I2C3_EV_IRQHandler();
+void __attribute__((weak))  I2C3_ER_IRQHandler();
+void __attribute__((weak))  OTG_HS_EP1_OUT_IRQHandler();
+void __attribute__((weak))  OTG_HS_EP1_IN_IRQHandler();
+void __attribute__((weak))  OTG_HS_WKUP_IRQHandler();
+void __attribute__((weak))  OTG_HS_IRQHandler();
+void __attribute__((weak))  DCMI_IRQHandler();
+void __attribute__((weak))  CRYP_IRQHandler();
+void __attribute__((weak))  HASH_RNG_IRQHandler();
+void __attribute__((weak))  FPU_IRQHandler();
+void __attribute__((weak))  UART7_IRQHandler();
+void __attribute__((weak))  UART8_IRQHandler();
+void __attribute__((weak))  SPI4_IRQHandler();
+void __attribute__((weak))  SPI5_IRQHandler();
+void __attribute__((weak))  SPI6_IRQHandler();
+void __attribute__((weak))  SAI1_IRQHandler();
+void __attribute__((weak))  LTDC_IRQHandler();
+void __attribute__((weak))  LTDC_ER_IRQHandler();
+void __attribute__((weak))  DMA2D_IRQHandler();
+
+//Stack top, defined in the linker script
+extern char _main_stack_top asm("_main_stack_top");
+
+//Interrupt vectors, must be placed @ address 0x00000000
+//The extern declaration is required otherwise g++ optimizes it out
+extern void (* const __Vectors[])();
+void (* const __Vectors[])() __attribute__ ((section(".isr_vector"))) =
+{
+    reinterpret_cast<void (*)()>(&_main_stack_top),/* Stack pointer*/
+    Reset_Handler,              /* Reset Handler */
+    NMI_Handler,                /* NMI Handler */
+    HardFault_Handler,          /* Hard Fault Handler */
+    MemManage_Handler,          /* MPU Fault Handler */
+    BusFault_Handler,           /* Bus Fault Handler */
+    UsageFault_Handler,         /* Usage Fault Handler */
+    0,                          /* Reserved */
+    0,                          /* Reserved */
+    0,                          /* Reserved */
+    0,                          /* Reserved */
+    SVC_Handler,                /* SVCall Handler */
+    DebugMon_Handler,           /* Debug Monitor Handler */
+    0,                          /* Reserved */
+    PendSV_Handler,             /* PendSV Handler */
+    SysTick_Handler,            /* SysTick Handler */
+
+    /* External Interrupts */
+	WWDG_IRQHandler,
+	PVD_IRQHandler,
+	TAMP_STAMP_IRQHandler,
+	RTC_WKUP_IRQHandler,
+	FLASH_IRQHandler,
+	RCC_IRQHandler,
+	EXTI0_IRQHandler,
+	EXTI1_IRQHandler,
+	EXTI2_IRQHandler,
+	EXTI3_IRQHandler,
+	EXTI4_IRQHandler,
+	DMA1_Stream0_IRQHandler,
+	DMA1_Stream1_IRQHandler,
+	DMA1_Stream2_IRQHandler,
+	DMA1_Stream3_IRQHandler,
+	DMA1_Stream4_IRQHandler,
+	DMA1_Stream5_IRQHandler,
+	DMA1_Stream6_IRQHandler,
+	ADC_IRQHandler,
+	CAN1_TX_IRQHandler,
+	CAN1_RX0_IRQHandler,
+	CAN1_RX1_IRQHandler,
+	CAN1_SCE_IRQHandler,
+	EXTI9_5_IRQHandler,
+	TIM1_BRK_TIM9_IRQHandler,
+	TIM1_UP_TIM10_IRQHandler,
+	TIM1_TRG_COM_TIM11_IRQHandler,
+	TIM1_CC_IRQHandler,
+	TIM2_IRQHandler,
+	TIM3_IRQHandler,
+	TIM4_IRQHandler,
+	I2C1_EV_IRQHandler,
+	I2C1_ER_IRQHandler,
+	I2C2_EV_IRQHandler,
+	I2C2_ER_IRQHandler,
+	SPI1_IRQHandler,
+	SPI2_IRQHandler,
+	USART1_IRQHandler,
+	USART2_IRQHandler,
+	USART3_IRQHandler,
+	EXTI15_10_IRQHandler,
+	RTC_Alarm_IRQHandler,
+	OTG_FS_WKUP_IRQHandler,
+	TIM8_BRK_TIM12_IRQHandler,
+	TIM8_UP_TIM13_IRQHandler,
+	TIM8_TRG_COM_TIM14_IRQHandler,
+	TIM8_CC_IRQHandler,
+	DMA1_Stream7_IRQHandler,
+	FMC_IRQHandler,
+	SDIO_IRQHandler,
+	TIM5_IRQHandler,
+	SPI3_IRQHandler,
+	UART4_IRQHandler,
+	UART5_IRQHandler,
+	TIM6_DAC_IRQHandler,
+	TIM7_IRQHandler,
+	DMA2_Stream0_IRQHandler,
+	DMA2_Stream1_IRQHandler,
+	DMA2_Stream2_IRQHandler,
+	DMA2_Stream3_IRQHandler,
+	DMA2_Stream4_IRQHandler,
+	ETH_IRQHandler,
+	ETH_WKUP_IRQHandler,
+	CAN2_TX_IRQHandler,
+	CAN2_RX0_IRQHandler,
+	CAN2_RX1_IRQHandler,
+	CAN2_SCE_IRQHandler,
+	OTG_FS_IRQHandler,
+	DMA2_Stream5_IRQHandler,
+	DMA2_Stream6_IRQHandler,
+	DMA2_Stream7_IRQHandler,
+	USART6_IRQHandler,
+	I2C3_EV_IRQHandler,
+	I2C3_ER_IRQHandler,
+	OTG_HS_EP1_OUT_IRQHandler,
+	OTG_HS_EP1_IN_IRQHandler,
+	OTG_HS_WKUP_IRQHandler,
+	OTG_HS_IRQHandler,
+	DCMI_IRQHandler,
+	CRYP_IRQHandler,
+	HASH_RNG_IRQHandler,
+	FPU_IRQHandler,
+	UART7_IRQHandler,
+	UART8_IRQHandler,
+	SPI4_IRQHandler,
+	SPI5_IRQHandler,
+	SPI6_IRQHandler,
+	SAI1_IRQHandler,
+	LTDC_IRQHandler,
+	LTDC_ER_IRQHandler,
+	DMA2D_IRQHandler
+};
+
+#pragma weak WWDG_IRQHandler = Default_Handler
+#pragma weak PVD_IRQHandler = Default_Handler
+#pragma weak TAMP_STAMP_IRQHandler = Default_Handler
+#pragma weak RTC_WKUP_IRQHandler = Default_Handler
+#pragma weak FLASH_IRQHandler = Default_Handler
+#pragma weak RCC_IRQHandler = Default_Handler
+#pragma weak EXTI0_IRQHandler = Default_Handler
+#pragma weak EXTI1_IRQHandler = Default_Handler
+#pragma weak EXTI2_IRQHandler = Default_Handler
+#pragma weak EXTI3_IRQHandler = Default_Handler
+#pragma weak EXTI4_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream0_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream1_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream2_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream3_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream4_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream5_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream6_IRQHandler = Default_Handler
+#pragma weak ADC_IRQHandler = Default_Handler
+#pragma weak CAN1_TX_IRQHandler = Default_Handler
+#pragma weak CAN1_RX0_IRQHandler = Default_Handler
+#pragma weak CAN1_RX1_IRQHandler = Default_Handler
+#pragma weak CAN1_SCE_IRQHandler = Default_Handler
+#pragma weak EXTI9_5_IRQHandler = Default_Handler
+#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler
+#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler
+#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler
+#pragma weak TIM1_CC_IRQHandler = Default_Handler
+#pragma weak TIM2_IRQHandler = Default_Handler
+#pragma weak TIM3_IRQHandler = Default_Handler
+#pragma weak TIM4_IRQHandler = Default_Handler
+#pragma weak I2C1_EV_IRQHandler = Default_Handler
+#pragma weak I2C1_ER_IRQHandler = Default_Handler
+#pragma weak I2C2_EV_IRQHandler = Default_Handler
+#pragma weak I2C2_ER_IRQHandler = Default_Handler
+#pragma weak SPI1_IRQHandler = Default_Handler
+#pragma weak SPI2_IRQHandler = Default_Handler
+// #pragma weak USART1_IRQHandler = Default_Handler
+// #pragma weak USART2_IRQHandler = Default_Handler
+// #pragma weak USART3_IRQHandler = Default_Handler
+#pragma weak EXTI15_10_IRQHandler = Default_Handler
+#pragma weak RTC_Alarm_IRQHandler = Default_Handler
+#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler
+#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler
+#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler
+#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler
+#pragma weak TIM8_CC_IRQHandler = Default_Handler
+#pragma weak DMA1_Stream7_IRQHandler = Default_Handler
+#pragma weak FMC_IRQHandler = Default_Handler
+#pragma weak SDIO_IRQHandler = Default_Handler
+#pragma weak TIM5_IRQHandler = Default_Handler
+#pragma weak SPI3_IRQHandler = Default_Handler
+// #pragma weak UART4_IRQHandler = Default_Handler
+// #pragma weak UART5_IRQHandler = Default_Handler
+#pragma weak TIM6_DAC_IRQHandler = Default_Handler
+#pragma weak TIM7_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream0_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream1_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream2_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream3_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream4_IRQHandler = Default_Handler
+#pragma weak ETH_IRQHandler = Default_Handler
+#pragma weak ETH_WKUP_IRQHandler = Default_Handler
+#pragma weak CAN2_TX_IRQHandler = Default_Handler
+#pragma weak CAN2_RX0_IRQHandler = Default_Handler
+#pragma weak CAN2_RX1_IRQHandler = Default_Handler
+#pragma weak CAN2_SCE_IRQHandler = Default_Handler
+#pragma weak OTG_FS_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream5_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream6_IRQHandler = Default_Handler
+#pragma weak DMA2_Stream7_IRQHandler = Default_Handler
+// #pragma weak USART6_IRQHandler = Default_Handler
+#pragma weak I2C3_EV_IRQHandler = Default_Handler
+#pragma weak I2C3_ER_IRQHandler = Default_Handler
+#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler
+#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler
+#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler
+#pragma weak OTG_HS_IRQHandler = Default_Handler
+#pragma weak DCMI_IRQHandler = Default_Handler
+#pragma weak CRYP_IRQHandler = Default_Handler
+#pragma weak HASH_RNG_IRQHandler = Default_Handler
+#pragma weak FPU_IRQHandler = Default_Handler
+// #pragma weak UART7_IRQHandler = Default_Handler
+// #pragma weak UART8_IRQHandler = Default_Handler
+#pragma weak SPI4_IRQHandler = Default_Handler
+#pragma weak SPI5_IRQHandler = Default_Handler
+#pragma weak SPI6_IRQHandler = Default_Handler
+#pragma weak SAI1_IRQHandler = Default_Handler
+#pragma weak LTDC_IRQHandler = Default_Handler
+#pragma weak LTDC_ER_IRQHandler = Default_Handler
+#pragma weak DMA2D_IRQHandler = Default_Handler
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/arch_registers_impl.h b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/arch_registers_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..dfa0203013e65b9bc414c954d4cb1ddc1867d258
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/arch_registers_impl.h
@@ -0,0 +1,13 @@
+
+#ifndef ARCH_REGISTERS_IMPL_H
+#define	ARCH_REGISTERS_IMPL_H
+
+//Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency
+#define STM32F429xx
+#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
+#include "CMSIS/Include/core_cm4.h"
+#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h"
+
+#define RCC_SYNC() __DSB() //Workaround for a bug in stm32f42x
+
+#endif	//ARCH_REGISTERS_IMPL_H
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/bsp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0ab256dbe94228c93fb58fd18850ff97ec3c14c2
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/bsp.cpp
@@ -0,0 +1,304 @@
+/***************************************************************************
+ *   Copyright (C) 2014 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/ 
+
+/***********************************************************************
+* bsp.cpp Part of the Miosix Embedded OS.
+* Board support package, this file initializes hardware.
+************************************************************************/
+
+#include <cstdlib>
+#include <inttypes.h>
+#include <sys/ioctl.h>
+#include "interfaces/bsp.h"
+#include "kernel/kernel.h"
+#include "kernel/sync.h"
+#include "interfaces/delays.h"
+#include "interfaces/portability.h"
+#include "interfaces/arch_registers.h"
+#include "config/miosix_settings.h"
+#include "kernel/logging.h"
+#include "filesystem/file_access.h"
+#include "filesystem/console/console_device.h"
+#include "drivers/serial.h"
+#include "drivers/sd_stm32f2_f4.h"
+#include "board_settings.h"
+#include "hwmapping.h"
+// #include "kernel/IRQDisplayPrint.h"
+
+namespace miosix {
+
+//
+// Initialization
+//
+
+/**
+ * The example code from ST checks for the busy flag after each command.
+ * Interestingly I couldn't find any mention of this in the datsheet.
+ */
+static void sdramCommandWait()
+{
+    for(int i=0;i<0xffff;i++)
+        if((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY)==0) return;
+}
+
+void configureSdram()
+{
+    //Enable all gpios, passing clock
+    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
+                    RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
+                    RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN |
+                    RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN;
+    RCC_SYNC();
+    
+    //First, configure SDRAM GPIOs
+    GPIOB->AFR[0]=0x0cc00000;
+    GPIOC->AFR[0]=0x0000000c;
+    GPIOD->AFR[0]=0x000000cc;
+    GPIOD->AFR[1]=0xcc000ccc;
+    GPIOE->AFR[0]=0xc00000cc;
+    GPIOE->AFR[1]=0xcccccccc;
+    GPIOF->AFR[0]=0x00cccccc;
+    GPIOF->AFR[1]=0xccccc000;
+    GPIOG->AFR[0]=0x00cc00cc;
+    GPIOG->AFR[1]=0xc000000c;
+
+    GPIOB->MODER=0x00002800;
+    GPIOC->MODER=0x00000002;
+    GPIOD->MODER=0xa02a000a;
+    GPIOE->MODER=0xaaaa800a;
+    GPIOF->MODER=0xaa800aaa;
+    GPIOG->MODER=0x80020a0a;
+    
+    GPIOA->OSPEEDR=0xaaaaaaaa; //Default to 50MHz speed for all GPIOs...
+    GPIOB->OSPEEDR=0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins
+    GPIOC->OSPEEDR=0xaaaaaaaa | 0x00000003;
+    GPIOD->OSPEEDR=0xaaaaaaaa | 0xf03f000f;
+    GPIOE->OSPEEDR=0xaaaaaaaa | 0xffffc00f;
+    GPIOF->OSPEEDR=0xaaaaaaaa | 0xffc00fff;
+    GPIOG->OSPEEDR=0xaaaaaaaa | 0xc0030f0f;
+    GPIOH->OSPEEDR=0xaaaaaaaa;
+    
+    //Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST,
+    //finish the job and remove the default pull-up
+    GPIOB->PUPDR=0;
+    
+    //Second, actually start the SDRAM controller
+    RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN;
+    RCC_SYNC();
+    
+    //SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000)
+    //Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0],
+    //they aren't just don't care, the controller will fail if they aren't at 0
+    FMC_Bank5_6->SDCR[0]=FMC_SDCR1_SDCLK_1// SDRAM runs @ half CPU frequency
+                       | FMC_SDCR1_RBURST // Enable read burst
+                       | 0;               //  0 delay between reads after CAS
+    FMC_Bank5_6->SDCR[1]=0                //  8 bit column address
+                       | FMC_SDCR1_NR_0   // 12 bit row address
+                       | FMC_SDCR1_MWID_0 // 16 bit data bus
+                       | FMC_SDCR1_NB     //  4 banks
+                       | FMC_SDCR1_CAS_1; //  2 cycle CAS latency (F<133MHz)
+    
+    #ifdef SYSCLK_FREQ_180MHz
+    //One SDRAM clock cycle is 11.1ns
+    //Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0],
+    //they aren't just don't care, the controller will fail if they aren't at 0
+    FMC_Bank5_6->SDTR[0]=(6-1)<<12        // 6 cycle TRC  (66.6ns>63ns)
+                       | (2-1)<<20;       // 2 cycle TRP  (22.2ns>15ns)
+    FMC_Bank5_6->SDTR[1]=(2-1)<<0         // 2 cycle TMRD
+                       | (7-1)<<4         // 7 cycle TXSR (77.7ns>70ns)
+                       | (4-1)<<8         // 4 cycle TRAS (44.4ns>42ns)
+                       | (2-1)<<16        // 2 cycle TWR
+                       | (2-1)<<24;       // 2 cycle TRCD (22.2ns>15ns)
+    #elif defined(SYSCLK_FREQ_168MHz)
+    //One SDRAM clock cycle is 11.9ns
+    //Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0],
+    //they aren't just don't care, the controller will fail if they aren't at 0
+    FMC_Bank5_6->SDTR[0]=(6-1)<<12        // 6 cycle TRC  (71.4ns>63ns)
+                       | (2-1)<<20;       // 2 cycle TRP  (23.8ns>15ns)
+    FMC_Bank5_6->SDTR[1]=(2-1)<<0         // 2 cycle TMRD
+                       | (6-1)<<4         // 6 cycle TXSR (71.4ns>70ns)
+                       | (4-1)<<8         // 4 cycle TRAS (47.6ns>42ns)
+                       | (2-1)<<16        // 2 cycle TWR
+                       | (2-1)<<24;       // 2 cycle TRCD (23.8ns>15ns)
+    #else
+    #error No SDRAM timings for this clock
+    #endif
+
+    FMC_Bank5_6->SDCMR=  FMC_SDCMR_CTB2   // Enable bank 2
+                       | 1;               // MODE=001 clock enabled
+    sdramCommandWait();
+    
+    //ST and SDRAM datasheet agree a 100us delay is required here.
+    delayUs(100);
+
+    FMC_Bank5_6->SDCMR=  FMC_SDCMR_CTB2   // Enable bank 2
+                       | 2;               // MODE=010 precharge all command
+    sdramCommandWait();
+    
+    FMC_Bank5_6->SDCMR=  (8-1)<<5         // NRFS=8 SDRAM datasheet says
+                                          // "at least two AUTO REFRESH cycles"
+                       | FMC_SDCMR_CTB2   // Enable bank 2
+                       | 3;               // MODE=011 auto refresh
+    sdramCommandWait();
+
+    FMC_Bank5_6->SDCMR=0x220<<9           // MRD=0x220:CAS latency=2 burst len=1
+                       | FMC_SDCMR_CTB2   // Enable bank 2
+                       | 4;               // MODE=100 load mode register
+    sdramCommandWait();
+
+    // 64ms/4096=15.625us
+    #ifdef SYSCLK_FREQ_180MHz
+    //15.625us*90MHz=1406-20=1386
+    FMC_Bank5_6->SDRTR=1386<<1;
+    #elif defined(SYSCLK_FREQ_168MHz)
+    //15.625us*84MHz=1312-20=1292
+    FMC_Bank5_6->SDRTR=1292<<1;
+    #else
+    #error No refresh timings for this clock
+    #endif
+}
+
+// static IRQDisplayPrint *irq_display;
+void IRQbspInit()
+{
+    //If using SDRAM GPIOs are enabled by configureSdram(), else enable them here
+    #ifndef __ENABLE_XRAM
+    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
+                    RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
+                    RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN |
+                    RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN;
+    RCC_SYNC();
+    #endif //__ENABLE_XRAM
+    
+    // enable spi1, spi4
+    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_SPI4EN;
+
+    RCC_SYNC();
+
+    interfaces::spi1::sck::mode(Mode::ALTERNATE);
+    interfaces::spi1::sck::alternateFunction(5);
+    interfaces::spi1::miso::mode(Mode::ALTERNATE);
+    interfaces::spi1::miso::alternateFunction(5);
+    interfaces::spi1::mosi::mode(Mode::ALTERNATE);
+    interfaces::spi1::mosi::alternateFunction(5);
+
+    interfaces::spi4::sck::mode(Mode::ALTERNATE);
+    interfaces::spi4::sck::alternateFunction(5);
+    interfaces::spi4::miso::mode(Mode::ALTERNATE);
+    interfaces::spi4::miso::alternateFunction(5);
+    interfaces::spi4::mosi::mode(Mode::ALTERNATE);
+    interfaces::spi4::mosi::alternateFunction(5);
+
+    peripherals::ra01::pc13::cs::mode(Mode::OUTPUT);
+    peripherals::ra01::pc13::dio0::mode(Mode::INPUT);
+    peripherals::ra01::pc13::nrst::mode(Mode::OUTPUT);
+    peripherals::ra01::pc13::cs::high();
+    peripherals::ra01::pc13::nrst::high();
+
+    peripherals::ra01::pe4::cs::mode(Mode::OUTPUT);
+    peripherals::ra01::pe4::dio0::mode(Mode::INPUT);
+    peripherals::ra01::pe4::nrst::mode(Mode::OUTPUT);
+    peripherals::ra01::pe4::cs::high();
+    peripherals::ra01::pe4::nrst::high();
+
+    peripherals::cc3135::cs::mode(Mode::OUTPUT);
+    peripherals::cc3135::hib::mode(Mode::OUTPUT);
+    peripherals::cc3135::intr::mode(Mode::INPUT);
+    peripherals::cc3135::nrst::mode(Mode::OUTPUT);
+    peripherals::cc3135::cs::high();
+    peripherals::cc3135::hib::high();
+    peripherals::cc3135::nrst::high();
+
+    _led::mode(Mode::OUTPUT);
+    ledOn();
+    delayMs(100);
+    ledOff();
+    DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(
+        new STM32Serial(defaultSerial,defaultSerialSpeed,
+        defaultSerialFlowctrl ? STM32Serial::RTSCTS : STM32Serial::NOFLOWCTRL)));
+//     irq_display = new IRQDisplayPrint();
+//     DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(irq_display));
+}
+
+// void* printIRQ(void *argv)
+// {
+// 	intrusive_ref_ptr<IRQDisplayPrint> irqq(irq_display);
+// 	irqq.get()->printIRQ();
+// 	return NULL;
+// }
+
+void bspInit2()
+{
+    #ifdef WITH_FILESYSTEM
+    basicFilesystemSetup(SDIODriver::instance());
+    #endif //WITH_FILESYSTEM
+//     Thread::create(printIRQ, 2048);
+}
+
+//
+// Shutdown and reboot
+//
+
+/**
+This function disables filesystem (if enabled), serial port (if enabled) and
+puts the processor in deep sleep mode.<br>
+Wakeup occurs when PA.0 goes high, but instead of sleep(), a new boot happens.
+<br>This function does not return.<br>
+WARNING: close all files before using this function, since it unmounts the
+filesystem.<br>
+When in shutdown mode, power consumption of the miosix board is reduced to ~
+5uA??, however, true power consumption depends on what is connected to the GPIO
+pins. The user is responsible to put the devices connected to the GPIO pin in the
+minimal power consumption mode before calling shutdown(). Please note that to
+minimize power consumption all unused GPIO must not be left floating.
+*/
+void shutdown()
+{
+    ioctl(STDOUT_FILENO,IOCTL_SYNC,0);
+
+    #ifdef WITH_FILESYSTEM
+    FilesystemManager::instance().umountAll();
+    #endif //WITH_FILESYSTEM
+
+    disableInterrupts();
+
+    for(;;) ;
+}
+
+void reboot()
+{
+    ioctl(STDOUT_FILENO,IOCTL_SYNC,0);
+    
+    #ifdef WITH_FILESYSTEM
+    FilesystemManager::instance().umountAll();
+    #endif //WITH_FILESYSTEM
+
+    disableInterrupts();
+    miosix_private::IRQsystemReboot();
+}
+
+} //namespace miosix
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/bsp_impl.h b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/bsp_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c22cc6c9c06ba8cbb6a54215ff8805b555bfd3a
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/bsp_impl.h
@@ -0,0 +1,76 @@
+/***************************************************************************
+ *   Copyright (C) 2014 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/ 
+
+/***********************************************************************
+* bsp_impl.h Part of the Miosix Embedded OS.
+* Board support package, this file initializes hardware.
+************************************************************************/
+
+#ifndef BSP_IMPL_H
+#define BSP_IMPL_H
+
+#include "config/miosix_settings.h"
+#include "interfaces/gpio.h"
+#include "drivers/stm32_hardware_rng.h"
+
+namespace miosix {
+
+/**
+\addtogroup Hardware
+\{
+*/
+
+/**
+ * \internal
+ * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss
+ * Requires the CPU clock to be already configured (running from the PLL)
+ */
+void configureSdram();
+
+/**
+ * \internal
+ * used by the ledOn() and ledOff() implementation
+ */
+typedef Gpio<GPIOG_BASE,14> _led;
+
+inline void ledOn()
+{
+    _led::high();
+}
+
+inline void ledOff()
+{
+    _led::low();
+}
+
+/**
+\}
+*/
+
+} //namespace miosix
+
+#endif //BSP_IMPL_H
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/hwmapping.h b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/hwmapping.h
new file mode 100644
index 0000000000000000000000000000000000000000..a67bea72be0a86a8e478ac3fa1f8023a532dbc78
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/interfaces-impl/hwmapping.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ *   Copyright (C) 2018 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#ifndef HWMAPPING_H
+#define HWMAPPING_H
+
+#include "interfaces/gpio.h"
+
+namespace miosix {
+
+namespace interfaces 
+{
+
+// CC3135
+namespace spi1 
+{
+using sck = Gpio<GPIOA_BASE, 5>;
+using miso = Gpio<GPIOB_BASE, 4>;
+using mosi = Gpio<GPIOA_BASE, 7>;
+} // namespace spi1
+
+// RA-01
+namespace spi4 
+{
+using sck = Gpio<GPIOE_BASE, 2>;
+using miso = Gpio<GPIOE_BASE, 5>;
+using mosi = Gpio<GPIOE_BASE, 6>;
+} // namespace spi4
+
+} // namespace interfaces
+
+namespace peripherals 
+{
+
+namespace ra01 
+{
+
+namespace pc13 
+{
+using cs = Gpio<GPIOC_BASE, 13>;
+using dio0 = Gpio<GPIOF_BASE, 6>;
+using nrst = Gpio<GPIOC_BASE, 14>;
+} // namespace pc13
+
+namespace pe4 
+{
+using cs = Gpio<GPIOE_BASE, 4>;
+using dio0 = Gpio<GPIOE_BASE, 3>;
+using nrst = Gpio<GPIOG_BASE, 2>;
+} // namespace pe4
+
+} // namespace ra01
+
+namespace cc3135 
+{
+using cs = Gpio<GPIOD_BASE, 4>;
+using hib = Gpio<GPIOG_BASE, 3>;
+using intr = Gpio<GPIOD_BASE, 5>;
+using nrst = Gpio<GPIOB_BASE, 7>;
+} // namespace cc3135
+
+} // namespace peripherals
+
+} // namespace miosix
+
+#endif // HWMAPPING_H
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+256k_rom.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+256k_rom.ld
new file mode 100644
index 0000000000000000000000000000000000000000..e2425d265aaf968808b58724cebe4f785e4a21e8
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+256k_rom.ld
@@ -0,0 +1,180 @@
+/*
+ * C++ enabled linker script for stm32 (2M FLASH, 256K RAM)
+ * Developed by TFT: Terraneo Federico Technologies
+ * Optimized for use with the Miosix kernel
+ */
+
+/*
+ * This chip has an unusual quirk that the RAM is divided in two block mapped
+ * at two non contiguous memory addresses. I don't know why they've done that,
+ * probably doing the obvious thing would have made writing code too easy...
+ * Anyway, since hardware can't be changed, we've got to live with that and
+ * try to make use of both RAMs.
+ * 
+ * Given the constraints above, this linker script puts:
+ * - read only data and code (.text, .rodata, .eh_*) in FLASH
+ * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM
+ * - stacks and heap in the "large" 192KB RAM.
+ * 
+ * Unfortunately thread stacks can't be put in the small RAM as Miosix
+ * allocates them inside the heap.
+ */
+
+/*
+ * The main stack is used for interrupt handling by the kernel.
+ *
+ * *** Readme ***
+ * This linker script places the main stack (used by the kernel for interrupts)
+ * at the bottom of the ram, instead of the top. This is done for two reasons:
+ *
+ * - as an optimization for microcontrollers with little ram memory. In fact
+ *   the implementation of malloc from newlib requests memory to the OS in 4KB
+ *   block (except the first block that can be smaller). This is probably done
+ *   for compatibility with OSes with an MMU and paged memory. To see why this
+ *   is bad, consider a microcontroller with 8KB of ram: when malloc finishes
+ *   up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will
+ *   fail because the top part of the ram is used by the main stack. As a
+ *   result, the top part of the memory will not be used by malloc, even if
+ *   available (and it is nearly *half* the ram on an 8KB mcu). By placing the
+ *   main stack at the bottom of the ram, the upper 4KB block will be entirely
+ *   free and available as heap space.
+ *
+ * - In case of main stack overflow the cpu will fault because access to memory
+ *   before the beginning of the ram faults. Instead with the default stack
+ *   placement the main stack will silently collide with the heap.
+ * Note: if increasing the main stack size also increase the ORIGIN value in
+ * the MEMORY definitions below accordingly.
+ */
+_main_stack_size = 0x00000200;                     /* main stack = 512Bytes */
+_main_stack_top  = 0x10000000 + _main_stack_size;
+ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
+
+/* Mapping the heap into the large 192KB RAM */
+_end =      0x20000000;
+_heap_end = 0x20030000;                            /* end of available ram  */
+
+/* identify the Entry Point  */
+ENTRY(_Z13Reset_Handlerv)
+
+/* specify the memory areas  */
+MEMORY
+{
+    flash(rx)    : ORIGIN = 0x08000000, LENGTH =   2M
+    /*
+     * Note, the small ram starts at 0x10000000 but it is necessary to add the
+     * size of the main stack, so it is 0x10000200.
+     */
+    smallram(wx) : ORIGIN = 0x10000200, LENGTH =  64K-0x200 
+    largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K
+}
+
+/* now define the output sections  */
+SECTIONS
+{
+    . = 0;
+    
+    /* .text section: code goes to flash */
+    .text :
+    {
+        /* Startup code must go at address 0 */
+        KEEP(*(.isr_vector))
+        
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+        /* these sections for thumb interwork? */
+        *(.glue_7)
+        *(.glue_7t)
+        /* these sections for C++? */
+        *(.gcc_except_table)
+        *(.gcc_except_table.*)
+        *(.ARM.extab*)
+        *(.gnu.linkonce.armextab.*)
+
+        . = ALIGN(4);
+        /* .rodata: constant data */
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+
+        /* C++ Static constructors/destructors (eabi) */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        
+        . = ALIGN(4);
+        __miosix_init_array_start = .;
+        KEEP (*(SORT(.miosix_init_array.*)))
+        KEEP (*(.miosix_init_array))
+        __miosix_init_array_end = .;
+
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        /* C++ Static constructors/destructors (elf)  */
+        . = ALIGN(4);
+        _ctor_start = .;
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+       _ctor_end = .;
+
+        . = ALIGN(4);
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+    } > flash
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > flash
+    __exidx_end = .;
+
+	/* .data section: global variables go to ram, but also store a copy to
+       flash to initialize them */
+    .data : ALIGN(8)
+    {
+        _data = .;
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+        . = ALIGN(8);
+        _edata = .;
+    } > smallram AT > flash
+    _etext = LOADADDR(.data);
+
+    /* .bss section: uninitialized global variables go to ram */
+    _bss_start = .;
+    .bss :
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        . = ALIGN(8);
+    } > smallram
+    _bss_end = .;
+
+    /*_end = .;*/
+    /*PROVIDE(end = .);*/
+}
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+6m_xram.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+6m_xram.ld
new file mode 100644
index 0000000000000000000000000000000000000000..b61f04cea1b19c15a54b55515100951d99048fc8
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+6m_xram.ld
@@ -0,0 +1,183 @@
+/*
+ * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM)
+ * Developed by TFT: Terraneo Federico Technologies
+ * Optimized for use with the Miosix kernel
+ */
+
+/*
+ * This chip has an unusual quirk that the RAM is divided in two block mapped
+ * at two non contiguous memory addresses. I don't know why they've done that,
+ * probably doing the obvious thing would have made writing code too easy...
+ * Anyway, since hardware can't be changed, we've got to live with that and
+ * try to make use of both RAMs.
+ * 
+ * Given the constraints above, this linker script puts:
+ * - read only data and code (.text, .rodata, .eh_*) in FLASH
+ * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM
+ * - .data, .bss, stacks and heap in the external 6MB SDRAM.
+ * Note that the SDRAM is 8MB, but this linker script only uses the lower 6.
+ * The upper 2MB are reserved as framebuffers for the LCD. Notice that the
+ * choice to allocate this space is due to the SDRAM architecture, composed of
+ * 4 banks of 2MB each. Reserving a bank for the LCD allows the software
+ * running on the board and the LCD to operate (almost) independently.
+ */
+
+/*
+ * The main stack is used for interrupt handling by the kernel.
+ *
+ * *** Readme ***
+ * This linker script places the main stack (used by the kernel for interrupts)
+ * at the bottom of the ram, instead of the top. This is done for two reasons:
+ *
+ * - as an optimization for microcontrollers with little ram memory. In fact
+ *   the implementation of malloc from newlib requests memory to the OS in 4KB
+ *   block (except the first block that can be smaller). This is probably done
+ *   for compatibility with OSes with an MMU and paged memory. To see why this
+ *   is bad, consider a microcontroller with 8KB of ram: when malloc finishes
+ *   up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will
+ *   fail because the top part of the ram is used by the main stack. As a
+ *   result, the top part of the memory will not be used by malloc, even if
+ *   available (and it is nearly *half* the ram on an 8KB mcu). By placing the
+ *   main stack at the bottom of the ram, the upper 4KB block will be entirely
+ *   free and available as heap space.
+ *
+ * - In case of main stack overflow the cpu will fault because access to memory
+ *   before the beginning of the ram faults. Instead with the default stack
+ *   placement the main stack will silently collide with the heap.
+ * Note: if increasing the main stack size also increase the ORIGIN value in
+ * the MEMORY definitions below accordingly.
+ */
+_main_stack_size = 0x00000200;                     /* main stack = 512Bytes */
+_main_stack_top  = 0x10000000 + _main_stack_size;
+ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
+
+/* Mapping the heap into XRAM */
+_heap_end = 0xd0600000;                            /* end of available ram  */
+
+/* identify the Entry Point  */
+ENTRY(_Z13Reset_Handlerv)
+
+/* specify the memory areas  */
+MEMORY
+{
+    flash(rx)    : ORIGIN = 0x08000000, LENGTH =   2M
+    /*
+     * Note, the small ram starts at 0x10000000 but it is necessary to add the
+     * size of the main stack, so it is 0x10000200.
+     */
+    smallram(wx) : ORIGIN = 0x10000200, LENGTH =  64K-0x200 
+    largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K
+    xram(wx)     : ORIGIN = 0xd0000000, LENGTH =   6M
+    lcdram(wx)   : ORIGIN = 0xd0600000, LENGTH =   2M
+}
+
+/* now define the output sections  */
+SECTIONS
+{
+    . = 0;
+    
+    /* .text section: code goes to flash */
+    .text :
+    {
+        /* Startup code must go at address 0 */
+        KEEP(*(.isr_vector))
+        
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+        /* these sections for thumb interwork? */
+        *(.glue_7)
+        *(.glue_7t)
+        /* these sections for C++? */
+        *(.gcc_except_table)
+        *(.gcc_except_table.*)
+        *(.ARM.extab*)
+        *(.gnu.linkonce.armextab.*)
+
+        . = ALIGN(4);
+        /* .rodata: constant data */
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+
+        /* C++ Static constructors/destructors (eabi) */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        
+        . = ALIGN(4);
+        __miosix_init_array_start = .;
+        KEEP (*(SORT(.miosix_init_array.*)))
+        KEEP (*(.miosix_init_array))
+        __miosix_init_array_end = .;
+
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        /* C++ Static constructors/destructors (elf)  */
+        . = ALIGN(4);
+        _ctor_start = .;
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+       _ctor_end = .;
+
+        . = ALIGN(4);
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+    } > flash
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > flash
+    __exidx_end = .;
+
+	/* .data section: global variables go to ram, but also store a copy to
+       flash to initialize them */
+    .data : ALIGN(8)
+    {
+        _data = .;
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+        . = ALIGN(8);
+        _edata = .;
+    } > xram AT > flash
+    _etext = LOADADDR(.data);
+
+    /* .bss section: uninitialized global variables go to ram */
+    _bss_start = .;
+    .bss :
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        . = ALIGN(8);
+    } > xram
+    _bss_end = .;
+
+    _end = .;
+    PROVIDE(end = .);
+}
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+8m_xram.ld b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+8m_xram.ld
new file mode 100644
index 0000000000000000000000000000000000000000..78fe53104dfa12f2e1586b9af09c97b7958ecb4c
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32_2m+8m_xram.ld
@@ -0,0 +1,177 @@
+/*
+ * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM)
+ * Developed by TFT: Terraneo Federico Technologies
+ * Optimized for use with the Miosix kernel
+ */
+
+/*
+ * This chip has an unusual quirk that the RAM is divided in two block mapped
+ * at two non contiguous memory addresses. I don't know why they've done that,
+ * probably doing the obvious thing would have made writing code too easy...
+ * Anyway, since hardware can't be changed, we've got to live with that and
+ * try to make use of both RAMs.
+ * 
+ * Given the constraints above, this linker script puts:
+ * - read only data and code (.text, .rodata, .eh_*) in FLASH
+ * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM
+ * - .data, .bss, stacks and heap in the external 8MB SDRAM.
+ */
+
+/*
+ * The main stack is used for interrupt handling by the kernel.
+ *
+ * *** Readme ***
+ * This linker script places the main stack (used by the kernel for interrupts)
+ * at the bottom of the ram, instead of the top. This is done for two reasons:
+ *
+ * - as an optimization for microcontrollers with little ram memory. In fact
+ *   the implementation of malloc from newlib requests memory to the OS in 4KB
+ *   block (except the first block that can be smaller). This is probably done
+ *   for compatibility with OSes with an MMU and paged memory. To see why this
+ *   is bad, consider a microcontroller with 8KB of ram: when malloc finishes
+ *   up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will
+ *   fail because the top part of the ram is used by the main stack. As a
+ *   result, the top part of the memory will not be used by malloc, even if
+ *   available (and it is nearly *half* the ram on an 8KB mcu). By placing the
+ *   main stack at the bottom of the ram, the upper 4KB block will be entirely
+ *   free and available as heap space.
+ *
+ * - In case of main stack overflow the cpu will fault because access to memory
+ *   before the beginning of the ram faults. Instead with the default stack
+ *   placement the main stack will silently collide with the heap.
+ * Note: if increasing the main stack size also increase the ORIGIN value in
+ * the MEMORY definitions below accordingly.
+ */
+_main_stack_size = 0x00000200;                     /* main stack = 512Bytes */
+_main_stack_top  = 0x10000000 + _main_stack_size;
+ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
+
+/* Mapping the heap into XRAM */
+_heap_end = 0xd0800000;                            /* end of available ram  */
+
+/* identify the Entry Point  */
+ENTRY(_Z13Reset_Handlerv)
+
+/* specify the memory areas  */
+MEMORY
+{
+    flash(rx)    : ORIGIN = 0x08000000, LENGTH =   2M
+    /*
+     * Note, the small ram starts at 0x10000000 but it is necessary to add the
+     * size of the main stack, so it is 0x10000200.
+     */
+    smallram(wx) : ORIGIN = 0x10000200, LENGTH =  64K-0x200 
+    largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K
+    xram(wx)     : ORIGIN = 0xd0000000, LENGTH =   8M
+}
+
+/* now define the output sections  */
+SECTIONS
+{
+    . = 0;
+    
+    /* .text section: code goes to flash */
+    .text :
+    {
+        /* Startup code must go at address 0 */
+        KEEP(*(.isr_vector))
+        
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+        /* these sections for thumb interwork? */
+        *(.glue_7)
+        *(.glue_7t)
+        /* these sections for C++? */
+        *(.gcc_except_table)
+        *(.gcc_except_table.*)
+        *(.ARM.extab*)
+        *(.gnu.linkonce.armextab.*)
+
+        . = ALIGN(4);
+        /* .rodata: constant data */
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+
+        /* C++ Static constructors/destructors (eabi) */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        
+        . = ALIGN(4);
+        __miosix_init_array_start = .;
+        KEEP (*(SORT(.miosix_init_array.*)))
+        KEEP (*(.miosix_init_array))
+        __miosix_init_array_end = .;
+
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        /* C++ Static constructors/destructors (elf)  */
+        . = ALIGN(4);
+        _ctor_start = .;
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+       _ctor_end = .;
+
+        . = ALIGN(4);
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+    } > flash
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > flash
+    __exidx_end = .;
+
+	/* .data section: global variables go to ram, but also store a copy to
+       flash to initialize them */
+    .data : ALIGN(8)
+    {
+        _data = .;
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+        . = ALIGN(8);
+        _edata = .;
+    } > xram AT > flash
+    _etext = LOADADDR(.data);
+
+    /* .bss section: uninitialized global variables go to ram */
+    _bss_start = .;
+    .bss :
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        . = ALIGN(8);
+    } > xram
+    _bss_end = .;
+
+    _end = .;
+    PROVIDE(end = .);
+}
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32f4discovery.cfg b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32f4discovery.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..b489a546bd4743faa8bb88ffdb5568458798c188
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/stm32f4discovery.cfg
@@ -0,0 +1,17 @@
+#
+# OpenOCD configuration file for in-circuit debugging the stm32f4discovery
+# To start debugging issue those commands:
+#    arm-miosix-eabi-gdb main.elf
+#    target remote :3333
+#    monitor reset halt
+#    load
+#    break main
+#    continue
+#
+
+# Daemon configuration
+telnet_port 4444
+gdb_port 3333
+
+# Board support is available in newer oocd
+source [find board/stm32f4discovery.cfg]
diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc
index d574ef0fa037f8599d33ccf3a46ae89ddd307b4a..27c0d4504fd1c3038b9cc7266ffdb809d6f94286 100644
--- a/miosix/config/Makefile.inc
+++ b/miosix/config/Makefile.inc
@@ -53,6 +53,7 @@
 #OPT_BOARD := stm32f429zi_skyward_death_stack_x
 #OPT_BOARD := stm32f429zi_skyward_death_stack_v3
 #OPT_BOARD := stm32f429zi_skyward_groundstation
+#OPT_BOARD := stm32f429zi_skyward_groundstation_v2
 #OPT_BOARD := stm32f429zi_skyward_groundstation_parafoil
 #OPT_BOARD := stm32f100cx_generic
 #OPT_BOARD := stm32f407vg_skyward_tortellino
@@ -790,6 +791,39 @@ ifeq ($(OPT_BOARD),stm32f429zi_skyward_groundstation)
 
 endif
 
+##---------------------------------------------------------------------------
+## stm32f429zi_skyward_groundstation_v2
+##
+ifeq ($(OPT_BOARD),stm32f429zi_skyward_groundstation_v2)
+
+    ## Linker script type, there are three options
+    ## 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld)
+    ##    the most common choice, available for all microcontrollers
+    ## 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld)
+    ##    You must uncomment -D__ENABLE_XRAM below in this case.
+    ## 3) Code in FLASH, stack + heap in external RAM (file *6m_xram.ld)
+    ##    Same as above, but leaves the upper 2MB of RAM for the LCD.
+    LINKER_SCRIPT_PATH := arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/
+    #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_2m+256k_rom.ld
+    #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_2m+8m_xram.ld
+    LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_2m+6m_xram.ld
+
+    ## Uncommenting __ENABLE_XRAM enables the initialization of the external
+    ## 8MB SDRAM memory. Do not uncomment this even if you don't use a linker
+    ## script that requires it, as it is used for the LCD framebuffer.
+    XRAM := -D__ENABLE_XRAM
+
+    ## Select clock frequency. Warning: the default clock frequency for
+    ## this board is 168MHz and not 180MHz because, due to a limitation in
+    ## the PLL, it is not possible to generate a precise 48MHz output when
+    ## running the core at 180MHz. If 180MHz is chosen the USB peripheral will
+    ## NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48)
+    #CLOCK_FREQ := -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000
+    CLOCK_FREQ := -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000
+    #CLOCK_FREQ := -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000
+
+endif
+
 ##---------------------------------------------------------------------------
 ## stm32f429zi_skyward_groundstation_parafoil
 ##
@@ -986,6 +1020,8 @@ else ifeq ($(OPT_BOARD),stm32f429zi_skyward_death_stack_v3)
     ARCH := cortexM4_stm32f4
 else ifeq ($(OPT_BOARD),stm32f429zi_skyward_groundstation)
     ARCH := cortexM4_stm32f4
+else ifeq ($(OPT_BOARD),stm32f429zi_skyward_groundstation_v2)
+    ARCH := cortexM4_stm32f4
 else ifeq ($(OPT_BOARD),stm32f429zi_skyward_groundstation_parafoil)
     ARCH := cortexM4_stm32f4
 else ifeq ($(OPT_BOARD),stm32f100cx_generic)
@@ -2248,6 +2284,38 @@ else ifeq ($(ARCH),cortexM4_stm32f4)
         ## board.
         PROGRAM_CMDLINE := qstlink2 -cqewV ./main.bin
 
+    ##-------------------------------------------------------------------------
+    ## BOARD: stm32f429zi_skyward_groundstation_v2
+    ##
+    else ifeq ($(OPT_BOARD),stm32f429zi_skyward_groundstation_v2)
+
+        ## Base directory with header files for this board
+        BOARD_INC := arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2
+
+        ## Select linker script and boot file
+        ## Their path must be relative to the miosix directory.
+        BOOT_FILE := $(BOARD_INC)/core/stage_1_boot.o
+        #LINKER_SCRIPT := already selected in board options
+
+        ## Select architecture specific files
+        ## These are the files in arch/<arch name>/<board name>
+        ARCH_SRC :=                                  \
+        arch/common/drivers/stm32f2_f4_i2c.cpp       \
+        arch/common/drivers/stm32_hardware_rng.cpp   \
+        $(BOARD_INC)/interfaces-impl/bsp.cpp
+
+        ## Add a #define to allow querying board name
+        CFLAGS_BASE   += -D_BOARD_STM32F429ZI_SKYWARD_GS_V2
+        CXXFLAGS_BASE += -D_BOARD_STM32F429ZI_SKYWARD_GS_V2
+
+        ## Select programmer command line
+        ## This is the program that is invoked when the user types
+        ## 'make program'
+        ## The command must provide a way to program the board, or print an
+        ## error message saying that 'make program' is not supported for that
+        ## board.
+        PROGRAM_CMDLINE := qstlink2 -cqewV ./main.bin
+
     ##-------------------------------------------------------------------------
     ## BOARD: stm32f429zi_skyward_groundstation_parafoil
     ##
diff --git a/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/board_settings.h b/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/board_settings.h
new file mode 100644
index 0000000000000000000000000000000000000000..94cdc8b5c5cfab0aaf6f75c9d4433e228a31e652
--- /dev/null
+++ b/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/board_settings.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ *   Copyright (C) 2014 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#ifndef BOARD_SETTINGS_H
+#define	BOARD_SETTINGS_H
+
+#include "util/version.h"
+
+/**
+ * \internal
+ * Versioning for board_settings.h for out of git tree projects
+ */
+#define BOARD_SETTINGS_VERSION 100
+
+namespace miosix {
+
+/**
+ * \addtogroup Settings
+ * \{
+ */
+
+/// Size of stack for main().
+/// The C standard library is stack-heavy (iprintf requires 1KB) but the
+/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack.
+const unsigned int MAIN_STACK_SIZE=4*1024;
+
+/// Frequency of tick (in Hz). The frequency of the STM32F100RB timer in the
+/// stm32vldiscovery board can be divided by 1000. This allows to use a 1KHz
+/// tick and the minimun Thread::sleep value is 1ms
+/// For the priority scheduler this is also the context switch frequency
+const unsigned int TICK_FREQ=1000;
+
+///\internal Aux timer run @ 100KHz
+///Note that since the timer is only 16 bits this imposes a limit on the
+///burst measurement of 655ms. If due to a pause_kernel() or
+///disable_interrupts() section a thread runs for more than that time, a wrong
+///burst value will be measured
+const unsigned int AUX_TIMER_CLOCK=100000;
+const unsigned int AUX_TIMER_MAX=0xffff; ///<\internal Aux timer is 16 bits
+
+/// Serial port
+const unsigned int defaultSerial=1;
+const unsigned int defaultSerialSpeed=115200;
+const bool defaultSerialFlowctrl=false;
+//#define SERIAL_1_DMA
+//#define SERIAL_2_DMA //Serial 2 can't be used (GPIO conflict), so no DMA
+//#define SERIAL_3_DMA //Serial 3 can't be used (GPIO conflict), so no DMA
+
+//#define I2C_WITH_DMA
+
+//SD card driver
+static const unsigned char sdVoltage=30; //Board powered @ 3.0V
+#define SD_ONE_BIT_DATABUS //Can't use 4 bit databus due to pin conflicts
+
+/**
+ * \}
+ */
+
+} //namespace miosix
+
+#endif	/* BOARD_SETTINGS_H */
diff --git a/miosix/config/boards.cmake b/miosix/config/boards.cmake
index 5562dd51aeed0099ec7b74a522b1bae794a8cecb..541fb4d3521e133ca41cae717af93a7cd4d55ff3 100644
--- a/miosix/config/boards.cmake
+++ b/miosix/config/boards.cmake
@@ -70,6 +70,7 @@ set(BOARDS
     stm32f103cb_skyward_strain_board
     stm32f429zi_skyward_death_stack_v3
     stm32f429zi_skyward_groundstation
+    stm32f429zi_skyward_groundstation_v2
     stm32f429zi_skyward_groundstation_parafoil
     stm32f429zi_skyward_pyxis_auxiliary
     stm32f429zi_skyward_parafoil
diff --git a/miosix/config/options.cmake b/miosix/config/options.cmake
index a1f0260ec33485ed6e420459bf22c7248d137973..bc6ebaf8495b198e5045380582970dd4b7733998 100644
--- a/miosix/config/options.cmake
+++ b/miosix/config/options.cmake
@@ -777,6 +777,39 @@ if(${OPT_BOARD} STREQUAL stm32f429zi_skyward_groundstation)
 
 endif()
 
+##---------------------------------------------------------------------------
+## stm32f429zi_skyward_groundstation_v2
+##
+if(${OPT_BOARD} STREQUAL stm32f429zi_skyward_groundstation_v2)
+
+    ## Linker script type, there are three options
+    ## 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld)
+    ##    the most common choice, available for all microcontrollers
+    ## 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld)
+    ##    You must uncomment -D__ENABLE_XRAM below in this case.
+    ## 3) Code in FLASH, stack + heap in external RAM (file *6m_xram.ld)
+    ##    Same as above, but leaves the upper 2MB of RAM for the LCD.
+    set(LINKER_SCRIPT_PATH ${KPATH}/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2/)
+    #set(LINKER_SCRIPT ${LINKER_SCRIPT_PATH}stm32_2m+256k_rom.ld)
+    #set(LINKER_SCRIPT ${LINKER_SCRIPT_PATH}stm32_2m+8m_xram.ld)
+    set(LINKER_SCRIPT ${LINKER_SCRIPT_PATH}stm32_2m+6m_xram.ld)
+
+    ## Uncommenting __ENABLE_XRAM enables the initialization of the external
+    ## 8MB SDRAM memory. Do not uncomment this even if you don't use a linker
+    ## script that requires it, as it is used for the LCD framebuffer.
+    set(XRAM -D__ENABLE_XRAM)
+
+    ## Select clock frequency. Warning: the default clock frequency for
+    ## this board is 168MHz and not 180MHz because, due to a limitation in
+    ## the PLL, it is not possible to generate a precise 48MHz output when
+    ## running the core at 180MHz. If 180MHz is chosen the USB peripheral will
+    ## NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48)
+    #set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000)
+    set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000)
+    #set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000)
+
+endif()
+
 ##---------------------------------------------------------------------------
 ## stm32f429zi_skyward_groundstation_parafoil
 ##
@@ -1057,6 +1090,8 @@ elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_death_stack_v3)
     set(ARCH cortexM4_stm32f4)
 elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_groundstation)
     set(ARCH cortexM4_stm32f4)
+elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_groundstation_v2)
+    set(ARCH cortexM4_stm32f4)
 elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_groundstation_parafoil)
     set(ARCH cortexM4_stm32f4)
 elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_pyxis_auxiliary)
@@ -2277,33 +2312,66 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4)
     ##
     elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_groundstation)
 
-    ## Base directory with header files for this board
-    set(BOARD_INC arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation)
+        ## Base directory with header files for this board
+        set(BOARD_INC arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation)
 
-    ## Select linker script and boot file
-    ## Their path must be relative to the miosix directory.
-    set(BOOT_FILE ${KPATH}/${BOARD_INC}/core/stage_1_boot.cpp)
-    #set(LINKER_SCRIPT already selected in board options)
+        ## Select linker script and boot file
+        ## Their path must be relative to the miosix directory.
+        set(BOOT_FILE ${KPATH}/${BOARD_INC}/core/stage_1_boot.cpp)
+        #set(LINKER_SCRIPT already selected in board options)
 
-    ## Select architecture specific files
-    ## These are the files in arch/<arch name>/<board name>
-    set(ARCH_SRC
-        ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp
-        ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
-        ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
-    )
+        ## Select architecture specific files
+        ## These are the files in arch/<arch name>/<board name>
+        set(ARCH_SRC
+            ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp
+            ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
+            ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
+        )
 
-    ## Add a #define to allow querying board name
-    list(APPEND CFLAGS_BASE -D_BOARD_STM32F429ZI_SKYWARD_GS)
-    list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F429ZI_SKYWARD_GS)
+        ## Add a #define to allow querying board name
+        list(APPEND CFLAGS_BASE -D_BOARD_STM32F429ZI_SKYWARD_GS)
+        list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F429ZI_SKYWARD_GS)
 
-    ## Select programmer command line
-    ## This is the program that is invoked when the user types
-    ## 'make program'
-    ## The command must provide a way to program the board, or print an
-    ## error message saying that 'make program' is not supported for that
-    ## board.
-    set(PROGRAM_CMDLINE qstlink2 -cqewV ./main.bin)
+        ## Select programmer command line
+        ## This is the program that is invoked when the user types
+        ## 'make program'
+        ## The command must provide a way to program the board, or print an
+        ## error message saying that 'make program' is not supported for that
+        ## board.
+        set(PROGRAM_CMDLINE qstlink2 -cqewV ./main.bin)
+
+    ##-------------------------------------------------------------------------
+    ## BOARD: stm32f429zi_skyward_groundstation_v2
+    ##
+    elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_groundstation_v2)
+
+        ## Base directory with header files for this board
+        set(BOARD_INC arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2)
+
+        ## Select linker script and boot file
+        ## Their path must be relative to the miosix directory.
+        set(BOOT_FILE ${KPATH}/${BOARD_INC}/core/stage_1_boot.cpp)
+        #set(LINKER_SCRIPT already selected in board options)
+
+        ## Select architecture specific files
+        ## These are the files in arch/<arch name>/<board name>
+        set(ARCH_SRC
+            ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp
+            ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
+            ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
+        )
+
+        ## Add a #define to allow querying board name
+        list(APPEND CFLAGS_BASE -D_BOARD_STM32F429ZI_SKYWARD_GS_V2)
+        list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F429ZI_SKYWARD_GS_V2)
+
+        ## Select programmer command line
+        ## This is the program that is invoked when the user types
+        ## 'make program'
+        ## The command must provide a way to program the board, or print an
+        ## error message saying that 'make program' is not supported for that
+        ## board.
+        set(PROGRAM_CMDLINE qstlink2 -cqewV ./main.bin)
 
     ##-------------------------------------------------------------------------
     ## BOARD: stm32f429zi_skyward_groundstation_parafoil