From d92b52e1630460320c6c2e4a9d5cb9d2dc7ee5e0 Mon Sep 17 00:00:00 2001
From: Alberto Nidasio <alberto.nidasio@skywarder.eu>
Date: Wed, 7 Dec 2022 00:37:32 +0100
Subject: [PATCH] Fixed SD driver for stm32f7

Also fixed a missing memory configuration step in stage_1_boot.cpp. The IRQconfigureCache function has to be called with the position of the external memory in order to setup the MPU properly
---
 ...sd_stm32f2_f4.cpp => sd_stm32f2_f4_f7.cpp} | 160 +++++++++++++-----
 .../{sd_stm32f2_f4.h => sd_stm32f2_f4_f7.h}   |   0
 .../stm32f205_generic/interfaces-impl/bsp.cpp |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |   2 +-
 .../interfaces-impl/bsp.cpp                   |  99 ++++++-----
 .../interfaces-impl/bsp_impl.h                |  33 +++-
 ...1024k+256k_rom.ld => stm32_1m+256k_rom.ld} |  60 ++++---
 .../interfaces-impl/bsp.cpp                   |   1 +
 .../stm32f767zi_nucleo/stm32_2m+384k_ram.ld   |   2 +-
 .../core/stage_1_boot.cpp                     |   2 +-
 .../interfaces-impl/bsp.cpp                   |  13 +-
 .../stm32h753xi_eval/interfaces-impl/bsp.cpp  |   2 +-
 miosix/config/Makefile.inc                    |  29 +++-
 .../stm32f746zg_nucleo/board_settings.h       |  35 ++--
 .../stm32f767zi_nucleo/board_settings.h       |   5 +-
 .../stm32f769ni_discovery/board_settings.h    |   3 +-
 miosix/config/options.cmake                   |  29 +++-
 32 files changed, 321 insertions(+), 186 deletions(-)
 rename miosix/arch/common/drivers/{sd_stm32f2_f4.cpp => sd_stm32f2_f4_f7.cpp} (91%)
 rename miosix/arch/common/drivers/{sd_stm32f2_f4.h => sd_stm32f2_f4_f7.h} (100%)
 rename miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/{stm32_1024k+256k_rom.ld => stm32_1m+256k_rom.ld} (73%)

diff --git a/miosix/arch/common/drivers/sd_stm32f2_f4.cpp b/miosix/arch/common/drivers/sd_stm32f2_f4_f7.cpp
similarity index 91%
rename from miosix/arch/common/drivers/sd_stm32f2_f4.cpp
rename to miosix/arch/common/drivers/sd_stm32f2_f4_f7.cpp
index da9e577e..68ed3b12 100644
--- a/miosix/arch/common/drivers/sd_stm32f2_f4.cpp
+++ b/miosix/arch/common/drivers/sd_stm32f2_f4_f7.cpp
@@ -25,7 +25,7 @@
  *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
  ***************************************************************************/
 
-#include "sd_stm32f2_f4.h"
+#include "sd_stm32f2_f4_f7.h"
 #include "interfaces/bsp.h"
 #include "interfaces/arch_registers.h"
 #include "core/cache_cortexMx.h"
@@ -40,10 +40,10 @@
 //Note: enabling debugging might cause deadlock when using sleep() or reboot()
 //The bug won't be fixed because debugging is only useful for driver development
 ///\internal Debug macro, for normal conditions
-//#define DBG iprintf
+// #define DBG iprintf
 #define DBG(x,...) do {} while(0)
 ///\internal Debug macro, for errors only
-//#define DBGERR iprintf
+// #define DBGERR iprintf
 #define DBGERR(x,...) do {} while(0)
 
 /*
@@ -52,9 +52,17 @@
  */
 #if defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)
 
+#if defined(__SDMMC1)
 #define SDIO                 SDMMC1
 #define RCC_APB2ENR_SDIOEN   RCC_APB2ENR_SDMMC1EN
 #define SDIO_IRQn            SDMMC1_IRQn
+#elif defined(__SDMMC2)
+#define SDIO SDMMC2
+#define RCC_APB2ENR_SDIOEN   RCC_APB2ENR_SDMMC2EN
+#define SDIO_IRQn            SDMMC2_IRQn
+#else
+#warning This error is a reminder that you have not selected between SDMMC1 and SDMMC2 in Makefile.int
+#endif
 
 #define SDIO_STA_STBITERR    0 //This bit has been removed
 #define SDIO_STA_RXOVERR     SDMMC_STA_RXOVERR
@@ -76,6 +84,7 @@
 #define SDIO_CLKCR_CLKEN     SDMMC_CLKCR_CLKEN
 #define SDIO_CLKCR_PWRSAV    SDMMC_CLKCR_PWRSAV
 #define SDIO_CLKCR_PWRSAV    SDMMC_CLKCR_PWRSAV
+#define SDIO_CLKCR_WIDBUS_0  SDMMC_CLKCR_WIDBUS_0
 
 #define SDIO_MASK_STBITERRIE 0 //This bit has been removed
 #define SDIO_MASK_RXOVERRIE  SDMMC_MASK_RXOVERRIE
@@ -93,14 +102,24 @@
 
 #endif //defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)
 
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+#define DMA_Stream           DMA2_Stream0
+#else
+#define DMA_Stream           DMA2_Stream3
+#endif
+
 /**
  * \internal
- * DMA2 Stream3 interrupt handler
+ * DMA2 Stream interrupt handler
  */
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+void __attribute__((naked)) DMA2_Stream0_IRQHandler()
+#else
 void __attribute__((naked)) DMA2_Stream3_IRQHandler()
+#endif
 {
     saveContext();
-    asm volatile("bl _ZN6miosix18DMA2stream3irqImplEv");
+    asm volatile("bl _ZN6miosix12SDDMAirqImplEv");
     restoreContext();
 }
 
@@ -108,14 +127,16 @@ void __attribute__((naked)) DMA2_Stream3_IRQHandler()
  * \internal
  * SDIO interrupt handler
  */
-#if defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC1)
 void __attribute__((naked)) SDMMC1_IRQHandler()
+#elif (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+void __attribute__((naked)) SDMMC2_IRQHandler()
 #else //stm32f2 and stm32f4
 void __attribute__((naked)) SDIO_IRQHandler()
 #endif
 {
     saveContext();
-    asm volatile("bl _ZN6miosix11SDIOirqImplEv");
+    asm volatile("bl _ZN6miosix9SDirqImplEv");
     restoreContext();
 }
 
@@ -130,16 +151,26 @@ static unsigned int sdioFlags;      ///< \internal SDIO status flags
  * \internal
  * DMA2 Stream3 interrupt handler actual implementation
  */
-void __attribute__((used)) DMA2stream3irqImpl()
+void __attribute__((used)) SDDMAirqImpl()
 {
     dmaFlags=DMA2->LISR;
-    if(dmaFlags & (DMA_LISR_TEIF3 | DMA_LISR_DMEIF3 | DMA_LISR_FEIF3))
-        transferError=true;
-    
-    DMA2->LIFCR=DMA_LIFCR_CTCIF3  |
-                DMA_LIFCR_CTEIF3  |
-                DMA_LIFCR_CDMEIF3 |
-                DMA_LIFCR_CFEIF3;
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+    if (dmaFlags & (DMA_LISR_TEIF0 | DMA_LISR_DMEIF0 | DMA_LISR_FEIF0))
+        transferError = true;
+
+    DMA2->LIFCR = DMA_LIFCR_CTCIF0 |
+                    DMA_LIFCR_CTEIF0 |
+                    DMA_LIFCR_CDMEIF0 |
+                    DMA_LIFCR_CFEIF0;
+#else
+    if (dmaFlags & (DMA_LISR_TEIF3 | DMA_LISR_DMEIF3 | DMA_LISR_FEIF3))
+        transferError = true;
+
+    DMA2->LIFCR = DMA_LIFCR_CTCIF3 |
+                    DMA_LIFCR_CTEIF3 |
+                    DMA_LIFCR_CDMEIF3 |
+                    DMA_LIFCR_CFEIF3;
+#endif
     
     if(!waiting) return;
     waiting->IRQwakeup();
@@ -152,7 +183,7 @@ void __attribute__((used)) DMA2stream3irqImpl()
  * \internal
  * DMA2 Stream3 interrupt handler actual implementation
  */
-void __attribute__((used)) SDIOirqImpl()
+void __attribute__((used)) SDirqImpl()
 {
     sdioFlags=SDIO->STA;
     if(sdioFlags & (SDIO_STA_STBITERR | SDIO_STA_RXOVERR  |
@@ -193,12 +224,22 @@ enum CardType
 static CardType cardType=Invalid;
 
 //SD card GPIOs
-typedef Gpio<GPIOC_BASE,8>  sdD0;
-typedef Gpio<GPIOC_BASE,9>  sdD1;
-typedef Gpio<GPIOC_BASE,10> sdD2;
-typedef Gpio<GPIOC_BASE,11> sdD3;
-typedef Gpio<GPIOC_BASE,12> sdCLK;
-typedef Gpio<GPIOD_BASE,2>  sdCMD;
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+typedef Gpio<GPIOG_BASE, 9> sdD0;
+typedef Gpio<GPIOG_BASE, 10> sdD1;
+typedef Gpio<GPIOB_BASE, 3> sdD2;
+typedef Gpio<GPIOB_BASE, 4> sdD3;
+typedef Gpio<GPIOD_BASE, 6> sdCLK;
+typedef Gpio<GPIOD_BASE, 7> sdCMD;
+#else
+typedef Gpio<GPIOC_BASE, 8> sdD0;
+typedef Gpio<GPIOC_BASE, 9> sdD1;
+typedef Gpio<GPIOC_BASE, 10> sdD2;
+typedef Gpio<GPIOC_BASE, 11> sdD3;
+typedef Gpio<GPIOC_BASE, 12> sdCLK;
+typedef Gpio<GPIOD_BASE, 2> sdCMD;
+#endif
+
 
 //
 // Class BufferConverter
@@ -884,14 +925,12 @@ static void displayBlockTransferError()
 static unsigned int dmaTransferCommonSetup(const unsigned char *buffer)
 {
     //Clear both SDIO and DMA interrupt flags
-    SDIO->ICR=0x7ff;
-    DMA2->LIFCR=DMA_LIFCR_CTCIF3  |
-                DMA_LIFCR_CTEIF3  |
-                DMA_LIFCR_CDMEIF3 |
-                DMA_LIFCR_CFEIF3;
-    
+    SDIO->ICR=0x4005ff;
+    DMA2->LIFCR=0xffffffff;
+
     transferError=false;
-    dmaFlags=sdioFlags=0;
+    dmaFlags=0;
+    sdioFlags=0;
     waiting=Thread::getCurrentThread();
     
     //Select DMA transfer size based on buffer alignment. Best performance
@@ -937,13 +976,17 @@ static bool multipleBlockRead(unsigned char *buffer, unsigned int nblk,
                SDIO_MASK_TXUNDERRIE | //Interrupt on tx underrun
                SDIO_MASK_DCRCFAILIE | //Interrupt on data CRC fail
                SDIO_MASK_DTIMEOUTIE;  //Interrupt on data timeout
-	DMA2_Stream3->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO);
-	DMA2_Stream3->M0AR=reinterpret_cast<unsigned int>(buffer);
-	//Note: DMA2_Stream3->NDTR is don't care in peripheral flow control mode
-    DMA2_Stream3->FCR=DMA_SxFCR_FEIE    | //Interrupt on fifo error
+	DMA_Stream->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO);
+	DMA_Stream->M0AR=reinterpret_cast<unsigned int>(buffer);
+	//Note: DMA_Stream->NDTR is don't care in peripheral flow control mode
+    DMA_Stream->FCR=DMA_SxFCR_FEIE    | //Interrupt on fifo error
                       DMA_SxFCR_DMDIS   | //Fifo enabled
                       DMA_SxFCR_FTH_0;    //Take action if fifo half full
-	DMA2_Stream3->CR=DMA_SxCR_CHSEL_2   | //Channel 4 (SDIO)
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+    DMA_Stream->CR = (11 << DMA_SxCR_CHSEL_Pos) | // Channel 4 (SDIO)
+#else
+    DMA_Stream->CR = DMA_SxCR_CHSEL_2 | // Channel 4 (SDIO)
+#endif
                      DMA_SxCR_PBURST_0  | //4-beat bursts read from SDIO
                      DMA_SxCR_PL_0      | //Medium priority DMA stream
                      memoryTransferSize | //RAM data size depends on alignment
@@ -977,8 +1020,8 @@ static bool multipleBlockRead(unsigned char *buffer, unsigned int nblk,
             }
         }
     } else transferError=true;
-    DMA2_Stream3->CR=0;
-    while(DMA2_Stream3->CR & DMA_SxCR_EN) ; //DMA may take time to stop
+    DMA_Stream->CR=0;
+    while(DMA_Stream->CR & DMA_SxCR_EN) ; //DMA may take time to stop
     SDIO->DCTRL=0; //Disable data path state machine
     SDIO->MASK=0;
 
@@ -1040,16 +1083,20 @@ static bool multipleBlockWrite(const unsigned char *buffer, unsigned int nblk,
                SDIO_MASK_TXUNDERRIE | //Interrupt on tx underrun
                SDIO_MASK_DCRCFAILIE | //Interrupt on data CRC fail
                SDIO_MASK_DTIMEOUTIE;  //Interrupt on data timeout
-	DMA2_Stream3->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO);
-	DMA2_Stream3->M0AR=reinterpret_cast<unsigned int>(buffer);
-	//Note: DMA2_Stream3->NDTR is don't care in peripheral flow control mode
+	DMA_Stream->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO);
+	DMA_Stream->M0AR=reinterpret_cast<unsigned int>(buffer);
+	//Note: DMA_Stream->NDTR is don't care in peripheral flow control mode
     //Quirk: not enabling DMA_SxFCR_FEIE because the SDIO seems to generate
     //a spurious fifo error. The code was tested and the transfer completes
     //successfully even in the presence of this fifo error
-    DMA2_Stream3->FCR=DMA_SxFCR_DMDIS   | //Fifo enabled
+    DMA_Stream->FCR=DMA_SxFCR_DMDIS   | //Fifo enabled
                       DMA_SxFCR_FTH_1   | //Take action if fifo full
                       DMA_SxFCR_FTH_0;
-	DMA2_Stream3->CR=DMA_SxCR_CHSEL_2   | //Channel 4 (SDIO)
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+    DMA_Stream->CR = (11 << DMA_SxCR_CHSEL_Pos) | // Channel 4 (SDIO)
+#else
+    DMA_Stream->CR = DMA_SxCR_CHSEL_2 |   // Channel 4 (SDIO)
+#endif
                      DMA_SxCR_PBURST_0  | //4-beat bursts write to SDIO
                      DMA_SxCR_PL_0      | //Medium priority DMA stream
                      memoryTransferSize | //RAM data size depends on alignment
@@ -1082,8 +1129,8 @@ static bool multipleBlockWrite(const unsigned char *buffer, unsigned int nblk,
             }
         }
     } else transferError=true;
-    DMA2_Stream3->CR=0;
-    while(DMA2_Stream3->CR & DMA_SxCR_EN) ; //DMA may take time to stop
+    DMA_Stream->CR=0;
+    while(DMA_Stream->CR & DMA_SxCR_EN) ; //DMA may take time to stop
     SDIO->DCTRL=0; //Disable data path state machine
     SDIO->MASK=0;
 
@@ -1161,23 +1208,46 @@ static void initSDIOPeripheral()
         RCC_SYNC();
         RCC->APB2ENR |= RCC_APB2ENR_SDIOEN;
         RCC_SYNC();
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+        sdD0::mode(Mode::ALTERNATE);
+        sdD0::alternateFunction(11);
+#ifndef SD_ONE_BIT_DATABUS
+        sdD1::mode(Mode::ALTERNATE);
+        sdD1::alternateFunction(11);
+        sdD2::mode(Mode::ALTERNATE);
+        sdD2::alternateFunction(10);
+        sdD3::mode(Mode::ALTERNATE);
+        sdD3::alternateFunction(10);
+#endif // SD_ONE_BIT_DATABUS
+        sdCLK::mode(Mode::ALTERNATE);
+        sdCLK::alternateFunction(11);
+        sdCMD::mode(Mode::ALTERNATE);
+        sdCMD::alternateFunction(11);
+#else
         sdD0::mode(Mode::ALTERNATE);
         sdD0::alternateFunction(12);
-        #ifndef SD_ONE_BIT_DATABUS
+#ifndef SD_ONE_BIT_DATABUS
         sdD1::mode(Mode::ALTERNATE);
         sdD1::alternateFunction(12);
         sdD2::mode(Mode::ALTERNATE);
         sdD2::alternateFunction(12);
         sdD3::mode(Mode::ALTERNATE);
         sdD3::alternateFunction(12);
-        #endif //SD_ONE_BIT_DATABUS
+#endif // SD_ONE_BIT_DATABUS
         sdCLK::mode(Mode::ALTERNATE);
         sdCLK::alternateFunction(12);
         sdCMD::mode(Mode::ALTERNATE);
         sdCMD::alternateFunction(12);
+#endif
     }
+
+#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && defined(__SDMMC2)
+    NVIC_SetPriority(DMA2_Stream0_IRQn,15);//Low priority for DMA
+    NVIC_EnableIRQ(DMA2_Stream0_IRQn);
+#else
     NVIC_SetPriority(DMA2_Stream3_IRQn,15);//Low priority for DMA
     NVIC_EnableIRQ(DMA2_Stream3_IRQn);
+#endif
     NVIC_SetPriority(SDIO_IRQn,15);//Low priority for SDIO
     NVIC_EnableIRQ(SDIO_IRQn);
     
diff --git a/miosix/arch/common/drivers/sd_stm32f2_f4.h b/miosix/arch/common/drivers/sd_stm32f2_f4_f7.h
similarity index 100%
rename from miosix/arch/common/drivers/sd_stm32f2_f4.h
rename to miosix/arch/common/drivers/sd_stm32f2_f4_f7.h
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f205_generic/interfaces-impl/bsp.cpp b/miosix/arch/cortexM3_stm32f2/stm32f205_generic/interfaces-impl/bsp.cpp
index d5a5be65..ecf45f59 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f205_generic/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM3_stm32f2/stm32f205_generic/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "drivers/dcc.h"
 #include "board_settings.h"
 
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/interfaces-impl/bsp.cpp b/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/interfaces-impl/bsp.cpp
index 85bafd95..c3f154d4 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_stormtrooper/interfaces-impl/bsp.cpp
@@ -45,7 +45,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 using namespace std;
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp
index 375b9953..b421278a 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "drivers/dcc.h"
 #include "board_settings.h"
 
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/bsp.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/bsp.cpp
index 0c804db3..08b143b5 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/bsp.cpp
@@ -45,7 +45,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "drivers/dcc.h"
 #include "board_settings.h"
 
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f401re_nucleo/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f401re_nucleo/interfaces-impl/bsp.cpp
index 73c3d9de..d5ceb671 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f401re_nucleo/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f401re_nucleo/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/interfaces-impl/bsp.cpp
index 5c9a0963..a6d09330 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f401vc_stm32f4discovery/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/bsp.cpp
index 517187ec..09568c80 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_bitsboard/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/bsp.cpp
index 00bd3b64..06938eb4 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_thermal_test_chip/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f407vg_thermal_test_chip/interfaces-impl/bsp.cpp
index 0befcc82..6015c0f7 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f407vg_thermal_test_chip/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_thermal_test_chip/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f411ce_blackpill/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f411ce_blackpill/interfaces-impl/bsp.cpp
index 73c3d9de..d5ceb671 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f411ce_blackpill/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f411ce_blackpill/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/interfaces-impl/bsp.cpp
index 73c3d9de..d5ceb671 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f411re_nucleo/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/interfaces-impl/bsp.cpp
index 028ca42a..de452140 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_oledboard2/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/interfaces-impl/bsp.cpp
index c8d03fce..83e7da7b 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_anakin/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "drivers/stm32_sgm.h"
 #include "board_settings.h"
 
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_homeone/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_homeone/interfaces-impl/bsp.cpp
index e33e85e5..fa8f4dff 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_homeone/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_homeone/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 #include "hwmapping.h"
 
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/interfaces-impl/bsp.cpp
index 71b05b12..c6104c40 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 // #include "kernel/IRQDisplayPrint.h"
 
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f469ni_stm32f469i-disco/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32f4/stm32f469ni_stm32f469i-disco/interfaces-impl/bsp.cpp
index 2039114f..91e068ad 100644
--- a/miosix/arch/cortexM4_stm32f4/stm32f469ni_stm32f469i-disco/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32f4/stm32f469ni_stm32f469i-disco/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 // #include "kernel/IRQDisplayPrint.h"
 
diff --git a/miosix/arch/cortexM4_stm32l4/stm32l476rg_nucleo/interfaces-impl/bsp.cpp b/miosix/arch/cortexM4_stm32l4/stm32l476rg_nucleo/interfaces-impl/bsp.cpp
index 73b3badc..830d5e5e 100644
--- a/miosix/arch/cortexM4_stm32l4/stm32l476rg_nucleo/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM4_stm32l4/stm32l476rg_nucleo/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp.cpp b/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp.cpp
index 24bb3571..4255b80d 100644
--- a/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp.cpp
@@ -23,29 +23,32 @@
  *                                                                         *
  *   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.
-************************************************************************/
+ * bsp.cpp Part of the Miosix Embedded OS.
+ * Board support package, this file initializes hardware.
+ ************************************************************************/
+
+#include "interfaces/bsp.h"
 
-#include <cstdlib>
 #include <inttypes.h>
 #include <sys/ioctl.h>
-#include "interfaces/bsp.h"
-#include "kernel/kernel.h"
-#include "kernel/sync.h"
+
+#include <cstdlib>
+
+#include "board_settings.h"
+#include "config/miosix_settings.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
+#include "drivers/serial.h"
+#include "filesystem/console/console_device.h"
+#include "filesystem/file_access.h"
+#include "interfaces/arch_registers.h"
 #include "interfaces/delays.h"
 #include "interfaces/portability.h"
-#include "interfaces/arch_registers.h"
-#include "config/miosix_settings.h"
+#include "kernel/kernel.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 "kernel/sync.h"
 
 namespace miosix {
 
@@ -53,64 +56,68 @@ namespace miosix {
 // Initialization
 //
 
-void IRQbspInit()
-{
-    //Enable all gpios
+void IRQbspInit() {
+    // Enable all gpios
     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
                     RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
                     RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN |
                     RCC_AHB1ENR_GPIOHEN;
     RCC_SYNC();
-    GPIOA->OSPEEDR=0xaaaaaaaa; //Default to 50MHz speed for all GPIOS
-    GPIOB->OSPEEDR=0xaaaaaaaa;
-    GPIOC->OSPEEDR=0xaaaaaaaa;
-    GPIOD->OSPEEDR=0xaaaaaaaa;
-    GPIOE->OSPEEDR=0xaaaaaaaa;
-    GPIOF->OSPEEDR=0xaaaaaaaa;
-    GPIOH->OSPEEDR=0xaaaaaaaa;
-    _led::mode(Mode::OUTPUT);
+    GPIOA->OSPEEDR = 0xaaaaaaaa;  // Default to 50MHz speed for all GPIOS
+    GPIOB->OSPEEDR = 0xaaaaaaaa;
+    GPIOC->OSPEEDR = 0xaaaaaaaa;
+    GPIOD->OSPEEDR = 0xaaaaaaaa;
+    GPIOE->OSPEEDR = 0xaaaaaaaa;
+    GPIOF->OSPEEDR = 0xaaaaaaaa;
+    GPIOH->OSPEEDR = 0xaaaaaaaa;
+
+    userLed1::mode(Mode::OUTPUT);
+    userLed2::mode(Mode::OUTPUT);
+    userLed3::mode(Mode::OUTPUT);
+    userBtn::mode(Mode::INPUT);
+
     ledOn();
     delayMs(100);
     ledOff();
-    auto tx=Gpio<GPIOD_BASE,8>::getPin(); tx.alternateFunction(7);
-    auto rx=Gpio<GPIOD_BASE,9>::getPin(); rx.alternateFunction(7);
+    auto tx = Gpio<GPIOD_BASE, 8>::getPin();
+    tx.alternateFunction(7);
+    auto rx = Gpio<GPIOD_BASE, 9>::getPin();
+    rx.alternateFunction(7);
     DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(
-        new STM32Serial(3,defaultSerialSpeed,tx,rx)));
+        new STM32Serial(3, defaultSerialSpeed, tx, rx)));
 }
 
-void bspInit2()
-{
-    #ifdef WITH_FILESYSTEM
+void bspInit2() {
+#ifdef WITH_FILESYSTEM
     basicFilesystemSetup(SDIODriver::instance());
-    #endif //WITH_FILESYSTEM
+#endif  // WITH_FILESYSTEM
 }
 
 //
 // Shutdown and reboot
 //
 
-void shutdown()
-{
-    ioctl(STDOUT_FILENO,IOCTL_SYNC,0);
+void shutdown() {
+    ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
 
-    #ifdef WITH_FILESYSTEM
+#ifdef WITH_FILESYSTEM
     FilesystemManager::instance().umountAll();
-    #endif //WITH_FILESYSTEM
+#endif  // WITH_FILESYSTEM
 
     disableInterrupts();
-    for(;;) ;
+    for (;;)
+        ;
 }
 
-void reboot()
-{
-    ioctl(STDOUT_FILENO,IOCTL_SYNC,0);
-    
-    #ifdef WITH_FILESYSTEM
+void reboot() {
+    ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
+
+#ifdef WITH_FILESYSTEM
     FilesystemManager::instance().umountAll();
-    #endif //WITH_FILESYSTEM
+#endif  // WITH_FILESYSTEM
 
     disableInterrupts();
     miosix_private::IRQsystemReboot();
 }
 
-} //namespace miosix
+}  // namespace miosix
diff --git a/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp_impl.h b/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp_impl.h
index 6dcfe5b9..a085aeb2 100644
--- a/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp_impl.h
+++ b/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/interfaces-impl/bsp_impl.h
@@ -45,20 +45,37 @@ namespace miosix {
 
 /**
  * \internal
- * used by the ledOn() and ledOff() implementation
+ * Board pin definition
  */
-typedef Gpio<GPIOB_BASE,14> _led;
+typedef Gpio<GPIOB_BASE, 0> userLed1;
+typedef Gpio<GPIOB_BASE, 7> userLed2;
+typedef Gpio<GPIOB_BASE, 14> userLed3;
+typedef Gpio<GPIOC_BASE, 13> userBtn;
 
-inline void ledOn()
-{
-    _led::high();
+inline void ledOn() {
+    userLed1::high();
+    userLed2::high();
+    userLed3::high();
 }
 
-inline void ledOff()
-{
-    _led::low();
+inline void ledOff() {
+    userLed1::low();
+    userLed2::low();
+    userLed3::low();
 }
 
+inline void led1On() { userLed1::high(); }
+
+inline void led1Off() { userLed1::low(); }
+
+inline void led2On() { userLed2::high(); }
+
+inline void led2Off() { userLed2::low(); }
+
+inline void led3On() { userLed3::high(); }
+
+inline void led3Off() { userLed3::low(); }
+
 /**
  * Polls the SD card sense GPIO.
  * 
diff --git a/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/stm32_1024k+256k_rom.ld b/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/stm32_1m+256k_rom.ld
similarity index 73%
rename from miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/stm32_1024k+256k_rom.ld
rename to miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/stm32_1m+256k_rom.ld
index ed31c59f..1f81bdcc 100644
--- a/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/stm32_1024k+256k_rom.ld
+++ b/miosix/arch/cortexM7_stm32f7/stm32f746zg_nucleo/stm32_1m+256k_rom.ld
@@ -1,14 +1,14 @@
 /*
- * C++ enabled linker script for stm32 (1M FLASH, 256K RAM)
+ * C++ enabled linker script for stm32f746zg (1M FLASH, 256K RAM)
  * Developed by TFT: Terraneo Federico Technologies
  * Optimized for use with the Miosix kernel
  */
 
 /*
  * This linker script puts:
- * - read only data and code (.text, .rodata, .eh_*) in flash
- * - stacks, heap and sections .data and .bss in the internal ram
- * - the external ram (if available) is not used.
+ * - read only data and code (.text, .rodata, .eh_*) in FLASH
+ * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 64KB RAM
+ * - .data, .bss, stacks and heap in the internal RAM.
  */
 
 /*
@@ -36,33 +36,35 @@
  * 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_size = 512;                             /* main stack = 512Bytes */
 _main_stack_top  = 0x20000000 + _main_stack_size;
 ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
 
-/* end of the heap on 320KB microcontrollers */
-_heap_end = 0x20050000;                            /* end of available ram  */
+/* Mapping the heap to the end of SRAM2 */
+_heap_end = 0x20000000 + 320K;                       /* end of available ram */
 
-/* identify the Entry Point  */
+/* Identify the Entry Point  */
 ENTRY(_Z13Reset_Handlerv)
 
-/* specify the memory areas  */
+/*
+ * Specify the memory areas
+ *
+ * NOTE: starting at 0x20000000 there's 64KB of DTCM (Data Tightly Coupled
+ * Memory). Technically, we could use this as normal RAM as there's a way for
+ * the DMA to access it, but the datasheet is unclear about performance
+ * penalties for doing so. To avoid nonuniform DMA memory access latencies,
+ * we leave this 64KB DTCM unused except for the first 512Bytes which are for
+ * the interrupt stack. This leaves us with 384KB of RAM
+ */
 MEMORY
 {
-    flash(rx)   : ORIGIN = 0x08000000, LENGTH = 1M
-
-    /*
-     * NOTE: starting at 0x20000000 there's 64KB of DTCM. Technically, we could
-     * use this as normal RAM as there's a way the DMA can access it, but the
-     * datasheet is unclear about performance penalties for doing so.
-     * To avoid nonuniform DMA memory access latencies, we leve this 64KB DTCM
-     * unused except for the first 512Bytes which are for the interrupt stack.
-     * This leaves us with 256KB of RAM
-     */
-    ram(wx)     : ORIGIN = 0x20010000, LENGTH =  256K
+    sram(wx)  : ORIGIN = 0x20010000, LENGTH = 256K
+    dtcm(wx)  : ORIGIN = 0x20000000, LENGTH = 64K     /* Used for main stack */
+    flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M
 }
 
-/* now define the output sections  */
+/* Now define the output sections  */
 SECTIONS
 {
     . = 0;
@@ -76,10 +78,10 @@ SECTIONS
         *(.text)
         *(.text.*)
         *(.gnu.linkonce.t.*)
-        /* these sections for thumb interwork? */
+        /* These sections for thumb interwork? */
         *(.glue_7)
         *(.glue_7t)
-        /* these sections for C++? */
+        /* These sections for C++? */
         *(.gcc_except_table)
         *(.gcc_except_table.*)
         *(.ARM.extab*)
@@ -145,8 +147,10 @@ SECTIONS
     } > flash
     __exidx_end = .;
 
-	/* .data section: global variables go to ram, but also store a copy to
-       flash to initialize them */
+	/*
+     * .data section: global variables go to sram, but also store a copy to
+     * flash to initialize them
+     */
     .data : ALIGN(8)
     {
         _data = .;
@@ -155,10 +159,10 @@ SECTIONS
         *(.gnu.linkonce.d.*)
         . = ALIGN(8);
         _edata = .;
-    } > ram AT > flash
+    } > sram AT > flash
     _etext = LOADADDR(.data);
 
-    /* .bss section: uninitialized global variables go to ram */
+    /* .bss section: uninitialized global variables go to sram */
     _bss_start = .;
     .bss :
     {
@@ -166,7 +170,7 @@ SECTIONS
         *(.bss.*)
         *(.gnu.linkonce.b.*)
         . = ALIGN(8);
-    } > ram
+    } > sram
     _bss_end = .;
 
     _end = .;
diff --git a/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/interfaces-impl/bsp.cpp b/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/interfaces-impl/bsp.cpp
index 1c6af56e..288dab6f 100644
--- a/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/interfaces-impl/bsp.cpp
@@ -41,6 +41,7 @@
 #include "config/miosix_settings.h"
 #include "drivers/serial.h"
 #include "drivers/serial_stm32.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "filesystem/console/console_device.h"
 #include "filesystem/file_access.h"
 #include "interfaces/arch_registers.h"
diff --git a/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/stm32_2m+384k_ram.ld b/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/stm32_2m+384k_ram.ld
index 5047a834..ba3da77b 100644
--- a/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/stm32_2m+384k_ram.ld
+++ b/miosix/arch/cortexM7_stm32f7/stm32f767zi_nucleo/stm32_2m+384k_ram.ld
@@ -37,7 +37,7 @@
  * the MEMORY definitions below accordingly.
  */
 
-_main_stack_size = 0x00000200;                     /* main stack = 512Bytes */
+_main_stack_size = 512;                             /* main stack = 512Bytes */
 _main_stack_top  = 0x20000000 + _main_stack_size;
 ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
 
diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp
index c7c0042b..10027c52 100644
--- a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp
+++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp
@@ -26,7 +26,7 @@ void program_startup() {
     // enabled
     __disable_irq();
 
-    miosix::IRQconfigureCache();
+    miosix::IRQconfigureCache((const unsigned int*)0xc0000000, 16 * 1024 * 1024);
 
     // These are defined in the linker script
     extern unsigned char _etext asm("_etext");
diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp
index c6ea2f50..77e58cdf 100644
--- a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp
@@ -41,6 +41,7 @@
 #include "config/miosix_settings.h"
 #include "drivers/serial.h"
 #include "drivers/serial_stm32.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "filesystem/console/console_device.h"
 #include "filesystem/file_access.h"
 #include "interfaces/arch_registers.h"
@@ -262,7 +263,9 @@ void IRQbspInit() {
 }
 
 void bspInit2() {
-    // Nothing to do
+#ifdef WITH_FILESYSTEM
+    basicFilesystemSetup(SDIODriver::instance());
+#endif  // WITH_FILESYSTEM
 }
 
 //
@@ -272,6 +275,10 @@ void bspInit2() {
 void shutdown() {
     ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
 
+#ifdef WITH_FILESYSTEM
+    FilesystemManager::instance().umountAll();
+#endif  // WITH_FILESYSTEM
+
     disableInterrupts();
     for (;;)
         ;
@@ -280,6 +287,10 @@ void shutdown() {
 void reboot() {
     ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
 
+#ifdef WITH_FILESYSTEM
+    FilesystemManager::instance().umountAll();
+#endif  // WITH_FILESYSTEM
+
     disableInterrupts();
     miosix_private::IRQsystemReboot();
 }
diff --git a/miosix/arch/cortexM7_stm32h7/stm32h753xi_eval/interfaces-impl/bsp.cpp b/miosix/arch/cortexM7_stm32h7/stm32h753xi_eval/interfaces-impl/bsp.cpp
index 9dbc25d7..5217db4c 100644
--- a/miosix/arch/cortexM7_stm32h7/stm32h753xi_eval/interfaces-impl/bsp.cpp
+++ b/miosix/arch/cortexM7_stm32h7/stm32h753xi_eval/interfaces-impl/bsp.cpp
@@ -44,7 +44,7 @@
 #include "filesystem/file_access.h"
 #include "filesystem/console/console_device.h"
 #include "drivers/serial.h"
-#include "drivers/sd_stm32f2_f4.h"
+#include "drivers/sd_stm32f2_f4_f7.h"
 #include "board_settings.h"
 
 namespace miosix {
diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc
index ea5e7feb..6e30f0d6 100644
--- a/miosix/config/Makefile.inc
+++ b/miosix/config/Makefile.inc
@@ -63,7 +63,7 @@
 #OPT_BOARD := stm32l476rg_nucleo
 #OPT_BOARD := atsam4lc2aa_generic
 #OPT_BOARD := stm32f411ce_blackpill
-OPT_BOARD := stm32f767zi_nucleo
+#OPT_BOARD := stm32f767zi_nucleo
 #OPT_BOARD := stm32f769ni_discovery
 
 ##
@@ -2465,7 +2465,7 @@ else ifeq ($(ARCH),cortexM4_stm32f4)
     $(ARCH_INC)/interfaces-impl/portability.cpp              \
     $(ARCH_INC)/interfaces-impl/delays.cpp                   \
     $(ARCH_INC)/interfaces-impl/gpio_impl.cpp                \
-    arch/common/drivers/sd_stm32f2_f4.cpp                    \
+    arch/common/drivers/sd_stm32f2_f4_f7.cpp                 \
     arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c
 
 ##-----------------------------------------------------------------------------
@@ -2490,7 +2490,7 @@ else ifeq ($(ARCH),cortexM3_stm32f2)
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
         ARCH_SRC :=                                  \
-        arch/common/drivers/sd_stm32f2_f4.cpp        \
+        arch/common/drivers/sd_stm32f2_f4_f7.cpp     \
         $(BOARD_INC)/interfaces-impl/delays.cpp      \
         $(BOARD_INC)/interfaces-impl/bsp.cpp
 
@@ -2529,7 +2529,7 @@ else ifeq ($(ARCH),cortexM3_stm32f2)
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
         ARCH_SRC :=                                  \
-        arch/common/drivers/sd_stm32f2_f4.cpp        \
+        arch/common/drivers/sd_stm32f2_f4_f7.cpp     \
         $(BOARD_INC)/interfaces-impl/delays.cpp      \
         $(BOARD_INC)/interfaces-impl/bsp.cpp
 
@@ -2697,7 +2697,7 @@ else ifeq ($(ARCH),cortexM3_stm32f2)
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
         ARCH_SRC :=                                  \
-        arch/common/drivers/sd_stm32f2_f4.cpp        \
+        arch/common/drivers/sd_stm32f2_f4_f7.cpp     \
         arch/common/drivers/stm32f2_f4_i2c.cpp       \
         arch/common/drivers/servo_stm32.cpp          \
         $(BOARD_INC)/interfaces-impl/delays.cpp      \
@@ -2942,7 +2942,7 @@ else ifeq ($(ARCH),cortexM7_stm32f7)
         ## 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 := $(BOARD_INC)/stm32_1024k+256k_rom.ld
+        LINKER_SCRIPT := $(BOARD_INC)/stm32_1m+256k_rom.ld
 
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
@@ -2954,6 +2954,10 @@ else ifeq ($(ARCH),cortexM7_stm32f7)
         CFLAGS_BASE   += -D_BOARD_STM32F746ZG_NUCLEO
         CXXFLAGS_BASE += -D_BOARD_STM32F746ZG_NUCLEO
 
+        ## Select the SDMMC peripheral to use for the filesystem
+        SD := -D__SDMMC1
+        # SD := -D__SDMMC2
+
         ## Select clock frequency (HSE_VALUE is the xtal on board, fixed)
         CLOCK_FREQ := -DHSE_VALUE=8000000 -DSYSCLK_FREQ_216MHz=216000000
 
@@ -2989,6 +2993,10 @@ else ifeq ($(ARCH),cortexM7_stm32f7)
         CFLAGS_BASE   += -D_BOARD_STM32F767ZI_NUCLEO
         CXXFLAGS_BASE += -D_BOARD_STM32F767ZI_NUCLEO
 
+        ## Select the SDMMC peripheral to use for the filesystem
+        SD := -D__SDMMC1
+        # SD := -D__SDMMC2
+
         ## Select clock frequency (HSE_VALUE is the xtal on board, fixed)
         CLOCK_FREQ := -DHSE_VALUE=8000000 -DSYSCLK_FREQ_216MHz=216000000
 
@@ -3028,6 +3036,10 @@ else ifeq ($(ARCH),cortexM7_stm32f7)
         ## Enables the initialization of the external 16MB SDRAM memory
         XRAM := -D__ENABLE_XRAM
 
+        ## Select the SDMMC peripheral to use for the filesystem
+        # SD := -D__SDMMC1
+        SD := -D__SDMMC2
+
         ## Select clock frequency (HSE_VALUE is the xtal on board, fixed)
         CLOCK_FREQ := -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000
 
@@ -3059,9 +3071,9 @@ else ifeq ($(ARCH),cortexM7_stm32f7)
 
     AFLAGS_BASE   := $(ARCHOPTS)
     CFLAGS_BASE   += -D_ARCH_CORTEXM7_STM32F7 $(CLOCK_FREQ) $(XRAM) $(SRAM_BOOT)\
-                     $(ARCHOPTS) $(OPT_OPTIMIZATION) -c
+                     $(SD) $(ARCHOPTS) $(OPT_OPTIMIZATION) -c
     CXXFLAGS_BASE += -D_ARCH_CORTEXM7_STM32F7 $(CLOCK_FREQ) $(XRAM) $(SRAM_BOOT)\
-                     $(ARCHOPTS) $(OPT_EXCEPT) $(OPT_OPTIMIZATION) -c
+                     $(SD) $(ARCHOPTS) $(OPT_EXCEPT) $(OPT_OPTIMIZATION) -c
     LFLAGS_BASE   := $(ARCHOPTS) -Wl,--gc-sections,-Map,main.map                \
                      -Wl,-T$(KPATH)/$(LINKER_SCRIPT) $(OPT_EXCEPT)              \
                      $(OPT_OPTIMIZATION) -nostdlib
@@ -3073,6 +3085,7 @@ else ifeq ($(ARCH),cortexM7_stm32f7)
     arch/common/core/mpu_cortexMx.cpp                        \
     arch/common/core/cache_cortexMx.cpp                      \
     arch/common/drivers/serial_stm32.cpp                     \
+    arch/common/drivers/sd_stm32f2_f4_f7.cpp                 \
     arch/common/drivers/dcc.cpp                              \
     $(ARCH_INC)/interfaces-impl/portability.cpp              \
     $(ARCH_INC)/interfaces-impl/delays.cpp                   \
diff --git a/miosix/config/arch/cortexM7_stm32f7/stm32f746zg_nucleo/board_settings.h b/miosix/config/arch/cortexM7_stm32f7/stm32f746zg_nucleo/board_settings.h
index 5a70bc39..db80454f 100644
--- a/miosix/config/arch/cortexM7_stm32f7/stm32f746zg_nucleo/board_settings.h
+++ b/miosix/config/arch/cortexM7_stm32f7/stm32f746zg_nucleo/board_settings.h
@@ -44,33 +44,28 @@ namespace miosix {
  */
 
 /// Size of stack for main().
-/// The C standard library is stack-heavy (iprintf requires 1KB) 
-const unsigned int MAIN_STACK_SIZE=4*1024;
+/// The C standard library is stack-heavy (iprintf requires 1KB)
+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;
+/// Frequency of tick (in Hz). 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
+/// 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
-//This board only exposes USART3, without flow control, connected to an UART/USB
-const unsigned int defaultSerialSpeed=115200;
-// #define SERIAL_1_DMA
-// #define SERIAL_2_DMA
+const unsigned int defaultSerialSpeed = 115200;
 #define SERIAL_3_DMA
 
-//SD card driver
-static const unsigned char sdVoltage=33; //Board powered @ 3.3V
-#define SD_ONE_BIT_DATABUS //For now we'll use 1 bit bus
+// SD card driver
+static const unsigned char sdVoltage = 33;  // Board powered @ 3.3V
+// #define SD_ONE_BIT_DATABUS
 
 /**
  * \}
diff --git a/miosix/config/arch/cortexM7_stm32f7/stm32f767zi_nucleo/board_settings.h b/miosix/config/arch/cortexM7_stm32f7/stm32f767zi_nucleo/board_settings.h
index 80a64881..cc61b139 100644
--- a/miosix/config/arch/cortexM7_stm32f7/stm32f767zi_nucleo/board_settings.h
+++ b/miosix/config/arch/cortexM7_stm32f7/stm32f767zi_nucleo/board_settings.h
@@ -59,10 +59,13 @@ const unsigned int AUX_TIMER_CLOCK = 100000;
 const unsigned int AUX_TIMER_MAX = 0xffff;  ///<\internal Aux timer is 16 bits
 
 /// Serial port
-// This board only exposes USART3, without flow control
 const unsigned int defaultSerialSpeed = 115200;
 #define SERIAL_3_DMA
 
+// SD card driver
+static const unsigned char sdVoltage = 33;  // Board powered @ 3.3V
+// #define SD_ONE_BIT_DATABUS
+
 /**
  * \}
  */
diff --git a/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h b/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h
index ca505da4..14ebb531 100644
--- a/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h
+++ b/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h
@@ -61,10 +61,11 @@ 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;
-// #define SERIAL_1_DMA
+#define SERIAL_1_DMA
 
 // SD card driver
 static const unsigned char sdVoltage = 33;  // Board powered @ 3.3V
+// #define SD_ONE_BIT_DATABUS
 
 /**
  * \}
diff --git a/miosix/config/options.cmake b/miosix/config/options.cmake
index 7aa85f8c..6a76c2b3 100644
--- a/miosix/config/options.cmake
+++ b/miosix/config/options.cmake
@@ -2590,7 +2590,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4)
         ${KPATH}/${ARCH_INC}/interfaces-impl/portability.cpp
         ${KPATH}/${ARCH_INC}/interfaces-impl/delays.cpp
         ${KPATH}/${ARCH_INC}/interfaces-impl/gpio_impl.cpp
-        ${KPATH}/arch/common/drivers/sd_stm32f2_f4.cpp
+        ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
         ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c
     )
 
@@ -2617,7 +2617,7 @@ elseif(${ARCH} STREQUAL cortexM3_stm32f2)
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
         set(ARCH_SRC
-            ${KPATH}/arch/common/drivers/sd_stm32f2_f4.cpp
+            ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
             ${KPATH}/${BOARD_INC}/interfaces-impl/delays.cpp
             ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
         )
@@ -2657,7 +2657,7 @@ elseif(${ARCH} STREQUAL cortexM3_stm32f2)
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
         set(ARCH_SRC
-            ${KPATH}/arch/common/drivers/sd_stm32f2_f4.cpp
+            ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
             ${KPATH}/${BOARD_INC}/interfaces-impl/delays.cpp
             ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
         )
@@ -2808,7 +2808,7 @@ elseif(${ARCH} STREQUAL cortexM3_stm32f2)
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
         set(ARCH_SRC
-            ${KPATH}/arch/common/drivers/sd_stm32f2_f4.cpp
+            ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
             ${KPATH}/${BOARD_INC}/interfaces-impl/delays.cpp
             ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
         )
@@ -2836,7 +2836,7 @@ elseif(${ARCH} STREQUAL cortexM3_stm32f2)
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
         set(ARCH_SRC
-            ${KPATH}/arch/common/drivers/sd_stm32f2_f4.cpp
+            ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
             ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp
             ${KPATH}/arch/common/drivers/servo_stm32.cpp
             ${KPATH}/${BOARD_INC}/interfaces-impl/delays.cpp
@@ -3033,7 +3033,7 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7)
         ## 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 ${KPATH}/${BOARD_INC}/stm32_1024k+256k_rom.ld)
+        set(LINKER_SCRIPT ${KPATH}/${BOARD_INC}/stm32_1m+256k_rom.ld)
 
         ## Select architecture specific files
         ## These are the files in arch/<arch name>/<board name>
@@ -3046,6 +3046,10 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7)
         list(APPEND CFLAGS_BASE -D_BOARD_STM32F746ZG_NUCLEO)
         list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F746ZG_NUCLEO)
 
+        ## Select the SDMMC peripheral to use for the filesystem
+        set(SD -D__SDMMC1)
+        # set(SD -D__SDMMC2)
+
         ## Select clock frequency (HSE_VALUE is the xtal on board, fixed)
         set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_216MHz=216000000)
 
@@ -3082,6 +3086,10 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7)
         list(APPEND CFLAGS_BASE -D_BOARD_STM32F767ZI_NUCLEO)
         list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F767ZI_NUCLEO)
 
+        ## Select the SDMMC peripheral to use for the filesystem
+        set(SD -D__SDMMC1)
+        # set(SD -D__SDMMC2)
+
         ## Enables the initialization of the external 16MB SDRAM memory
         set(XRAM -D__ENABLE_XRAM)
 
@@ -3122,6 +3130,10 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7)
         list(APPEND CFLAGS_BASE -D_BOARD_STM32F769NI_DISCO)
         list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F769NI_DISCO)
 
+        ## Select the SDMMC peripheral to use for the filesystem
+        # set(SD -D__SDMMC1)
+        set(SD -D__SDMMC2)
+
         ## Enables the initialization of the external 16MB SDRAM memory
         set(XRAM -D__ENABLE_XRAM)
 
@@ -3142,8 +3154,8 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7)
     endif()
 
     set(AFLAGS_BASE ${ARCHOPTS})
-    list(APPEND CFLAGS_BASE -D_ARCH_CORTEXM7_STM32F7 ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${ARCHOPTS} ${OPT_OPTIMIZATION} -c)
-    list(APPEND CXXFLAGS_BASE -D_ARCH_CORTEXM7_STM32F7 ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${ARCHOPTS} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -c)
+    list(APPEND CFLAGS_BASE -D_ARCH_CORTEXM7_STM32F7 ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${SD} ${ARCHOPTS} ${OPT_OPTIMIZATION} -c)
+    list(APPEND CXXFLAGS_BASE -D_ARCH_CORTEXM7_STM32F7 ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${SD} ${ARCHOPTS} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -c)
     set(LFLAGS_BASE ${ARCHOPTS} -Wl,--gc-sections,-Map=main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib)
 
     ## Select architecture specific files
@@ -3153,6 +3165,7 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7)
         ${KPATH}/arch/common/core/mpu_cortexMx.cpp
         ${KPATH}/arch/common/core/cache_cortexMx.cpp
         ${KPATH}/arch/common/drivers/serial_stm32.cpp
+        ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
         ${KPATH}/arch/common/drivers/dcc.cpp
         ${KPATH}/${ARCH_INC}/interfaces-impl/portability.cpp
         ${KPATH}/${ARCH_INC}/interfaces-impl/delays.cpp
-- 
GitLab