diff --git a/CMakeLists.txt b/CMakeLists.txt
index c2605d79175e8c79e0b9b6bf492a968d4a7dea9f..88149950fc8e4b508382ee92c1c832856e93c459 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,501 +1,63 @@
-# Copyright (c) 2021 Skyward Experimental Rocketry
-# Author: Damiano Amatruda
+# Copyright (C) 2024 by Skyward
 #
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
 #
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
+# 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.
 #
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-cmake_minimum_required(VERSION 3.25)
-enable_testing()
-include(cmake/sbs.cmake)
-
-#-----------------------------------------------------------------------------#
-#                                   Project                                   #
-#-----------------------------------------------------------------------------#
-
-project(Boardcore)
-
-#-----------------------------------------------------------------------------#
-#                                 Entrypoints                                 #
-#-----------------------------------------------------------------------------#
-
-add_executable(bmx160-calibration-v2 src/entrypoints/bmx160-calibration-entry.cpp)
-sbs_target(bmx160-calibration-v2 stm32f429zi_death_stack_v2)
-
-add_executable(bmx160-calibration-v3 src/entrypoints/bmx160-calibration-entry.cpp)
-sbs_target(bmx160-calibration-v3 stm32f429zi_death_stack_v3)
-
-add_executable(config-dsgamma src/entrypoints/config-dsgamma.cpp)
-sbs_target(config-dsgamma stm32f429zi_stm32f4discovery)
-
-add_executable(imu-calibration src/entrypoints/imu-calibration.cpp)
-sbs_target(imu-calibration stm32f429zi_parafoil)
-
-add_executable(mxgui-helloworld src/entrypoints/examples/mxgui-helloworld.cpp)
-sbs_target(mxgui-helloworld stm32f429zi_stm32f4discovery)
-
-add_executable(compute-unit-v2-testsuite src/entrypoints/compute-unit-v2-testsuite.cpp)
-sbs_target(compute-unit-v2-testsuite stm32f767zi_compute_unit_v2_no_xram)
-
-# add_executable(kernel-testsuite src/entrypoints/kernel-testsuite.cpp)
-# sbs_target(kernel-testsuite stm32f767zi_compute_unit)
-
-add_executable(runcam-settings src/entrypoints/runcam-settings.cpp)
-sbs_target(runcam-settings stm32f407vg_stm32f4discovery)
-
-add_executable(sdcard-benchmark src/entrypoints/sdcard-benchmark.cpp)
-sbs_target(sdcard-benchmark stm32f429zi_death_stack_v2)
-
-add_executable(sx1278fsk-ra01-serial src/entrypoints/sx1278-serial.cpp)
-target_compile_definitions(sx1278fsk-ra01-serial PRIVATE SX1278_IS_FSK)
-sbs_target(sx1278fsk-ra01-serial stm32f429zi_nokia)
-
-add_executable(sx1278lora-ra01-serial src/entrypoints/sx1278-serial.cpp)
-target_compile_definitions(sx1278lora-ra01-serial PRIVATE SX1278_IS_LORA)
-sbs_target(sx1278lora-ra01-serial stm32f429zi_nokia)
-
-add_executable(sx1278fsk-skyward433-serial src/entrypoints/sx1278-serial.cpp)
-target_compile_definitions(sx1278fsk-skyward433-serial PRIVATE SX1278_IS_FSK SX1278_IS_SKYWARD433)
-sbs_target(sx1278fsk-skyward433-serial stm32f767zi_gemini_gs)
-
-add_executable(sx1278lora-skyward433-serial src/entrypoints/sx1278-serial.cpp)
-target_compile_definitions(sx1278lora-skyward433-serial PRIVATE SX1278_IS_LORA SX1278_IS_SKYWARD433)
-sbs_target(sx1278lora-skyward433-serial stm32f429zi_nokia)
-
-add_executable(sx1278fsk-ebyterig-serial src/entrypoints/sx1278-serial.cpp)
-target_compile_definitions(sx1278fsk-ebyterig-serial PRIVATE SX1278_IS_FSK)
-sbs_target(sx1278fsk-ebyterig-serial stm32f429zi_rig)
-
-#-----------------------------------------------------------------------------#
-#                                    Tests                                    #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-logger src/tests/logger/test-logger.cpp)
-sbs_target(test-logger stm32f429zi_stm32f4discovery)
-
-add_executable(test-eventinjector src/tests/test-eventinjector.cpp)
-sbs_target(test-eventinjector stm32f429zi_stm32f4discovery)
-
-add_executable(test-hsm src/tests/test-hsm.cpp)
-sbs_target(test-hsm stm32f429zi_stm32f4discovery)
-
-add_executable(test-interrupt src/tests/test-interrupt.cpp)
-sbs_target(test-interrupt stm32f429zi_stm32f4discovery)
-
-add_executable(test-max485 src/tests/test-max485.cpp)
-sbs_target(test-max485 stm32f407vg_stm32f4discovery)
-
-add_executable(test-pinobserver src/tests/test-pinobserver.cpp)
-sbs_target(test-pinobserver stm32f429zi_stm32f4discovery)
-
-add_executable(test-rtc src/tests/test-rtc.cpp)
-sbs_target(test-rtc stm32f767zi_compute_unit)
-
-add_executable(test-sensormanager src/tests/test-sensormanager.cpp)
-sbs_target(test-sensormanager stm32f429zi_death_stack_v2)
-
-add_executable(test-serial src/tests/test-serial.cpp)
-sbs_target(test-serial stm32f767zi_lyra_biscotto)
-
-add_executable(test-taskscheduler src/tests/scheduler/test-taskscheduler.cpp)
-sbs_target(test-taskscheduler stm32f407vg_stm32f4discovery)
-
-add_executable(test-trace-logger src/tests/test-trace-logger.cpp)
-sbs_target(test-trace-logger stm32f429zi_stm32f4discovery)
-
-add_executable(test-hil 
-    src/tests/hil/test-hil.cpp 
-    src/tests/hil/Sensors/Sensors.cpp 
-)
-sbs_target(test-hil stm32f767zi_death_stack_v4)
-
-#-----------------------------------------------------------------------------#
-#                                Tests - Catch                                #
-#-----------------------------------------------------------------------------#
-
-add_executable(catch-tests-boardcore
-    src/tests/catch/catch-tests-entry.cpp
-    src/tests/catch/skyQuaternion/test-skyquaternion.cpp
-    src/tests/catch/examples/example-test-factorial.cpp
-    src/tests/catch/test-aero.cpp
-    # src/tests/catch/test-buttonhandler.cpp
-    src/tests/catch/test-circularbuffer.cpp
-    src/tests/catch/test-eventbroker.cpp
-    src/tests/catch/test-gptimer.cpp
-    src/tests/catch/test-kalman.cpp
-    src/tests/catch/test-numeric.cpp
-    src/tests/catch/test-packetqueue.cpp
-    src/tests/catch/test-sensormanager-catch.cpp
-    src/tests/catch/xbee/test-xbee-parser.cpp
-    src/tests/catch/test-modulemanager.cpp
-    src/tests/catch/test-dependencymanager.cpp
-    src/tests/catch/test-MEA.cpp
-    src/tests/catch/test-airbrakesInterp.cpp
-    src/tests/catch/test-pitot.cpp
-    src/tests/catch/test-units.cpp
-    src/tests/catch/test-registry-frontend.cpp
-    src/tests/catch/propagator/test-propagator.cpp
-)
-target_compile_definitions(catch-tests-boardcore PRIVATE USE_MOCK_PERIPHERALS)
-sbs_target(catch-tests-boardcore stm32f429zi_stm32f4discovery)
-sbs_catch_test(catch-tests-boardcore)
-
-#-----------------------------------------------------------------------------#
-#                             Tests - Actuators                               #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-hbridge src/tests/actuators/test-hbridge.cpp)
-sbs_target(test-hbridge stm32f429zi_stm32f4discovery)
-
-add_executable(test-servo src/tests/actuators/test-servo.cpp)
-sbs_target(test-servo stm32f429zi_stm32f4discovery)
-
-# add_executable(test-buzzer src/tests/actuators/test-buzzer.cpp)
-# sbs_target(test-buzzer stm32f429zi_hre_test_stand)
-
-add_executable(test-stepper src/tests/actuators/test-stepper.cpp)
-sbs_target(test-stepper stm32f767zi_nucleo)
-
-add_executable(test-stepper-pwm src/tests/actuators/test-stepper-pwm.cpp)
-sbs_target(test-stepper-pwm stm32f767zi_nucleo)
-
-#-----------------------------------------------------------------------------#
-#                             Tests - Algorithms                              #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-kalman-benchmark src/tests/algorithms/Kalman/test-kalman-benchmark.cpp)
-sbs_target(test-kalman-benchmark stm32f429zi_stm32f4discovery)
-
-add_executable(test-attitude-parafoil src/tests/algorithms/NAS/test-attitude-parafoil.cpp)
-sbs_target(test-attitude-parafoil stm32f429zi_parafoil)
-
-add_executable(test-attitude-stack src/tests/algorithms/NAS/test-attitude-stack.cpp)
-sbs_target(test-attitude-stack stm32f429zi_death_stack_v2)
-
-add_executable(test-nas-parafoil src/tests/algorithms/NAS/test-nas-parafoil.cpp)
-sbs_target(test-nas-parafoil stm32f429zi_parafoil)
-
-add_executable(test-nas src/tests/algorithms/NAS/test-nas.cpp)
-sbs_target(test-nas stm32f429zi_death_stack_v3)
-
-add_executable(test-nas-with-triad src/tests/algorithms/NAS/test-nas-with-triad.cpp)
-sbs_target(test-nas-with-triad stm32f429zi_death_stack_v2)
-
-add_executable(test-triad src/tests/algorithms/NAS/test-triad.cpp)
-sbs_target(test-triad stm32f429zi_death_stack_v3)
-
-add_executable(test-triad-parafoil src/tests/algorithms/NAS/test-triad-parafoil.cpp)
-sbs_target(test-triad-parafoil stm32f429zi_parafoil)
-
-add_executable(test-ada src/tests/algorithms/ADA/test-ada.cpp)
-sbs_target(test-ada stm32f429zi_death_stack_v3)
-
-#-----------------------------------------------------------------------------#
-#                               Tests - Boards                                #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-compute-unit src/tests/boards/test-compute-unit.cpp)
-sbs_target(test-compute-unit stm32f767zi_compute_unit)
-
-add_executable(test-qspi-flash src/tests/boards/test-qspi-flash.cpp)
-sbs_target(test-qspi-flash stm32f767zi_compute_unit)
-
-#-----------------------------------------------------------------------------#
-#                               Tests - Drivers                               #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-ad5204 src/tests/drivers/test-ad5204.cpp)
-sbs_target(test-ad5204 stm32f205rc_ciuti)
-
-add_executable(test-can-2way src/tests/drivers/canbus/CanDriver/test-can-2way.cpp)
-sbs_target(test-can-2way stm32f429zi_pyxis_auxiliary)
-
-add_executable(test-can-filters src/tests/drivers/canbus/CanDriver/test-can-filters.cpp)
-sbs_target(test-can-filters stm32f429zi_pyxis_auxiliary)
-
-add_executable(test-can-loopback src/tests/drivers/canbus/CanDriver/test-can-loopback.cpp)
-sbs_target(test-can-loopback stm32f429zi_death_stack_v2)
-
-add_executable(test-can-protocol src/tests/drivers/canbus/CanProtocol/test-can-protocol.cpp)
-sbs_target(test-can-protocol stm32f429zi_death_stack_v2)
-
-add_executable(test-dsgamma src/tests/drivers/test-dsgamma.cpp)
-sbs_target(test-dsgamma stm32f429zi_stm32f4discovery)
-
-add_executable(test-general-purpose-timer src/tests/drivers/timer/test-general-purpose-timer.cpp)
-sbs_target(test-general-purpose-timer stm32f429zi_stm32f4discovery)
-
-add_executable(test-internal-adc src/tests/drivers/test-internal-adc.cpp)
-sbs_target(test-internal-adc stm32f767zi_compute_unit)
+# 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
+# Public License. This exception does not invalidate any other
+# 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/>
 
-add_executable(test-mavlink src/tests/drivers/test-mavlink.cpp)
-sbs_target(test-mavlink stm32f407vg_stm32f4discovery)
+cmake_minimum_required(VERSION 3.16)
 
-add_executable(test-MBLoadCell src/tests/drivers/test-MBLoadCell.cpp)
-sbs_target(test-MBLoadCell stm32f407vg_stm32f4discovery)
+project(SkywardBoardcore)
 
-add_executable(test-pwm src/tests/drivers/timer/test-pwm.cpp)
-sbs_target(test-pwm stm32f429zi_stm32f4discovery)
+set(BOARDCORE_PATH ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Path to the skyward-boardcore root")
 
-add_executable(test-counted-pwm src/tests/drivers/timer/test-counted-pwm.cpp)
-sbs_target(test-counted-pwm stm32f429zi_stm32f4discovery)
+# Includes all board/arch specific defines, dependencies, source files and boardcore_link_target function
+include(${BOARDCORE_PATH}/cmake/boardcore.cmake)
 
-add_executable(test-spi src/tests/drivers/spi/test-spi.cpp)
-sbs_target(test-spi stm32f407vg_stm32f4discovery)
+# Define the miosix library with kernel and architecture sources
+add_library(skyward-boardcore STATIC ${BOARDCORE_SRC})
 
-add_executable(test-timer-utils src/tests/drivers/timer/test-timer-utils.cpp)
-sbs_target(test-timer-utils stm32f429zi_stm32f4discovery)
+# Only one include directory for Boardcore!
+target_include_directories(skyward-boardcore PUBLIC ${BOARDCORE_PATH}/src/shared)
 
-add_executable(test-timestamptimer src/tests/drivers/timer/test-timestamptimer.cpp)
-sbs_target(test-timestamptimer stm32f429zi_stm32f4discovery)
+# Define DEBUG when in Debug mode
+target_compile_definitions(skyward-boardcore PUBLIC $<$<CONFIG:Debug>:DEBUG>)
+# Define NDEBUG when not in Debug mode
+target_compile_definitions(skyward-boardcore PUBLIC $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
 
-add_executable(test-xbee-bidir src/tests/drivers/xbee/test-xbee-bidir.cpp)
-sbs_target(test-xbee-bidir stm32f429zi_death_stack_v2)
+# Link libraries
+include(${MIOSIX_KPATH}/cmake/LinkTarget.cmake)
+miosix_link_target(skyward-boardcore)
 
-add_executable(test-xbee-gui
-    src/tests/drivers/xbee/test-xbee-gui.cpp
-    src/tests/drivers/xbee/gui/res/respect.cpp
+target_link_libraries(skyward-boardcore PUBLIC
+    TSCPP::TSCPP
+    Eigen3::Eigen
+    fmt::fmt-header-only
+    Catch2::Catch2
+    Mavlink::Mavlink
 )
-sbs_target(test-xbee-gui stm32f429zi_stm32f4discovery)
-
-add_executable(test-xbee-rcv src/tests/drivers/xbee/test-xbee-rcv.cpp)
-sbs_target(test-xbee-rcv stm32f429zi_stm32f4discovery)
-
-add_executable(test-xbee-snd src/tests/drivers/xbee/test-xbee-snd.cpp)
-sbs_target(test-xbee-snd stm32f429zi_stm32f4discovery)
-
-add_executable(test-usart-f4 src/tests/drivers/usart/test-usart.cpp)
-sbs_target(test-usart-f4 stm32f429zi_stm32f4discovery)
-
-add_executable(test-usart-f7 src/tests/drivers/usart/test-usart.cpp)
-sbs_target(test-usart-f7 stm32f767zi_nucleo)
-
-add_executable(test-i2c-driver-f4 src/tests/drivers/i2c/test-i2c-driver.cpp)
-sbs_target(test-i2c-driver-f4 stm32f429zi_stm32f4discovery)
-
-add_executable(test-i2c-f4 src/tests/drivers/i2c/test-i2c.cpp)
-sbs_target(test-i2c-f4 stm32f429zi_stm32f4discovery)
-
-add_executable(test-i2c-driver-f7 src/tests/drivers/i2c/test-i2c-driver.cpp)
-sbs_target(test-i2c-driver-f7 stm32f767zi_nucleo)
-
-add_executable(test-i2c-f7 src/tests/drivers/i2c/test-i2c.cpp)
-sbs_target(test-i2c-f7 stm32f767zi_nucleo)
-
-add_executable(test-wiz5500 src/tests/drivers/test-wiz5500.cpp)
-sbs_target(test-wiz5500 stm32f767zi_gemini_gs)
-
-add_executable(test-bsram src/tests/drivers/test-bsram.cpp)
-sbs_target(test-bsram stm32f767zi_lyra_biscotto)
-
-add_executable(test-dipswitch src/tests/drivers/test-dipswitch.cpp)
-sbs_target(test-dipswitch stm32f767zi_lyra_gs)
-
-#-----------------------------------------------------------------------------#
-#                               Tests - Events                                #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-fsm src/tests/events/fsm/test-fsm.cpp)
-sbs_target(test-fsm stm32f429zi_stm32f4discovery)
-
-#-----------------------------------------------------------------------------#
-#                               Tests - Radio                                 #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-sx1278fsk-bidir src/tests/radio/sx1278/fsk/test-sx1278-bidir.cpp)
-sbs_target(test-sx1278fsk-bidir stm32f429zi_nokia)
-
-add_executable(test-sx1278fsk-tx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp)
-target_compile_definitions(test-sx1278fsk-tx PRIVATE DISABLE_RX)
-sbs_target(test-sx1278fsk-tx stm32f429zi_nokia)
-
-add_executable(test-sx1278fsk-rx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp)
-target_compile_definitions(test-sx1278fsk-rx PRIVATE DISABLE_TX)
-sbs_target(test-sx1278fsk-rx stm32f429zi_nokia)
-
-add_executable(test-sx1278fsk-gui-tx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp)
-target_compile_definitions(test-sx1278fsk-gui-tx PRIVATE DISABLE_RX)
-sbs_target(test-sx1278fsk-gui-tx stm32f429zi_nokia)
-
-add_executable(test-sx1278fsk-gui-rx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp)
-target_compile_definitions(test-sx1278fsk-gui-rx PRIVATE DISABLE_TX)
-sbs_target(test-sx1278fsk-gui-rx stm32f429zi_nokia)
-
-add_executable(test-sx1278fsk-mavlink src/tests/radio/sx1278/fsk/test-sx1278-mavlink.cpp)
-sbs_target(test-sx1278fsk-mavlink stm32f429zi_nokia)
-
-# add_executable(test-mavlinkdriver src/tests/radio/test-mavlinkdriver.cpp)
-# sbs_target(test-mavlinkdriver stm32f407vg_stm32f4discovery)
-
-add_executable(test-sx1278lora-bidir src/tests/radio/sx1278/lora/test-sx1278-bidir.cpp)
-sbs_target(test-sx1278lora-bidir stm32f429zi_nokia)
-
-add_executable(test-sx1278lora-mavlink src/tests/radio/sx1278/lora/test-sx1278-mavlink.cpp)
-sbs_target(test-sx1278lora-mavlink stm32f429zi_nokia)
-
-add_executable(test-sx1278lora-simple-rx src/tests/radio/sx1278/lora/test-sx1278-simple.cpp)
-target_compile_definitions(test-sx1278lora-simple-rx PRIVATE ENABLE_RX)
-sbs_target(test-sx1278lora-simple-rx stm32f429zi_nokia)
-
-add_executable(test-sx1278lora-simple-tx src/tests/radio/sx1278/lora/test-sx1278-simple.cpp)
-target_compile_definitions(test-sx1278lora-simple-tx PRIVATE ENABLE_TX)
-sbs_target(test-sx1278lora-simple-tx stm32f429zi_nokia)
-
-add_executable(test-sx1278lora-tx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp)
-target_compile_definitions(test-sx1278lora-tx PRIVATE DISABLE_RX SX1278_IS_LORA)
-sbs_target(test-sx1278lora-tx stm32f429zi_nokia)
-
-add_executable(test-sx1278lora-rx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp)
-target_compile_definitions(test-sx1278lora-rx PRIVATE DISABLE_TX SX1278_IS_LORA)
-sbs_target(test-sx1278lora-rx stm32f429zi_nokia)
-
-add_executable(test-sx1278lora-gui-rx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp)
-target_compile_definitions(test-sx1278lora-gui-rx PRIVATE DISABLE_TX SX1278_IS_LORA)
-sbs_target(test-sx1278lora-gui-rx stm32f429zi_nokia)
-
-add_executable(test-sx1278lora-gui-tx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp)
-target_compile_definitions(test-sx1278lora-gui-tx PRIVATE DISABLE_RX SX1278_IS_LORA)
-sbs_target(test-sx1278lora-gui-tx stm32f429zi_nokia)
-
-#-----------------------------------------------------------------------------#
-#                               Tests - Sensors                               #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-ads1118 src/tests/sensors/test-ads1118.cpp)
-sbs_target(test-ads1118 stm32f407vg_stm32f4discovery)
-
-add_executable(test-ads131m04 src/tests/sensors/test-ads131m04.cpp)
-sbs_target(test-ads131m04 stm32f429zi_death_stack_v3)
-
-add_executable(test-ads131m08 src/tests/sensors/test-ads131m08.cpp)
-sbs_target(test-ads131m08 stm32f767zi_compute_unit)
-
-add_executable(test-analog-pressure-sensors src/tests/sensors/analog/test-analog-pressure-sensors.cpp)
-sbs_target(test-analog-pressure-sensors stm32f429zi_stm32f4discovery)
-
-add_executable(test-battery-voltage src/tests/sensors/analog/test-battery-voltage.cpp)
-sbs_target(test-battery-voltage stm32f429zi_stm32f4discovery)
-
-add_executable(test-current-sensor src/tests/sensors/analog/test-current-sensor.cpp)
-sbs_target(test-current-sensor stm32f429zi_stm32f4discovery)
-
-add_executable(test-calibration-benchmark src/tests/sensors/calibration/test-calibration-benchmark.cpp)
-sbs_target(test-calibration-benchmark stm32f407vg_stm32f4discovery)
-
-add_executable(test-calibration-stats src/tests/sensors/calibration/test-calibration-stats.cpp)
-sbs_target(test-calibration-stats stm32f407vg_stm32f4discovery)
-
-add_executable(test-bme280-spi src/tests/sensors/test-bme280-spi.cpp)
-sbs_target(test-bme280-spi stm32f429zi_stm32f4discovery)
-
-add_executable(test-bme280-i2c src/tests/sensors/test-bme280-i2c.cpp)
-sbs_target(test-bme280-i2c stm32f429zi_stm32f4discovery)
-
-add_executable(test-bmp280-spi src/tests/sensors/test-bmp280-spi.cpp)
-sbs_target(test-bmp280-spi stm32f429zi_stm32f4discovery)
-
-add_executable(test-bmp280-i2c src/tests/sensors/test-bmp280-i2c.cpp)
-sbs_target(test-bmp280-i2c stm32f429zi_stm32f4discovery)
-
-add_executable(test-bmx160 src/tests/sensors/test-bmx160.cpp)
-sbs_target(test-bmx160 stm32f429zi_death_stack_v2)
-
-add_executable(test-bmx160-with-correction src/tests/sensors/test-bmx160-with-correction.cpp)
-sbs_target(test-bmx160-with-correction stm32f429zi_death_stack_v2)
-
-add_executable(test-hx711 src/tests/sensors/test-hx711.cpp)
-sbs_target(test-hx711 stm32f429zi_stm32f4discovery)
-
-add_executable(test-l3gd20 src/tests/sensors/test-l3gd20.cpp)
-sbs_target(test-l3gd20 stm32f429zi_stm32f4discovery)
-
-add_executable(test-l3gd20-fifo src/tests/sensors/test-l3gd20-fifo.cpp)
-sbs_target(test-l3gd20-fifo stm32f429zi_stm32f4discovery)
-
-add_executable(test-lis3dsh src/tests/sensors/test-lis3dsh.cpp)
-sbs_target(test-lis3dsh stm32f407vg_stm32f4discovery)
-
-add_executable(test-lis3mdl src/tests/sensors/test-lis3mdl.cpp)
-sbs_target(test-lis3mdl stm32f429zi_death_stack_v2)
-
-add_executable(test-lis331hh src/tests/sensors/test-lis331hh.cpp)
-sbs_target(test-lis331hh stm32f205rc_ciuti)
-
-add_executable(test-lps331ap src/tests/sensors/test-lps331ap.cpp)
-sbs_target(test-lps331ap stm32f429zi_stm32f4discovery)
-
-add_executable(test-max6675 src/tests/sensors/test-max6675.cpp)
-sbs_target(test-max6675 stm32f429zi_stm32f4discovery)
-
-add_executable(test-max31855 src/tests/sensors/test-max31855.cpp)
-sbs_target(test-max31855 stm32f429zi_stm32f4discovery)
-
-add_executable(test-max31856 src/tests/sensors/test-max31856.cpp)
-sbs_target(test-max31856 stm32f767zi_compute_unit)
-
-add_executable(test-mpu9250 src/tests/sensors/test-mpu9250.cpp)
-sbs_target(test-mpu9250 stm32f429zi_parafoil)
-
-add_executable(test-ms5803-spi src/tests/sensors/test-ms5803-spi.cpp)
-sbs_target(test-ms5803-spi stm32f429zi_death_stack_v2)
-
-add_executable(test-ms5803-i2c src/tests/sensors/test-ms5803-i2c.cpp)
-sbs_target(test-ms5803-i2c stm32f429zi_stm32f4discovery)
-
-add_executable(test-ubxgps-serial src/tests/sensors/test-ubxgps-serial.cpp)
-sbs_target(test-ubxgps-serial stm32f429zi_death_stack_v2)
-
-add_executable(test-ubxgps-spi src/tests/sensors/test-ubxgps-spi.cpp)
-sbs_target(test-ubxgps-spi stm32f429zi_death_stack_v2)
-
-add_executable(test-vn100-serial src/tests/sensors/test-vn100-serial.cpp)
-sbs_target(test-vn100-serial stm32f407vg_stm32f4discovery)
-
-add_executable(test-vn100-spi src/tests/sensors/test-vn100-spi.cpp)
-sbs_target(test-vn100-spi stm32f407vg_stm32f4discovery)
-
-add_executable(test-vn300 src/tests/sensors/test-vn300.cpp)
-sbs_target(test-vn300 stm32f767zi_compute_unit)
-
-
-add_executable(test-lis2mdl src/tests/sensors/test-lis2mdl.cpp)
-sbs_target(test-lis2mdl stm32f429zi_stm32f4discovery)
-
-add_executable(test-h3lis331dl src/tests/sensors/test-h3lis331dl.cpp)
-sbs_target(test-h3lis331dl stm32f407vg_stm32f4discovery)
-
-add_executable(test-lps28dfw src/tests/sensors/test-lps28dfw.cpp)
-sbs_target(test-lps28dfw stm32f767zi_nucleo)
-
-add_executable(test-lps22df src/tests/sensors/test-lps22df.cpp)
-sbs_target(test-lps22df stm32f767zi_nucleo)
-
-add_executable(test-lsm6dsrx src/tests/sensors/test-lsm6dsrx.cpp)
-sbs_target(test-lsm6dsrx stm32f407vg_stm32f4discovery)
-
-#-----------------------------------------------------------------------------#
-#                                Tests - Utils                                #
-#-----------------------------------------------------------------------------#
-
-add_executable(test-csvreader src/tests/utils/test-csvreader.cpp)
-sbs_target(test-csvreader stm32f429zi_stm32f4discovery)
-
-add_executable(test-buttonhandler src/tests/utils/test-buttonhandler.cpp)
-sbs_target(test-buttonhandler stm32f429zi_stm32f4discovery)
 
-add_executable(test-syncpacketqueue src/tests/utils/test-syncpacketqueue.cpp)
-sbs_target(test-syncpacketqueue stm32f407vg_stm32f4discovery)
+# Link MxGui if supported by the target
+if(DEFINED MXGUI_BASE_BOARD_NAME)
+    target_link_libraries(skyward-boardcore PUBLIC MxGui::${MXGUI_BASE_BOARD_NAME})
+elseif(TARGET MxGui::${BOARD_NAME})
+    target_link_libraries(skyward-boardcore PUBLIC MxGui::${BOARD_NAME})
+endif()
diff --git a/cmake/boardcore-host.cmake b/cmake/boardcore-host.cmake
index ece5ac859c0c527711aed7fab0e355af70f5c311..47825eeb34ac9d3b51e4e4657b052174c9d7ae9f 100644
--- a/cmake/boardcore-host.cmake
+++ b/cmake/boardcore-host.cmake
@@ -22,43 +22,43 @@
 # Boardcore source files used when compiling for host
 set(BOARDCORE_HOST_SRC
     # Debug
-    ${SBS_BASE}/src/shared/utils/Debug.cpp
-    ${SBS_BASE}/src/shared/diagnostic/CpuMeter/CpuMeter.cpp
-    ${SBS_BASE}/src/shared/diagnostic/PrintLogger.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/Debug.cpp
+    ${BOARDCORE_PATH}/src/shared/diagnostic/CpuMeter/CpuMeter.cpp
+    ${BOARDCORE_PATH}/src/shared/diagnostic/PrintLogger.cpp
 
     # Actuators
-    ${SBS_BASE}/src/shared/actuators/Servo/Servo.cpp
+    ${BOARDCORE_PATH}/src/shared/actuators/Servo/Servo.cpp
 
     # Events
-    ${SBS_BASE}/src/shared/events/EventBroker.cpp
+    ${BOARDCORE_PATH}/src/shared/events/EventBroker.cpp
 
     # Algorithms
-    ${SBS_BASE}/src/shared/algorithms/MEA/MEA.cpp
-    ${SBS_BASE}/src/shared/algorithms/AirBrakes/AirBrakesPI.cpp
-    ${SBS_BASE}/src/shared/algorithms/AirBrakes/AirBrakesInterp.cpp
-    ${SBS_BASE}/src/shared/algorithms/Propagator/Propagator.cpp
+    ${BOARDCORE_PATH}/src/shared/algorithms/MEA/MEA.cpp
+    ${BOARDCORE_PATH}/src/shared/algorithms/AirBrakes/AirBrakesPI.cpp
+    ${BOARDCORE_PATH}/src/shared/algorithms/AirBrakes/AirBrakesInterp.cpp
+    ${BOARDCORE_PATH}/src/shared/algorithms/Propagator/Propagator.cpp
 
     # Logger
-    ${SBS_BASE}/src/shared/logger/Logger.cpp
+    ${BOARDCORE_PATH}/src/shared/logger/Logger.cpp
 
     # Radio
-    ${SBS_BASE}/src/shared/radio/Xbee/APIFrameParser.cpp
+    ${BOARDCORE_PATH}/src/shared/radio/Xbee/APIFrameParser.cpp
 
     # Scheduler
-    ${SBS_BASE}/src/shared/scheduler/TaskScheduler.cpp
+    ${BOARDCORE_PATH}/src/shared/scheduler/TaskScheduler.cpp
 
     # Sensors
-    ${SBS_BASE}/src/shared/sensors/SensorManager.cpp
-    ${SBS_BASE}/src/shared/sensors/SensorSampler.cpp
+    ${BOARDCORE_PATH}/src/shared/sensors/SensorManager.cpp
+    ${BOARDCORE_PATH}/src/shared/sensors/SensorSampler.cpp
 
     # Utils
-    ${SBS_BASE}/src/shared/utils/AeroUtils/AeroUtils.cpp
-    ${SBS_BASE}/src/shared/utils/SkyQuaternion/SkyQuaternion.cpp
-    ${SBS_BASE}/src/shared/utils/Stats/Stats.cpp
-    ${SBS_BASE}/src/shared/utils/TestUtils/TestHelper.cpp
-    ${SBS_BASE}/src/shared/utils/Registry/RegistryFrontend.cpp
-    ${SBS_BASE}/src/shared/utils/Registry/RegistrySerializer.cpp
-    ${SBS_BASE}/src/shared/utils/DependencyManager/DependencyManager.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/AeroUtils/AeroUtils.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/SkyQuaternion/SkyQuaternion.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/Stats/Stats.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/TestUtils/TestHelper.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/Registry/RegistryFrontend.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/Registry/RegistrySerializer.cpp
+    ${BOARDCORE_PATH}/src/shared/utils/DependencyManager/DependencyManager.cpp
 )
 
 # Create a library specific for host builds
diff --git a/cmake/boardcore.cmake b/cmake/boardcore.cmake
index 2d773978aa5dbfcdb7770a23a6ab0360cc89e521..f37825291985479e8bf0e12257c7d88e819aebb0 100644
--- a/cmake/boardcore.cmake
+++ b/cmake/boardcore.cmake
@@ -22,6 +22,15 @@
 # Load in BOARDCORE_PATH the project path
 cmake_path(GET CMAKE_CURRENT_LIST_DIR PARENT_PATH BOARDCORE_PATH)
 
+# TODO: include the miosix_opt_board_list and boardcore_opt_board_list and dispatch automatically in base of this
+
+# Include all the architecture and board specific defines
+if(DEFINED BOARDCORE_OPT_BOARD)
+    include(${BOARDCORE_PATH}/src/bsps/CMakeLists.txt)
+#elseif(${MIOSIX_OPT_BOARD})
+#    include(${BOARDCORE_PATH}/libs/miosix-kernel/miosix/arch/CMakeLists.txt)
+endif()
+
 # Include dependencies and board list
 include(${BOARDCORE_PATH}/cmake/dependencies.cmake)
 include(${BOARDCORE_PATH}/cmake/boardcore-host.cmake)
@@ -42,8 +51,8 @@ set(BOARDCORE_SRC
     ${BOARDCORE_PATH}/src/shared/algorithms/AirBrakes/AirBrakesInterp.cpp
     ${BOARDCORE_PATH}/src/shared/algorithms/NAS/NAS.cpp
     ${BOARDCORE_PATH}/src/shared/algorithms/NAS/StateInitializer.cpp
-    ${SBS_BASE}/src/shared/algorithms/Propagator/Propagator.cpp
-    ${SBS_BASE}/src/shared/algorithms/Follower/Follower.cpp
+    ${BOARDCORE_PATH}/src/shared/algorithms/Propagator/Propagator.cpp
+    ${BOARDCORE_PATH}/src/shared/algorithms/Follower/Follower.cpp
 
     # Debug
     ${BOARDCORE_PATH}/src/shared/utils/Debug.cpp
@@ -144,51 +153,42 @@ set(BOARDCORE_SRC
     ${BOARDCORE_PATH}/src/shared/utils/DependencyManager/DependencyManager.cpp
 )
 
-# Creates the Skyward::Boardcore::${BOARD_NAME} library
-function(add_boardcore_library BOARD_OPTIONS_FILE)
-    # Get board options
-    include(${BOARD_OPTIONS_FILE})
-
-    # Create a library for the board
-    set(BOARDCORE_LIB boardcore-${BOARD_NAME})
-    add_library(${BOARDCORE_LIB} STATIC EXCLUDE_FROM_ALL ${BOARDCORE_SRC})
-
-    # Only one include directory for Boardcore!
-    target_include_directories(${BOARDCORE_LIB} PUBLIC ${BOARDCORE_PATH}/src/shared)
-
-    # Define DEBUG when in Debug mode
-    target_compile_definitions(${BOARDCORE_LIB} PUBLIC $<$<CONFIG:Debug>:DEBUG>)
-    # Define NDEBUG when not in Debug mode
-    target_compile_definitions(${BOARDCORE_LIB} PUBLIC $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
-
-    # Link libraries
-    target_link_libraries(${BOARDCORE_LIB} PUBLIC
-        $<TARGET_OBJECTS:Miosix::Boot::${BOARD_NAME}>
-        $<LINK_GROUP:RESCAN,Miosix::Kernel::${BOARD_NAME},stdc++,c,m,gcc,atomic>
-        TSCPP::TSCPP
-        Eigen3::Eigen
-        fmt::fmt-header-only
-        Catch2::Catch2
-        Mavlink::Mavlink
+# Function to link the Miosix libraries to a target and register the build command
+#
+#   boardcore_link_target(<target>)
+#
+# What it does:
+# - Links the Miosix libraries to the target
+# - Tells the linker to generate the map file
+# - Registers custom targets to create the hex and bin files (${TARGET}_bin and ${TARGET}_hex)
+# - Registers a custom target to flash the program to the board (${TARGET}_program)
+function(boardcore_link_target TARGET)
+
+    # Linker script and linking options are eredited from miosix libraries
+    
+    # Linking skyward-boardcore library
+    target_link_libraries(${TARGET} PUBLIC skyward-boardcore)
+
+    # Tell the linker to produce the map file
+    target_link_options(${TARGET} PRIVATE -Wl,-Map,$<TARGET_FILE_DIR:${TARGET}>/$<TARGET_FILE_BASE_NAME:${TARGET}>.map)
+
+    # Add a post build command to create the hex file to flash on the board
+    add_custom_command(
+        OUTPUT ${TARGET}.hex
+        COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${TARGET}> ${TARGET}.hex
+        COMMENT "Creating ${TARGET}.hex"
+        VERBATIM
     )
+    add_custom_target(${TARGET}_hex ALL DEPENDS ${TARGET}.hex)
+    add_custom_command(
+        OUTPUT ${TARGET}.bin
+        COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${TARGET}> ${TARGET}.bin
+        COMMENT "Creating ${TARGET}.bin"
+        VERBATIM
+    )
+    add_custom_target(${TARGET}_bin ALL DEPENDS ${TARGET}.bin)
 
-    # Link MxGui if supported by the target
-    if(DEFINED MXGUI_BASE_BOARD_NAME)
-        target_link_libraries(${BOARDCORE_LIB} PUBLIC MxGui::${MXGUI_BASE_BOARD_NAME})
-    elseif(TARGET MxGui::${BOARD_NAME})
-        target_link_libraries(${BOARDCORE_LIB} PUBLIC MxGui::${BOARD_NAME})
-    endif()
-
-    # Create a nice alias for the library
-    add_library(Skyward::Boardcore::${BOARD_NAME} ALIAS ${BOARDCORE_LIB})
+    # Generate custom build command to flash the target
+    miosix_add_program_target(${TARGET})
 endfunction()
 
-# Create the Miosix libraries for Boardcore custom boards
-foreach(BOARD_OPTIONS_FILE ${BOARDCORE_BOARDS_OPTIONS_FILES})
-    add_miosix_libraries(${BOARD_OPTIONS_FILE})
-endforeach()
-
-# Create Boardcore library for each board
-foreach(BOARD_OPTIONS_FILE ${MIOSIX_BOARDS_OPTIONS_FILES} ${BOARDCORE_BOARDS_OPTIONS_FILES})
-    add_boardcore_library(${BOARD_OPTIONS_FILE})
-endforeach()
diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake
index f0a5db0585af4e5db1b53c972b0b69b8b0050896..317289e2c84855e76a43d3fbbdc1369f6048e96f 100644
--- a/cmake/dependencies.cmake
+++ b/cmake/dependencies.cmake
@@ -20,33 +20,33 @@
 # THE SOFTWARE.
 
 # Miosix Kernel
-include(${SBS_BASE}/libs/miosix-kernel/miosix/cmake/miosix.cmake EXCLUDE_FROM_ALL)
+include(${BOARDCORE_PATH}/libs/miosix-kernel/miosix/CMakeLists.txt)
 
 # Miosix Host
-add_subdirectory(${SBS_BASE}/libs/miosix-host EXCLUDE_FROM_ALL)
+add_subdirectory(${BOARDCORE_PATH}/libs/miosix-host miosix-host EXCLUDE_FROM_ALL)
 
 # MxGui graphical library
-include(${SBS_BASE}/libs/mxgui/cmake/mxgui.cmake)
+include(${BOARDCORE_PATH}/libs/mxgui/cmake/mxgui.cmake)
 
 # Serialization library
-add_subdirectory(${SBS_BASE}/libs/tscpp EXCLUDE_FROM_ALL)
+add_subdirectory(${BOARDCORE_PATH}/libs/tscpp tscpp EXCLUDE_FROM_ALL)
 
 # Eigen library
 set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
 set(EIGEN_TEST_NOQT ON CACHE BOOL "Disable Qt support in unit tests")
 set(CMAKE_Fortran_COMPILER NOTFOUND)
-add_subdirectory(${SBS_BASE}/libs/eigen EXCLUDE_FROM_ALL)
+add_subdirectory(${BOARDCORE_PATH}/libs/eigen eigen EXCLUDE_FROM_ALL)
 target_compile_definitions(eigen INTERFACE EIGEN_MAX_ALIGN_BYTES=0)
 
 # Format library
-add_subdirectory(${SBS_BASE}/libs/fmt EXCLUDE_FROM_ALL)
+add_subdirectory(${BOARDCORE_PATH}/libs/fmt fmt EXCLUDE_FROM_ALL)
 target_compile_definitions(fmt-header-only INTERFACE _GLIBCXX_USE_WCHAR_T FMT_UNICODE=0 FMT_STATIC_THOUSANDS_SEPARATOR=0)
 target_compile_options(fmt-header-only INTERFACE -fno-math-errno)
 
 # Catch2 library
-add_subdirectory(${SBS_BASE}/libs/Catch2 EXCLUDE_FROM_ALL)
-list(APPEND CMAKE_MODULE_PATH ${SBS_BASE}/libs/Catch2/contrib)
+add_subdirectory(${BOARDCORE_PATH}/libs/Catch2 Catch2 EXCLUDE_FROM_ALL)
+list(APPEND CMAKE_MODULE_PATH ${BOARDCORE_PATH}/libs/Catch2/contrib)
 include(Catch)
 
 # MavLink library
-add_subdirectory(${SBS_BASE}/libs/mavlink-skyward-lib EXCLUDE_FROM_ALL)
+add_subdirectory(${BOARDCORE_PATH}/libs/mavlink-skyward-lib mavlink-skyward-lib EXCLUDE_FROM_ALL)
diff --git a/libs/miosix-kernel b/libs/miosix-kernel
index 90cbe7d35aafae2baf29623d54de8a68185bc978..568bfabf6134582f75e39b2fd541e9cbd6079fd1 160000
--- a/libs/miosix-kernel
+++ b/libs/miosix-kernel
@@ -1 +1 @@
-Subproject commit 90cbe7d35aafae2baf29623d54de8a68185bc978
+Subproject commit 568bfabf6134582f75e39b2fd541e9cbd6079fd1
diff --git a/src/bsps/CMakeLists.txt b/src/bsps/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c91f328f42181b40da0c6053795863e3e9f6c994
--- /dev/null
+++ b/src/bsps/CMakeLists.txt
@@ -0,0 +1,89 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# 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
+# Public License. This exception does not invalidate any other
+# 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/>
+
+# Load in BSPS_PATH and MIOSIX_KPATH the relative project paths
+set(MIOSIX_KPATH ${BOARDCORE_PATH}/libs/miosix-kernel/miosix)
+set(BSPS_PATH ${BOARDCORE_PATH}/src/bsps)
+
+set(BOARDCORE_BOARDS
+    stm32f767zi_lyra_biscotto
+    stm32f767zi_compute_unit
+    stm32f767zi_compute_unit_v2
+)
+
+# Target board option, this also implicitly select the target architecture
+set(BOARDCORE_OPT_BOARD NOT_SET CACHE STRING "Target board")
+set_property(CACHE BOARDCORE_OPT_BOARD PROPERTY STRINGS ${BOARDCORE_BOARDS})
+if(BOARDCORE_OPT_BOARD STREQUAL NOT_SET)
+    message(FATAL_ERROR "You must specify a target board with BOARDCORE_OPT_BOARD")
+elseif(NOT BOARDCORE_OPT_BOARD IN_LIST BOARDCORE_BOARDS)
+    message(FATAL_ERROR "Selected board ${BOARDCORE_OPT_BOARD} is not in the BOARDCORE_BOARDS list")
+    message(BOARDCORE_BOARDS)
+endif()
+
+# Optimization flags are set with CMAKE_<LANG>_FLAGS_<CONFIG>
+# The default values are in the toolchain file
+
+# C++ Exception/rtti support disable flags.
+# To save code size if not using C++ exceptions (nor some STL code which
+# implicitly uses it) uncomment this option.
+# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used.
+option(MIOSIX_DISABLE_EXEPTIONS "Disables C++ exceptions/rtti support" OFF)
+if(MIOSIX_DISABLE_EXEPTIONS)
+    set(MIOSIX_OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS)
+endif()
+
+# Auto guess architecture name from board name
+if(
+    BOARDCORE_OPT_BOARD STREQUAL stm32f767zi_lyra_biscotto OR
+    BOARDCORE_OPT_BOARD STREQUAL stm32f767zi_compute_unit OR
+    BOARDCORE_OPT_BOARD STREQUAL stm32f767zi_compute_unit_v2
+)
+    set(MIOSIX_ARCH_NAME cortexM7_stm32f7)
+# elseif(
+#     BOARDCORE_OPT_BOARD STREQUAL stm32f429zi_con_rig
+# )
+#     set(MIOSIX_ARCH_NAME cortexM4_stm32f4)
+else()
+    message(FATAL_ERROR "Unknown architecture for board ${BOARDCORE_OPT_BOARD}")
+endif()
+
+# Then, initialize C/C++ flags
+set(MIOSIX_C_FLAGS
+    -D_MIOSIX_BOARDNAME="${BOARDCORE_OPT_BOARD}" -D_DEFAULT_SOURCE=1
+    -ffunction-sections -Wall -Werror=return-type -g
+)
+set(MIOSIX_CXX_FLAGS
+    -D_MIOSIX_BOARDNAME="${BOARDCORE_OPT_BOARD}" -D_DEFAULT_SOURCE=1
+    -std=c++14 -ffunction-sections -Wall -Werror=return-type -g
+)
+
+# Include dependencies and board list
+include(${BSPS_PATH}/${BOARDCORE_OPT_BOARD}/CMakeLists.txt)
+
+# Now include the architecture specific CMakeLists that will:
+# - Sets common things for all boards of that specific architecture
+# - Includes the board specific CMakeLists file
+include(${MIOSIX_KPATH}/arch/${MIOSIX_ARCH_NAME}/CMakeLists.txt)
diff --git a/src/bsps/stm32f767zi_compute_unit/CMakeLists.txt b/src/bsps/stm32f767zi_compute_unit/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c453c7a160042b48fa0767574a64452a3f707fb9
--- /dev/null
+++ b/src/bsps/stm32f767zi_compute_unit/CMakeLists.txt
@@ -0,0 +1,104 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# 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
+# Public License. This exception does not invalidate any other
+# 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/>
+
+# The stm32f767 has the double precision FPU, so we will build for m7
+set(MIOSIX_CPU_FLAGS -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16)
+
+# Directory with header files for this board
+set(MIOSIX_BOARD_INC ${BSPS_PATH}/${BOARDCORE_OPT_BOARD})
+
+# The user can set a custom path for board_settings.h
+set(MIOSIX_CUSTOM_BOARD_SETTINGS_INC "" CACHE PATH "Include directory for custom board_settings.h")
+mark_as_advanced(MIOSIX_CUSTOM_BOARD_SETTINGS_INC)
+if(MIOSIX_CUSTOM_BOARD_SETTINGS_INC)
+    set(MIOSIX_BOARD_SETTINGS_INC ${MIOSIX_CUSTOM_BOARD_SETTINGS_INC})
+    message(NOTICE "You have set a custom path for board_settings.h")
+else()
+    set(MIOSIX_BOARD_SETTINGS_INC ${MIOSIX_BOARD_INC}/config)
+endif()
+
+# 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(MIOSIX_LINKER_SCRIPT_LIST
+    stm32_2m+16m_xram.ld
+    stm32_2m+384k_ram.ld
+)
+if(NOT MIOSIX_LINKER_SCRIPT IN_LIST MIOSIX_LINKER_SCRIPT_LIST)
+    # If there is no cached value, or the cached value is not in the list, set a default value
+    set(MIOSIX_LINKER_SCRIPT stm32_2m+16m_xram.ld CACHE STRING "Linker script" FORCE)
+endif()
+set_property(CACHE MIOSIX_LINKER_SCRIPT PROPERTY STRINGS ${MIOSIX_LINKER_SCRIPT_LIST})
+
+# 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.
+option(MIOSIX_ENABLE_XRAM "Enables the initialization of the external 16MB SDRAM memory" ON)
+if(MIOSIX_ENABLE_XRAM)
+    set(XRAM -D__ENABLE_XRAM) # TODO: Change to an always defined flag
+else()
+    message(NOTICE "You have disabled the XRAM, make sure that the selected linker script does not use it")
+endif()
+
+# Select HSE clock frequency (external clock on board, fixed)
+set(MIOSIX_HSE_VALUE -DHSE_VALUE=25000000)
+
+# Select clock frequency.
+# Warning: 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 SDIO and RNG will run ~6% slower (45MHz insteand of 48MHz)
+set(MIOSIX_SYSCLK_FREQ_LIST
+    -DSYSCLK_FREQ_216MHz=216000000
+)
+if(NOT MIOSIX_SYSCLK_FREQ IN_LIST MIOSIX_SYSCLK_FREQ_LIST)
+    # If there is no cached value, or the cached value is not in the list, set a default value
+    set(MIOSIX_SYSCLK_FREQ -DSYSCLK_FREQ_216MHz=216000000 CACHE STRING "Clock frenquency" FORCE)
+endif()
+set_property(CACHE MIOSIX_SYSCLK_FREQ PROPERTY STRINGS ${MIOSIX_SYSCLK_FREQ_LIST})
+
+if(MIOSIX_SYSCLK_FREQ STREQUAL -DSYSCLK_FREQ_180MHz=180000000)
+    message(NOTICE "The clock frequency has been set to 180MHz, the SDIO and RNG will run ~6% slower (45MHz insteand of 48MHz)")
+endif()
+
+# Select architecture specific files
+set(MIOSIX_ARCH_SRC
+    ${BSPS_PATH}/${BOARDCORE_OPT_BOARD}/core/stage_1_boot.cpp
+    ${BSPS_PATH}/${BOARDCORE_OPT_BOARD}/interfaces-impl/bsp.cpp
+)
+
+# Add a #define to allow querying board name
+list(APPEND MIOSIX_C_FLAGS -D_BOARD_STM32F767ZI_COMPUTE_UNIT)
+list(APPEND MIOSIX_CXX_FLAGS -D_BOARD_STM32F767ZI_COMPUTE_UNIT)
+
+# Specify a custom flash command
+# This is the program that is invoked when the program-<target_name> target is
+# built. Use <binary> or <hex> as placeolders, they will be replaced by the
+# build systems with the binary or hex file path repectively.
+# If a command is not specified, the build system will fallback to st-flash
+# set(PROGRAM_CMDLINE st-flash --connect-under-reset --reset write <binary> 0x8000000)
diff --git a/src/bsps/stm32f767zi_compute_unit/config/board_options.cmake b/src/bsps/stm32f767zi_compute_unit/config/board_options.cmake
deleted file mode 100644
index ce147ce11e93d6c2955b4102f43795b434bc5400..0000000000000000000000000000000000000000
--- a/src/bsps/stm32f767zi_compute_unit/config/board_options.cmake
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright (C) 2023 by Skyward
-#
-# This program is free software; you can redistribute it and/or 
-# it under the terms of the GNU General Public License as published 
-# 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 
-# Public License. This exception does not invalidate any other 
-# 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/>
-
-set(BOARD_NAME stm32f767zi_compute_unit)
-set(ARCH_NAME cortexM7_stm32f7)
-
-# Base directories with header files for this board
-set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common)
-set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME})
-set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config)
-
-# Specify where to find the board specific config/miosix_settings.h
-set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH})
-
-# Specify where to find the board specific config/mxgui_settings.h
-set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH})
-
-# Optimization flags:
-# -O0 do no optimization, the default if no optimization level is specified
-# -O or -O1 optimize minimally
-# -O2 optimize more
-# -O3 optimize even more
-# -Ofast optimize very aggressively to the point of breaking the standard
-# -Og Optimize debugging experience, enables optimizations that do not
-# interfere with debugging
-# -Os Optimize for size with -O2 optimizations that do not increase code size
-set(OPT_OPTIMIZATION
-    $<$<CONFIG:Debug>:-O2>
-    $<$<CONFIG:Release>:-O2>
-)
-
-# Boot file and linker script
-set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp)
-# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld)
-set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+16m_xram.ld)
-
-# Enables the initialization of the external 16MB SDRAM memory
-set(XRAM -D__ENABLE_XRAM)
-
-# Select clock frequency (HSE_VALUE is the xtal on board, fixed)
-set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000)
-
-# C++ Exception/rtti support disable flags.
-# To save code size if not using C++ exceptions (nor some STL code which
-# implicitly uses it) uncomment this option.
-# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used.
-# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS)
-
-# Specify a custom flash command
-# This is the program that is invoked when the flash flag (-f or --flash) is
-# used with the Miosix Build System. Use $binary or $hex as placeolders, they
-# will be replaced by the build systems with the binary or hex file repectively.
-# If a command is not specified, the build system will use st-flash if found
-# set(PROGRAM_CMDLINE "here your custom flash command")
-
-# Basic flags
-set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16)
-set(LINK_PATH_ARCH thumb/cm7/hardfp/fpv5)
-
-# Flags for ASM and linker
-set(AFLAGS_BASE ${FLAGS_BASE})
-set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib)
-
-# Flags for C/C++
-string(TOUPPER ${BOARD_NAME} BOARD_UPPER)
-set(CFLAGS_BASE
-    -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\"
-    -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g
-    -D_ARCH_CORTEXM7_STM32F7
-    ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c
-)
-set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT})
-
-# Select architecture specific files
-set(ARCH_SRC
-    ${ARCH_PATH}/interfaces-impl/delays.cpp
-    ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp
-    ${ARCH_PATH}/interfaces-impl/portability.cpp
-    ${BOARD_PATH}/interfaces-impl/bsp.cpp
-    ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c
-    ${KPATH}/arch/common/core/cache_cortexMx.cpp
-    ${KPATH}/arch/common/core/interrupts_cortexMx.cpp
-    ${KPATH}/arch/common/core/mpu_cortexMx.cpp
-    ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp
-    ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
-    ${KPATH}/arch/common/drivers/serial_stm32.cpp
-    ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
-)
diff --git a/src/bsps/stm32f767zi_compute_unit/config/miosix_settings.h b/src/bsps/stm32f767zi_compute_unit/config/miosix_settings.h
index 64b0670cab5f4cdfc3d8e06db7cc06e913deae15..dd185dcc5a51d0528eafb73f2f2ea929b266efd6 100644
--- a/src/bsps/stm32f767zi_compute_unit/config/miosix_settings.h
+++ b/src/bsps/stm32f767zi_compute_unit/config/miosix_settings.h
@@ -27,8 +27,8 @@
 // The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never
 // defined when compiling the code.
 #ifndef PARSING_FROM_IDE
-//#error This error is a reminder that you have not edited miosix_settings.h
-// yet.
+// #error This error is a reminder that you have not edited miosix_settings.h
+//  yet.
 #endif  // PARSING_FROM_IDE
 
 /**
@@ -70,14 +70,14 @@ namespace miosix
 // Uncomment only *one* of those
 
 #define SCHED_TYPE_PRIORITY
-//#define SCHED_TYPE_CONTROL_BASED
-//#define SCHED_TYPE_EDF
+// #define SCHED_TYPE_CONTROL_BASED
+// #define SCHED_TYPE_EDF
 
 /// \def WITH_CPU_TIME_COUNTER
 /// Allows to enable/disable CPUTimeCounter to save code size and remove its
 /// overhead from the scheduling process. By default it is not defined
 /// (CPUTimeCounter is disabled).
-//#define WITH_CPU_TIME_COUNTER
+// #define WITH_CPU_TIME_COUNTER
 
 //
 // Filesystem options
@@ -93,6 +93,33 @@ namespace miosix
 /// By default it is defined (DevFs is enabled)
 #define WITH_DEVFS
 
+/// \def WITH_FATFS
+/// Allows to enable/disable FATFS support to save code size
+/// By default it is defined (FATFS is enabled)
+#define WITH_FATFS
+/// Maxium number of files that can be opened on a mounted FATFS partition.
+/// Must be greater than 0
+constexpr unsigned char FATFS_MAX_OPEN_FILES = 8;
+/// The truncate/ftruncate operations, and seeking past the end of the file are
+/// two patterns for zero-filling a file. This requires a buffer to be done
+/// efficiently, and the size of the buffer impacts performance. To save RAM the
+/// suggested value is 512 byte, for performance 4096 or even 16384 are better.
+/// Note that no buffer is allocated unless required, the buffer is deallocated
+/// afterwards, and the worst case memory required is one buffer per mounted
+/// FATFS partition if one concurrent truncate/write past the end per partition
+/// occurs.
+constexpr unsigned int FATFS_EXTEND_BUFFER = 512;
+
+/// \def WITH_LITTLEFS
+/// Allows to enable/disable LittleFS support to save code size
+/// By default it is not defined (LittleFS is disabled)
+// #define WITH_LITTLEFS
+
+/// \def WITH_ROMFS
+/// Allows to enable/disable RomFS support to save code size
+/// By default it is not defined (RomFS is disabled)
+// #define WITH_ROMFS
+
 /// \def SYNC_AFTER_WRITE
 /// Increases filesystem write robustness. After each write operation the
 /// filesystem is synced so that a power failure happens data is not lost
@@ -101,8 +128,10 @@ namespace miosix
 /// By default it is defined (slow but safe)
 #define SYNC_AFTER_WRITE
 
-/// Maximum number of open files. Trying to open more will fail.
-/// Cannot be lower than 3, as the first three are stdin, stdout, stderr
+/// Maximum number of files a single process (or the kernel) can open. This
+/// constant is used to size file descriptor tables. Individual filesystems can
+/// introduce futher limitations. Cannot be less than 3, as the first three are
+/// stdin, stdout, stderr, and in this case no additional files can be opened.
 const unsigned char MAX_OPEN_FILES = 8;
 
 /// \def WITH_PROCESSES
@@ -110,19 +139,12 @@ const unsigned char MAX_OPEN_FILES = 8;
 /// This enables the dynamic loader to load elf programs, the extended system
 /// call service and, if the hardware supports it, the MPU to provide memory
 /// isolation of processes
-//#define WITH_PROCESSES
-
-#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
-#error Processes require C++ exception support
-#endif  // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
-
-#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
-#error Processes require filesystem support
-#endif  // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
-
-#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
-#error Processes require devfs support
-#endif  // defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
+// #define WITH_PROCESSES
+/// RomFS is enabled by default when using processes. Comment the following
+/// lines if you want to use processes without RomFS.
+#if defined(WITH_PROCESSES) && !defined(WITH_ROMFS)
+#define WITH_ROMFS
+#endif
 
 //
 // C/C++ standard library I/O (stdin, stdout and stderr related)
@@ -145,7 +167,7 @@ const unsigned char MAX_OPEN_FILES = 8;
 /// \def WITH_DEEP_SLEEP
 /// Adds interfaces and required variables to support deep sleep state switch
 /// automatically when peripherals are not required
-//#define WITH_DEEP_SLEEP
+// #define WITH_DEEP_SLEEP
 
 /**
  * \def JTAG_DISABLE_SLEEP
@@ -168,7 +190,7 @@ const unsigned int STACK_IDLE = 256;
 
 /// Default stack size for pthread_create.
 /// The chosen value is enough to call C standard library functions
-/// such as printf/fopen which are stack-heavy
+/// such as printf/fopen which are stack-heavy (MUST be divisible by 4)
 const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048;
 
 /// Maximum size of the RAM image of a process. If a program requires more
@@ -177,13 +199,28 @@ const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024;
 
 /// Minimum size of the stack for a process. If a program specifies a lower
 /// size the kernel will not run it (MUST be divisible by 4)
-const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN;
+const unsigned int MIN_PROCESS_STACK_SIZE = 1024;
 
 /// Every userspace thread has two stacks, one for when it is running in
 /// userspace and one for when it is running in kernelspace (that is, while it
 /// is executing system calls). This is the size of the stack for when the
 /// thread is running in kernelspace (MUST be divisible by 4)
-const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024;
+const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2048;
+
+/// Maximum number of arguments passed through argv to a process
+/// Also maximum number of environment variables passed through envp to a
+/// process
+const unsigned int MAX_PROCESS_ARGS = 16;
+
+/// Maximum size of the memory area at the top of the stack for arguments and
+/// environment variables. This area is not considered part of the stack and
+/// does not contribute to the stack size.
+const unsigned int MAX_PROCESS_ARGS_BLOCK_SIZE = 512;
+
+static_assert(STACK_IDLE >= STACK_MIN, "");
+static_assert(STACK_DEFAULT_FOR_PTHREAD >= STACK_MIN, "");
+static_assert(MIN_PROCESS_STACK_SIZE >= STACK_MIN, "");
+static_assert(SYSTEM_MODE_PROCESS_STACK_SIZE >= STACK_MIN, "");
 
 /// Number of priorities (MUST be >1)
 /// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as
diff --git a/src/bsps/stm32f767zi_compute_unit_v2/CMakeLists.txt b/src/bsps/stm32f767zi_compute_unit_v2/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..164c430953dae74fbb7c0db7baf02bb9f8ba73e9
--- /dev/null
+++ b/src/bsps/stm32f767zi_compute_unit_v2/CMakeLists.txt
@@ -0,0 +1,109 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# 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
+# Public License. This exception does not invalidate any other
+# 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/>
+
+# The stm32f767 has the double precision FPU, so we will build for m7
+set(MIOSIX_CPU_FLAGS -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16)
+
+# Directory with header files for this board
+set(MIOSIX_BOARD_INC ${BSPS_PATH}/${BOARDCORE_OPT_BOARD})
+
+# The user can set a custom path for board_settings.h
+set(MIOSIX_CUSTOM_BOARD_SETTINGS_INC "" CACHE PATH "Include directory for custom board_settings.h")
+mark_as_advanced(MIOSIX_CUSTOM_BOARD_SETTINGS_INC)
+if(MIOSIX_CUSTOM_BOARD_SETTINGS_INC)
+    set(MIOSIX_BOARD_SETTINGS_INC ${MIOSIX_CUSTOM_BOARD_SETTINGS_INC})
+    message(NOTICE "You have set a custom path for board_settings.h")
+else()
+    set(MIOSIX_BOARD_SETTINGS_INC ${MIOSIX_BOARD_INC}/config)
+endif()
+
+# 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(MIOSIX_LINKER_SCRIPT_LIST
+    stm32_2m+32m_xram.ld
+    stm32_2m+384k_ram.ld
+)
+if(NOT MIOSIX_LINKER_SCRIPT IN_LIST MIOSIX_LINKER_SCRIPT_LIST)
+    # If there is no cached value, or the cached value is not in the list, set a default value
+    set(MIOSIX_LINKER_SCRIPT stm32_2m+32m_xram.ld CACHE STRING "Linker script" FORCE)
+endif()
+set_property(CACHE MIOSIX_LINKER_SCRIPT PROPERTY STRINGS ${MIOSIX_LINKER_SCRIPT_LIST})
+
+# 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.
+option(MIOSIX_ENABLE_XRAM "Enables the initialization of the external 16MB SDRAM memory" ON)
+if(MIOSIX_ENABLE_XRAM)
+    set(XRAM -D__ENABLE_XRAM) # TODO: Change to an always defined flag
+else()
+    message(NOTICE "You have disabled the XRAM, make sure that the selected linker script does not use it")
+endif()
+
+# Select HSE clock frequency (external clock on board, fixed)
+set(MIOSIX_HSE_VALUE -DHSE_VALUE=25000000)
+
+# Select clock frequency.
+# Warning: 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 SDIO and RNG will run ~6% slower (45MHz insteand of 48MHz)
+set(MIOSIX_SYSCLK_FREQ_LIST
+    -DSYSCLK_FREQ_216MHz=216000000
+)
+if(NOT MIOSIX_SYSCLK_FREQ IN_LIST MIOSIX_SYSCLK_FREQ_LIST)
+    # If there is no cached value, or the cached value is not in the list, set a default value
+    set(MIOSIX_SYSCLK_FREQ -DSYSCLK_FREQ_216MHz=216000000 CACHE STRING "Clock frenquency" FORCE)
+endif()
+set_property(CACHE MIOSIX_SYSCLK_FREQ PROPERTY STRINGS ${MIOSIX_SYSCLK_FREQ_LIST})
+
+if(MIOSIX_SYSCLK_FREQ STREQUAL -DSYSCLK_FREQ_180MHz=180000000)
+    message(NOTICE "The clock frequency has been set to 180MHz, the SDIO and RNG will run ~6% slower (45MHz insteand of 48MHz)")
+endif()
+
+# Select architecture specific files
+set(MIOSIX_ARCH_SRC
+    ${BSPS_PATH}/${BOARDCORE_OPT_BOARD}/core/stage_1_boot.cpp
+    ${BSPS_PATH}/${BOARDCORE_OPT_BOARD}/interfaces-impl/bsp.cpp
+)
+
+# Add a #define to allow querying board name
+list(APPEND MIOSIX_C_FLAGS -D_BOARD_STM32F767ZI_COMPUTE_UNIT_V2)
+list(APPEND MIOSIX_CXX_FLAGS -D_BOARD_STM32F767ZI_COMPUTE_UNIT_V2)
+
+
+list(APPEND MIOSIX_ARCH_SRC
+    ${MIOSIX_KPATH}/arch/common/drivers/stm32_bsram.cpp
+)
+
+# Specify a custom flash command
+# This is the program that is invoked when the program-<target_name> target is
+# built. Use <binary> or <hex> as placeolders, they will be replaced by the
+# build systems with the binary or hex file path repectively.
+# If a command is not specified, the build system will fallback to st-flash
+# set(PROGRAM_CMDLINE st-flash --connect-under-reset --reset write <binary> 0x8000000)
diff --git a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options.cmake b/src/bsps/stm32f767zi_compute_unit_v2/config/board_options.cmake
deleted file mode 100644
index f1795749d8d38b00767a4797bd348fa6b98708cc..0000000000000000000000000000000000000000
--- a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options.cmake
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2023 by Skyward
-#
-# This program is free software; you can redistribute it and/or 
-# it under the terms of the GNU General Public License as published 
-# 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 
-# Public License. This exception does not invalidate any other 
-# 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/>
-
-set(BOARD_NAME stm32f767zi_compute_unit_v2)
-set(ARCH_NAME cortexM7_stm32f7)
-
-# Base directories with header files for this board
-set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common)
-set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME})
-set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config)
-
-# Specify where to find the board specific config/miosix_settings.h
-set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH})
-
-# Specify where to find the board specific config/mxgui_settings.h
-set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH})
-
-# Optimization flags:
-# -O0 do no optimization, the default if no optimization level is specified
-# -O or -O1 optimize minimally
-# -O2 optimize more
-# -O3 optimize even more
-# -Ofast optimize very aggressively to the point of breaking the standard
-# -Og Optimize debugging experience, enables optimizations that do not
-# interfere with debugging
-# -Os Optimize for size with -O2 optimizations that do not increase code size
-set(OPT_OPTIMIZATION -O2)
-
-# Boot file and linker script
-set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp)
-# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld)
-set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+32m_xram.ld)
-
-# Enables the initialization of the external 16MB SDRAM memory
-set(XRAM -D__ENABLE_XRAM)
-
-# Select clock frequency (HSE_VALUE is the xtal on board, fixed)
-set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000)
-
-# C++ Exception/rtti support disable flags.
-# To save code size if not using C++ exceptions (nor some STL code which
-# implicitly uses it) uncomment this option.
-# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used.
-# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS)
-
-# Specify a custom flash command
-# This is the program that is invoked when the flash flag (-f or --flash) is
-# used with the Miosix Build System. Use $binary or $hex as placeolders, they
-# will be replaced by the build systems with the binary or hex file repectively.
-# If a command is not specified, the build system will use st-flash if found
-# set(PROGRAM_CMDLINE "here your custom flash command")
-
-# Basic flags
-set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16)
-set(LINK_PATH_ARCH thumb/cm7/hardfp/fpv5)
-
-# Flags for ASM and linker
-set(AFLAGS_BASE ${FLAGS_BASE})
-set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib)
-
-# Flags for C/C++
-string(TOUPPER ${BOARD_NAME} BOARD_UPPER)
-set(CFLAGS_BASE
-    -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\"
-    -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g
-    -D_ARCH_CORTEXM7_STM32F7
-    ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c
-)
-set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT})
-
-# Select architecture specific files
-set(ARCH_SRC
-    ${ARCH_PATH}/interfaces-impl/delays.cpp
-    ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp
-    ${ARCH_PATH}/interfaces-impl/portability.cpp
-    ${BOARD_PATH}/interfaces-impl/bsp.cpp
-    ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c
-    ${KPATH}/arch/common/core/cache_cortexMx.cpp
-    ${KPATH}/arch/common/core/interrupts_cortexMx.cpp
-    ${KPATH}/arch/common/core/mpu_cortexMx.cpp
-    ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp
-    ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
-    ${KPATH}/arch/common/drivers/serial_stm32.cpp
-    ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
-    ${KPATH}/arch/common/drivers/stm32_bsram.cpp
-)
diff --git a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options_no_xram.cmake b/src/bsps/stm32f767zi_compute_unit_v2/config/board_options_no_xram.cmake
deleted file mode 100644
index 55442096325d63927e3233ceab1a66b46db9e1f1..0000000000000000000000000000000000000000
--- a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options_no_xram.cmake
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2023 by Skyward
-#
-# This program is free software; you can redistribute it and/or 
-# it under the terms of the GNU General Public License as published 
-# 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 
-# Public License. This exception does not invalidate any other 
-# 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/>
-
-set(BOARD_NAME stm32f767zi_compute_unit_v2_no_xram)
-set(ARCH_NAME cortexM7_stm32f7)
-
-# Base directories with header files for this board
-set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common)
-set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/stm32f767zi_compute_unit_v2)
-set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/stm32f767zi_compute_unit_v2/config)
-
-# Specify where to find the board specific config/miosix_settings.h
-set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH})
-
-# Specify where to find the board specific config/mxgui_settings.h
-set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH})
-
-# Optimization flags:
-# -O0 do no optimization, the default if no optimization level is specified
-# -O or -O1 optimize minimally
-# -O2 optimize more
-# -O3 optimize even more
-# -Ofast optimize very aggressively to the point of breaking the standard
-# -Og Optimize debugging experience, enables optimizations that do not
-# interfere with debugging
-# -Os Optimize for size with -O2 optimizations that do not increase code size
-set(OPT_OPTIMIZATION -O2)
-
-# Boot file and linker script
-set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp)
-set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld)
-# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+16m_xram.ld)
-
-# Enables the initialization of the external 16MB SDRAM memory
-set(XRAM -D__ENABLE_XRAM)
-
-# Select clock frequency (HSE_VALUE is the xtal on board, fixed)
-set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000)
-
-# C++ Exception/rtti support disable flags.
-# To save code size if not using C++ exceptions (nor some STL code which
-# implicitly uses it) uncomment this option.
-# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used.
-# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS)
-
-# Specify a custom flash command
-# This is the program that is invoked when the flash flag (-f or --flash) is
-# used with the Miosix Build System. Use $binary or $hex as placeolders, they
-# will be replaced by the build systems with the binary or hex file repectively.
-# If a command is not specified, the build system will use st-flash if found
-# set(PROGRAM_CMDLINE "here your custom flash command")
-
-# Basic flags
-set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16)
-set(LINK_PATH_ARCH thumb/cm7/hardfp/fpv5)
-
-# Flags for ASM and linker
-set(AFLAGS_BASE ${FLAGS_BASE})
-set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib)
-
-# Flags for C/C++
-string(TOUPPER ${BOARD_NAME} BOARD_UPPER)
-set(CFLAGS_BASE
-    -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\"
-    -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g
-    -D_ARCH_CORTEXM7_STM32F7
-    ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c
-)
-set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT})
-
-# Select architecture specific files
-set(ARCH_SRC
-    ${ARCH_PATH}/interfaces-impl/delays.cpp
-    ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp
-    ${ARCH_PATH}/interfaces-impl/portability.cpp
-    ${BOARD_PATH}/interfaces-impl/bsp.cpp
-    ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c
-    ${KPATH}/arch/common/core/cache_cortexMx.cpp
-    ${KPATH}/arch/common/core/interrupts_cortexMx.cpp
-    ${KPATH}/arch/common/core/mpu_cortexMx.cpp
-    ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp
-    ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
-    ${KPATH}/arch/common/drivers/serial_stm32.cpp
-    ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
-    ${KPATH}/arch/common/drivers/stm32_bsram.cpp
-)
diff --git a/src/bsps/stm32f767zi_compute_unit_v2/config/miosix_settings.h b/src/bsps/stm32f767zi_compute_unit_v2/config/miosix_settings.h
index 64b0670cab5f4cdfc3d8e06db7cc06e913deae15..f592c28ef8b73649efce20292dfadb37352bb2bc 100644
--- a/src/bsps/stm32f767zi_compute_unit_v2/config/miosix_settings.h
+++ b/src/bsps/stm32f767zi_compute_unit_v2/config/miosix_settings.h
@@ -93,6 +93,33 @@ namespace miosix
 /// By default it is defined (DevFs is enabled)
 #define WITH_DEVFS
 
+/// \def WITH_FATFS
+/// Allows to enable/disable FATFS support to save code size
+/// By default it is defined (FATFS is enabled)
+#define WITH_FATFS
+/// Maxium number of files that can be opened on a mounted FATFS partition.
+/// Must be greater than 0
+constexpr unsigned char FATFS_MAX_OPEN_FILES = 8;
+/// The truncate/ftruncate operations, and seeking past the end of the file are
+/// two patterns for zero-filling a file. This requires a buffer to be done
+/// efficiently, and the size of the buffer impacts performance. To save RAM the
+/// suggested value is 512 byte, for performance 4096 or even 16384 are better.
+/// Note that no buffer is allocated unless required, the buffer is deallocated
+/// afterwards, and the worst case memory required is one buffer per mounted
+/// FATFS partition if one concurrent truncate/write past the end per partition
+/// occurs.
+constexpr unsigned int FATFS_EXTEND_BUFFER = 512;
+
+/// \def WITH_LITTLEFS
+/// Allows to enable/disable LittleFS support to save code size
+/// By default it is not defined (LittleFS is disabled)
+// #define WITH_LITTLEFS
+
+/// \def WITH_ROMFS
+/// Allows to enable/disable RomFS support to save code size
+/// By default it is not defined (RomFS is disabled)
+// #define WITH_ROMFS
+
 /// \def SYNC_AFTER_WRITE
 /// Increases filesystem write robustness. After each write operation the
 /// filesystem is synced so that a power failure happens data is not lost
@@ -101,8 +128,10 @@ namespace miosix
 /// By default it is defined (slow but safe)
 #define SYNC_AFTER_WRITE
 
-/// Maximum number of open files. Trying to open more will fail.
-/// Cannot be lower than 3, as the first three are stdin, stdout, stderr
+/// Maximum number of files a single process (or the kernel) can open. This
+/// constant is used to size file descriptor tables. Individual filesystems can
+/// introduce futher limitations. Cannot be less than 3, as the first three are
+/// stdin, stdout, stderr, and in this case no additional files can be opened.
 const unsigned char MAX_OPEN_FILES = 8;
 
 /// \def WITH_PROCESSES
@@ -110,19 +139,12 @@ const unsigned char MAX_OPEN_FILES = 8;
 /// This enables the dynamic loader to load elf programs, the extended system
 /// call service and, if the hardware supports it, the MPU to provide memory
 /// isolation of processes
-//#define WITH_PROCESSES
-
-#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
-#error Processes require C++ exception support
-#endif  // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
-
-#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
-#error Processes require filesystem support
-#endif  // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
-
-#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
-#error Processes require devfs support
-#endif  // defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
+// #define WITH_PROCESSES
+/// RomFS is enabled by default when using processes. Comment the following
+/// lines if you want to use processes without RomFS.
+#if defined(WITH_PROCESSES) && !defined(WITH_ROMFS)
+#define WITH_ROMFS
+#endif
 
 //
 // C/C++ standard library I/O (stdin, stdout and stderr related)
@@ -168,7 +190,7 @@ const unsigned int STACK_IDLE = 256;
 
 /// Default stack size for pthread_create.
 /// The chosen value is enough to call C standard library functions
-/// such as printf/fopen which are stack-heavy
+/// such as printf/fopen which are stack-heavy (MUST be divisible by 4)
 const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048;
 
 /// Maximum size of the RAM image of a process. If a program requires more
@@ -177,13 +199,28 @@ const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024;
 
 /// Minimum size of the stack for a process. If a program specifies a lower
 /// size the kernel will not run it (MUST be divisible by 4)
-const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN;
+const unsigned int MIN_PROCESS_STACK_SIZE = 1024;
 
 /// Every userspace thread has two stacks, one for when it is running in
 /// userspace and one for when it is running in kernelspace (that is, while it
 /// is executing system calls). This is the size of the stack for when the
 /// thread is running in kernelspace (MUST be divisible by 4)
-const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024;
+const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2048;
+
+/// Maximum number of arguments passed through argv to a process
+/// Also maximum number of environment variables passed through envp to a
+/// process
+const unsigned int MAX_PROCESS_ARGS = 16;
+
+/// Maximum size of the memory area at the top of the stack for arguments and
+/// environment variables. This area is not considered part of the stack and
+/// does not contribute to the stack size.
+const unsigned int MAX_PROCESS_ARGS_BLOCK_SIZE = 512;
+
+static_assert(STACK_IDLE >= STACK_MIN, "");
+static_assert(STACK_DEFAULT_FOR_PTHREAD >= STACK_MIN, "");
+static_assert(MIN_PROCESS_STACK_SIZE >= STACK_MIN, "");
+static_assert(SYSTEM_MODE_PROCESS_STACK_SIZE >= STACK_MIN, "");
 
 /// Number of priorities (MUST be >1)
 /// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as
diff --git a/src/bsps/stm32f767zi_lyra_biscotto/CMakeLists.txt b/src/bsps/stm32f767zi_lyra_biscotto/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bfcde51fb559a69a6d014e95820398a67c583a54
--- /dev/null
+++ b/src/bsps/stm32f767zi_lyra_biscotto/CMakeLists.txt
@@ -0,0 +1,109 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# 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
+# Public License. This exception does not invalidate any other
+# 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/>
+
+# The stm32f767 has the double precision FPU, so we will build for m7
+set(MIOSIX_CPU_FLAGS -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16)
+
+# Directory with header files for this board
+set(MIOSIX_BOARD_INC ${BSPS_PATH}/${BOARDCORE_OPT_BOARD})
+
+# The user can set a custom path for board_settings.h
+set(MIOSIX_CUSTOM_BOARD_SETTINGS_INC "" CACHE PATH "Include directory for custom board_settings.h")
+mark_as_advanced(MIOSIX_CUSTOM_BOARD_SETTINGS_INC)
+if(MIOSIX_CUSTOM_BOARD_SETTINGS_INC)
+    set(MIOSIX_BOARD_SETTINGS_INC ${MIOSIX_CUSTOM_BOARD_SETTINGS_INC})
+    message(NOTICE "You have set a custom path for board_settings.h")
+else()
+    set(MIOSIX_BOARD_SETTINGS_INC ${MIOSIX_BOARD_INC}/config)
+endif()
+
+# 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(MIOSIX_LINKER_SCRIPT_LIST
+    stm32_2m+32m_xram.ld
+    stm32_2m+384k_ram.ld
+)
+if(NOT MIOSIX_LINKER_SCRIPT IN_LIST MIOSIX_LINKER_SCRIPT_LIST)
+    # If there is no cached value, or the cached value is not in the list, set a default value
+    set(MIOSIX_LINKER_SCRIPT stm32_2m+32m_xram.ld CACHE STRING "Linker script" FORCE)
+endif()
+set_property(CACHE MIOSIX_LINKER_SCRIPT PROPERTY STRINGS ${MIOSIX_LINKER_SCRIPT_LIST})
+
+# 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.
+option(MIOSIX_ENABLE_XRAM "Enables the initialization of the external 16MB SDRAM memory" ON)
+if(MIOSIX_ENABLE_XRAM)
+    set(XRAM -D__ENABLE_XRAM) # TODO: Change to an always defined flag
+else()
+    message(NOTICE "You have disabled the XRAM, make sure that the selected linker script does not use it")
+endif()
+
+# Select HSE clock frequency (external clock on board, fixed)
+set(MIOSIX_HSE_VALUE -DHSE_VALUE=25000000)
+
+# Select clock frequency.
+# Warning: 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 SDIO and RNG will run ~6% slower (45MHz insteand of 48MHz)
+set(MIOSIX_SYSCLK_FREQ_LIST
+    -DSYSCLK_FREQ_216MHz=216000000
+)
+if(NOT MIOSIX_SYSCLK_FREQ IN_LIST MIOSIX_SYSCLK_FREQ_LIST)
+    # If there is no cached value, or the cached value is not in the list, set a default value
+    set(MIOSIX_SYSCLK_FREQ -DSYSCLK_FREQ_216MHz=216000000 CACHE STRING "Clock frenquency" FORCE)
+endif()
+set_property(CACHE MIOSIX_SYSCLK_FREQ PROPERTY STRINGS ${MIOSIX_SYSCLK_FREQ_LIST})
+
+if(MIOSIX_SYSCLK_FREQ STREQUAL -DSYSCLK_FREQ_180MHz=180000000)
+    message(NOTICE "The clock frequency has been set to 180MHz, the SDIO and RNG will run ~6% slower (45MHz insteand of 48MHz)")
+endif()
+
+# Select architecture specific files
+set(MIOSIX_ARCH_SRC
+    ${BSPS_PATH}/${BOARDCORE_OPT_BOARD}/core/stage_1_boot.cpp
+    ${BSPS_PATH}/${BOARDCORE_OPT_BOARD}/interfaces-impl/bsp.cpp
+)
+
+# Add a #define to allow querying board name
+list(APPEND MIOSIX_C_FLAGS -D_BOARD_STM32F767ZI_LYRA_BISCOTTO)
+list(APPEND MIOSIX_CXX_FLAGS -D_BOARD_STM32F767ZI_LYRA_BISCOTTO)
+
+
+list(APPEND MIOSIX_ARCH_SRC
+    ${MIOSIX_KPATH}/arch/common/drivers/stm32_bsram.cpp
+)
+
+# Specify a custom flash command
+# This is the program that is invoked when the program-<target_name> target is
+# built. Use <binary> or <hex> as placeolders, they will be replaced by the
+# build systems with the binary or hex file path repectively.
+# If a command is not specified, the build system will fallback to st-flash
+# set(PROGRAM_CMDLINE st-flash --connect-under-reset --reset write <binary> 0x8000000)
diff --git a/src/bsps/stm32f767zi_lyra_biscotto/config/board_options.cmake b/src/bsps/stm32f767zi_lyra_biscotto/config/board_options.cmake
deleted file mode 100644
index 1f21a96fb6da6f81cde3f259f1a60abd7480e2e8..0000000000000000000000000000000000000000
--- a/src/bsps/stm32f767zi_lyra_biscotto/config/board_options.cmake
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (C) 2023 by Skyward
-#
-# This program is free software; you can redistribute it and/or 
-# it under the terms of the GNU General Public License as published 
-# 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 
-# Public License. This exception does not invalidate any other 
-# 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/>
-
-set(BOARD_NAME stm32f767zi_lyra_biscotto)
-set(ARCH_NAME cortexM7_stm32f7)
-
-# Base directories with header files for this board
-set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common)
-set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME})
-set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config)
-
-# Specify where to find the board specific config/miosix_settings.h
-set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH})
-
-# Specify where to find the board specific config/mxgui_settings.h
-set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH})
-
-# Optimization flags:
-# -O0 do no optimization, the default if no optimization level is specified
-# -O or -O1 optimize minimally
-# -O2 optimize more
-# -O3 optimize even more
-# -Ofast optimize very aggressively to the point of breaking the standard
-# -Og Optimize debugging experience, enables optimizations that do not
-# interfere with debugging
-# -Os Optimize for size with -O2 optimizations that do not increase code size
-set(OPT_OPTIMIZATION -O2)
-
-# Boot file and linker script
-set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp)
-# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld)
-set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+32m_xram.ld)
-
-# Enables the initialization of the external 16MB SDRAM memory
-set(XRAM -D__ENABLE_XRAM)
-
-# Select clock frequency (HSE_VALUE is the xtal on board, fixed)
-set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000)
-
-# C++ Exception/rtti support disable flags.
-# To save code size if not using C++ exceptions (nor some STL code which
-# implicitly uses it) uncomment this option.
-# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used.
-# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS)
-
-# Specify a custom flash command
-# This is the program that is invoked when the flash flag (-f or --flash) is
-# used with the Miosix Build System. Use $binary or $hex as placeolders, they
-# will be replaced by the build systems with the binary or hex file repectively.
-# If a command is not specified, the build system will use st-flash if found
-# set(PROGRAM_CMDLINE "here your custom flash command")
-
-# Basic flags
-set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16)
-
-# Flags for ASM and linker
-set(AFLAGS_BASE ${FLAGS_BASE})
-set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib)
-
-# Flags for C/C++
-string(TOUPPER ${BOARD_NAME} BOARD_UPPER)
-set(CFLAGS_BASE
-    -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\"
-    -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g
-    -D_ARCH_CORTEXM7_STM32F7
-    ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c
-)
-set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT})
-
-# Select architecture specific files
-set(ARCH_SRC
-    ${ARCH_PATH}/interfaces-impl/delays.cpp
-    ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp
-    ${ARCH_PATH}/interfaces-impl/portability.cpp
-    ${BOARD_PATH}/interfaces-impl/bsp.cpp
-    ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c
-    ${KPATH}/arch/common/core/cache_cortexMx.cpp
-    ${KPATH}/arch/common/core/interrupts_cortexMx.cpp
-    ${KPATH}/arch/common/core/mpu_cortexMx.cpp
-    ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp
-    ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
-    ${KPATH}/arch/common/drivers/serial_stm32.cpp
-    ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
-    ${KPATH}/arch/common/drivers/stm32_bsram.cpp
-)
diff --git a/src/bsps/stm32f767zi_lyra_biscotto/config/miosix_settings.h b/src/bsps/stm32f767zi_lyra_biscotto/config/miosix_settings.h
index 64b0670cab5f4cdfc3d8e06db7cc06e913deae15..f592c28ef8b73649efce20292dfadb37352bb2bc 100644
--- a/src/bsps/stm32f767zi_lyra_biscotto/config/miosix_settings.h
+++ b/src/bsps/stm32f767zi_lyra_biscotto/config/miosix_settings.h
@@ -93,6 +93,33 @@ namespace miosix
 /// By default it is defined (DevFs is enabled)
 #define WITH_DEVFS
 
+/// \def WITH_FATFS
+/// Allows to enable/disable FATFS support to save code size
+/// By default it is defined (FATFS is enabled)
+#define WITH_FATFS
+/// Maxium number of files that can be opened on a mounted FATFS partition.
+/// Must be greater than 0
+constexpr unsigned char FATFS_MAX_OPEN_FILES = 8;
+/// The truncate/ftruncate operations, and seeking past the end of the file are
+/// two patterns for zero-filling a file. This requires a buffer to be done
+/// efficiently, and the size of the buffer impacts performance. To save RAM the
+/// suggested value is 512 byte, for performance 4096 or even 16384 are better.
+/// Note that no buffer is allocated unless required, the buffer is deallocated
+/// afterwards, and the worst case memory required is one buffer per mounted
+/// FATFS partition if one concurrent truncate/write past the end per partition
+/// occurs.
+constexpr unsigned int FATFS_EXTEND_BUFFER = 512;
+
+/// \def WITH_LITTLEFS
+/// Allows to enable/disable LittleFS support to save code size
+/// By default it is not defined (LittleFS is disabled)
+// #define WITH_LITTLEFS
+
+/// \def WITH_ROMFS
+/// Allows to enable/disable RomFS support to save code size
+/// By default it is not defined (RomFS is disabled)
+// #define WITH_ROMFS
+
 /// \def SYNC_AFTER_WRITE
 /// Increases filesystem write robustness. After each write operation the
 /// filesystem is synced so that a power failure happens data is not lost
@@ -101,8 +128,10 @@ namespace miosix
 /// By default it is defined (slow but safe)
 #define SYNC_AFTER_WRITE
 
-/// Maximum number of open files. Trying to open more will fail.
-/// Cannot be lower than 3, as the first three are stdin, stdout, stderr
+/// Maximum number of files a single process (or the kernel) can open. This
+/// constant is used to size file descriptor tables. Individual filesystems can
+/// introduce futher limitations. Cannot be less than 3, as the first three are
+/// stdin, stdout, stderr, and in this case no additional files can be opened.
 const unsigned char MAX_OPEN_FILES = 8;
 
 /// \def WITH_PROCESSES
@@ -110,19 +139,12 @@ const unsigned char MAX_OPEN_FILES = 8;
 /// This enables the dynamic loader to load elf programs, the extended system
 /// call service and, if the hardware supports it, the MPU to provide memory
 /// isolation of processes
-//#define WITH_PROCESSES
-
-#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
-#error Processes require C++ exception support
-#endif  // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
-
-#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
-#error Processes require filesystem support
-#endif  // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
-
-#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
-#error Processes require devfs support
-#endif  // defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
+// #define WITH_PROCESSES
+/// RomFS is enabled by default when using processes. Comment the following
+/// lines if you want to use processes without RomFS.
+#if defined(WITH_PROCESSES) && !defined(WITH_ROMFS)
+#define WITH_ROMFS
+#endif
 
 //
 // C/C++ standard library I/O (stdin, stdout and stderr related)
@@ -168,7 +190,7 @@ const unsigned int STACK_IDLE = 256;
 
 /// Default stack size for pthread_create.
 /// The chosen value is enough to call C standard library functions
-/// such as printf/fopen which are stack-heavy
+/// such as printf/fopen which are stack-heavy (MUST be divisible by 4)
 const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048;
 
 /// Maximum size of the RAM image of a process. If a program requires more
@@ -177,13 +199,28 @@ const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024;
 
 /// Minimum size of the stack for a process. If a program specifies a lower
 /// size the kernel will not run it (MUST be divisible by 4)
-const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN;
+const unsigned int MIN_PROCESS_STACK_SIZE = 1024;
 
 /// Every userspace thread has two stacks, one for when it is running in
 /// userspace and one for when it is running in kernelspace (that is, while it
 /// is executing system calls). This is the size of the stack for when the
 /// thread is running in kernelspace (MUST be divisible by 4)
-const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024;
+const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2048;
+
+/// Maximum number of arguments passed through argv to a process
+/// Also maximum number of environment variables passed through envp to a
+/// process
+const unsigned int MAX_PROCESS_ARGS = 16;
+
+/// Maximum size of the memory area at the top of the stack for arguments and
+/// environment variables. This area is not considered part of the stack and
+/// does not contribute to the stack size.
+const unsigned int MAX_PROCESS_ARGS_BLOCK_SIZE = 512;
+
+static_assert(STACK_IDLE >= STACK_MIN, "");
+static_assert(STACK_DEFAULT_FOR_PTHREAD >= STACK_MIN, "");
+static_assert(MIN_PROCESS_STACK_SIZE >= STACK_MIN, "");
+static_assert(SYSTEM_MODE_PROCESS_STACK_SIZE >= STACK_MIN, "");
 
 /// Number of priorities (MUST be >1)
 /// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as
diff --git a/src/tests/test-serial/CMakeLists.txt b/src/tests/test-serial/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ca864fd57be3085dc4f0ca20b5b173d91242e322
--- /dev/null
+++ b/src/tests/test-serial/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# 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
+# Public License. This exception does not invalidate any other
+# 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/>
+
+cmake_minimum_required(VERSION 3.16)
+
+project(TestSerial C CXX ASM)
+
+# Set here your board of choice
+set(BOARDCORE_OPT_BOARD stm32f767zi_compute_unit CACHE STRING "Target board")
+
+cmake_path(GET CMAKE_CURRENT_LIST_DIR PARENT_PATH TESTS_PATH)
+include(${TESTS_PATH}/../../CMakeLists.txt)
+
+# List here your source files (.s, .c and .cpp)
+add_executable(test-serial test-serial.cpp)
+boardcore_link_target(test-serial)
+
+# List here additional include directories
+# target_include_directories(test-serial PRIVATE here_your_includes)
+
+# List here additional static libraries
+# target_link_libraries(test-serial PRIVATE here_your_libraries)
diff --git a/src/tests/test-serial.cpp b/src/tests/test-serial/test-serial.cpp
similarity index 100%
rename from src/tests/test-serial.cpp
rename to src/tests/test-serial/test-serial.cpp