diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/.project b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/.project
index 13ae8dd52..a23c22fa3 100644
--- a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/.project
+++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/.project
@@ -29,6 +29,11 @@
2
CHIBIOS/os/hal/boards/ST_NUCLEO64_G474RE
+
+ fatfs
+ 2
+ CHIBIOS/ext/fatfs
+
os
2
diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/STM32L4R9xI_SB.ld b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/STM32L4R9xI_SB.ld
index a8c6b9393..bfa4d3aba 100644
--- a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/STM32L4R9xI_SB.ld
+++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/STM32L4R9xI_SB.ld
@@ -27,9 +27,9 @@ MEMORY
flash5 (rx) : org = 0x00000000, len = 0
flash6 (rx) : org = 0x00000000, len = 0
flash7 (rx) : org = 0x00000000, len = 0
- ram0 (wx) : org = 0x20000000, len = 640k - 384k /* Host data. */
- ram1 (wx) : org = 0x20040000, len = 192k /* Sandbox 1 data. */
- ram2 (wx) : org = 0x20070000, len = 192k /* Sandbox 2 data. */
+ ram0 (wx) : org = 0x20000000, len = 640k - 256k /* Host data. */
+ ram1 (wx) : org = 0x20060000, len = 128k /* Sandbox 1 data. */
+ ram2 (wx) : org = 0x20080000, len = 128k /* Sandbox 2 data. */
ram3 (wx) : org = 0x00000000, len = 0
ram4 (wx) : org = 0x00000000, len = 0
ram5 (wx) : org = 0x00000000, len = 0
diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/mcuconf.h b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/mcuconf.h
index a5f8ac05e..033e5e59b 100644
--- a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/mcuconf.h
+++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/mcuconf.h
@@ -293,7 +293,7 @@
#define STM32_SERIAL_USE_USART3 FALSE
#define STM32_SERIAL_USE_UART4 FALSE
#define STM32_SERIAL_USE_UART5 FALSE
-#define STM32_SERIAL_USE_LPUART1 FALSE
+#define STM32_SERIAL_USE_LPUART1 TRUE
/*
* SIO driver system settings.
diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/main.c b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/main.c
index b7a8579bc..924337bc1 100644
--- a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/main.c
+++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/main.c
@@ -26,33 +26,49 @@
#include "startup_defs.h"
+#include "sdmon.h"
+
/*===========================================================================*/
/* VFS-related. */
/*===========================================================================*/
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE
-/* VFS FatFS driver object representing the root directory.*/
-static vfs_fatfs_driver_c root_driver;
+/* VFS FatFS driver used by all file systems.*/
+static vfs_fatfs_driver_c fatfs_driver;
#endif
-/* VFS overlay driver object representing the root directory.*/
+/* VFS overlay driver object representing the absolute root directory.*/
static vfs_overlay_driver_c root_overlay_driver;
-/* VFS streams driver object representing the /dev directory.*/
-static vfs_streams_driver_c dev_driver;
+/* Segregated roots for the two sandboxes.*/
+static vfs_overlay_driver_c sb1_root_overlay_driver;
+static vfs_overlay_driver_c sb2_root_overlay_driver;
+
+/* Shared directory between the two sandboxes.*/
+static vfs_overlay_driver_c sb_shared_overlay_driver;
+
+/* VFS streams driver objects representing the /dev private directories.*/
+static vfs_streams_driver_c sb1_dev_driver;
+static vfs_streams_driver_c sb2_dev_driver;
/* VFS API will use this object as implicit root, defining this
symbol is expected.*/
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
+/* Used for /dev/null.*/
static NullStream nullstream;
-/* Stream to be exposed under /dev as files.*/
-static const drv_streams_element_t streams[] = {
+/* Streams to be exposed under /dev as files.*/
+static const drv_streams_element_t sb1_streams[] = {
{"VSD1", (BaseSequentialStream *)&SD2},
{"null", (BaseSequentialStream *)&nullstream},
{NULL, NULL}
};
+static const drv_streams_element_t sb2_streams[] = {
+ {"VSD1", (BaseSequentialStream *)&LPSD1},
+ {"null", (BaseSequentialStream *)&nullstream},
+ {NULL, NULL}
+};
/*===========================================================================*/
/* SB-related. */
@@ -72,7 +88,7 @@ static const sb_config_t sb_config1 = {
.writeable = true
}
},
- .vfs_driver = (vfs_driver_c *)&root_overlay_driver
+ .vfs_driver = (vfs_driver_c *)&sb1_root_overlay_driver
};
/* Sandbox 2 configuration.*/
@@ -89,7 +105,7 @@ static const sb_config_t sb_config2 = {
.writeable = true
}
},
- .vfs_driver = (vfs_driver_c *)&root_overlay_driver
+ .vfs_driver = (vfs_driver_c *)&sb2_root_overlay_driver
};
/* Sandbox objects.*/
@@ -98,6 +114,8 @@ sb_class_t sbx1, sbx2;
static THD_WORKING_AREA(waUnprivileged1, 512);
static THD_WORKING_AREA(waUnprivileged2, 512);
+static thread_t *utp1, *utp2;
+
/*===========================================================================*/
/* Main and generic code. */
/*===========================================================================*/
@@ -117,15 +135,34 @@ static THD_FUNCTION(Thread1, arg) {
}
}
+/*
+ * SB termination event.
+ */
+static void SBHandler(eventid_t id) {
+
+ (void)id;
+
+ if (chThdTerminatedX(utp1)) {
+ chprintf((BaseSequentialStream *)&SD2, "SB1 terminated\r\n");
+ }
+
+ if (chThdTerminatedX(utp2)) {
+ chprintf((BaseSequentialStream *)&SD2, "SB2 terminated\r\n");
+ }
+}
+
/*
* Application entry point.
*/
int main(void) {
- unsigned i = 1U;
- thread_t *utp1, *utp2;
- event_listener_t el1;
+ event_listener_t el0, el1, el2;
vfs_file_node_c *fnp;
msg_t ret;
+ static const evhandler_t evhndl[] = {
+ sdmonInsertHandler,
+ sdmonRemoveHandler,
+ SBHandler
+ };
/*
* System initializations.
@@ -142,27 +179,64 @@ int main(void) {
sbHostInit();
/*
- * Starting a serial port for I/O, initializing other streams too.
+ * Starting a serial ports for I/O, initializing other streams too.
*/
sdStart(&SD2, NULL);
+ sdStart(&LPSD1, NULL);
nullObjectInit(&nullstream);
+ /*
+ * Activates the card insertion monitor.
+ */
+ sdmonInit();
+
/*
* Creating a blinker thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
/*
- * Initializing an overlay VFS object as a root, no overlaid driver,
- * registering a streams VFS driver on the VFS overlay root as "/dev".
+ * Initializing an overlay VFS object as a root on top of a FatFS driver.
+ * This is accessible from kernel space and covers the whole file system.
*/
- drvOverlayObjectInit(&root_overlay_driver, NULL, NULL);
- ret = drvOverlayRegisterDriver(&root_overlay_driver,
- drvStreamsObjectInit(&dev_driver, &streams[0]),
+ drvOverlayObjectInit(&root_overlay_driver, (vfs_driver_c *)&fatfs_driver, NULL);
+
+ /*
+ * Initializing overlay drivers for the two sandbox roots. Those also use
+ * the FatFS driver but are restricted to "/sb1" and "/sb2" directories.
+ */
+ drvOverlayObjectInit(&sb1_root_overlay_driver, (vfs_driver_c *)&fatfs_driver, "sb1");
+ drvOverlayObjectInit(&sb2_root_overlay_driver, (vfs_driver_c *)&fatfs_driver, "sb2");
+ ret = drvOverlayRegisterDriver(&sb1_root_overlay_driver,
+ drvStreamsObjectInit(&sb1_dev_driver, &sb1_streams[0]),
"dev");
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
+ ret = drvOverlayRegisterDriver(&sb2_root_overlay_driver,
+ drvStreamsObjectInit(&sb2_dev_driver, &sb2_streams[0]),
+ "dev");
+ if (CH_RET_IS_ERROR(ret)) {
+ chSysHalt("VFS");
+ }
+
+ /*
+ * Initializing overlay driver for the directory shared among the sandboxes.
+ * It is seen as "/shared".
+ */
+ drvOverlayObjectInit(&sb_shared_overlay_driver, (vfs_driver_c *)&fatfs_driver, "shared");
+ ret = drvOverlayRegisterDriver(&sb1_root_overlay_driver,
+ (vfs_driver_c *)&sb_shared_overlay_driver,
+ "shared");
+ if (CH_RET_IS_ERROR(ret)) {
+ chSysHalt("VFS");
+ }
+ ret = drvOverlayRegisterDriver(&sb2_root_overlay_driver,
+ (vfs_driver_c *)&sb_shared_overlay_driver,
+ "shared");
+ if (CH_RET_IS_ERROR(ret)) {
+ chSysHalt("VFS");
+ }
/*
* Sandbox objects initialization.
@@ -171,16 +245,26 @@ int main(void) {
sbObjectInit(&sbx2, &sb_config2);
/*
- * Associating standard input, output and error to sandboxes. Both sandboxes
- * use the same serial port in this setup.
+ * Associating standard input, output and error to sandbox 1.
*/
- ret = vfsOpenFile("/dev/VSD1", 0, &fnp);
+ ret = vfsDrvOpenFile((vfs_driver_c *)&sb1_root_overlay_driver,
+ "/dev/VSD1", 0, &fnp);
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
+ vfsCloseFile(fnp);
+
+ /*
+ * Associating standard input, output and error to sandbox 1.
+ */
+ ret = vfsDrvOpenFile((vfs_driver_c *)&sb2_root_overlay_driver,
+ "/dev/VSD1", 0, &fnp);
+ if (CH_RET_IS_ERROR(ret)) {
+ chSysHalt("VFS");
+ }
sbPosixRegisterFileDescriptor(&sbx2, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
@@ -188,20 +272,24 @@ int main(void) {
/*
* Creating **static** boxes using MPU.
- * Note: The two regions cover both sandbox 1 and 2, there is no
- * isolation among them.
*/
mpuConfigureRegion(MPU_REGION_0,
- 0x08070000U,
+ 0x08180000,
MPU_RASR_ATTR_AP_RO_RO |
MPU_RASR_ATTR_CACHEABLE_WT_NWA |
- MPU_RASR_SIZE_64K |
+ MPU_RASR_SIZE_512K |
MPU_RASR_ENABLE);
mpuConfigureRegion(MPU_REGION_1,
- 0x2001E000U,
+ 0x20060000,
MPU_RASR_ATTR_AP_RW_RW |
MPU_RASR_ATTR_CACHEABLE_WB_WA |
- MPU_RASR_SIZE_8K |
+ MPU_RASR_SIZE_128K |
+ MPU_RASR_ENABLE);
+ mpuConfigureRegion(MPU_REGION_2,
+ 0x20080000,
+ MPU_RASR_ATTR_AP_RW_RW |
+ MPU_RASR_ATTR_CACHEABLE_WB_WA |
+ MPU_RASR_SIZE_128K |
MPU_RASR_ENABLE);
/* Starting sandboxed thread 1.*/
@@ -223,13 +311,16 @@ int main(void) {
/*
* Listening to sandbox events.
*/
- chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
+ chEvtRegister(&sdmon_inserted_event, &el0, (eventid_t)0);
+ chEvtRegister(&sdmon_removed_event, &el1, (eventid_t)1);
+ chEvtRegister(&sb.termination_es, &el2, (eventid_t)2);
/*
* Normal main() thread activity, in this demo it monitors the user button
* and checks for sandboxes state.
*/
while (true) {
+ chEvtDispatch(evhndl, chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)));
/* Checking for user button, launching test suite if pressed.*/
if (palReadLine(LINE_BUTTON)) {
@@ -237,18 +328,7 @@ int main(void) {
test_execute((BaseSequentialStream *)&SD2, &oslib_test_suite);
}
- /* Waiting for a sandbox event or timeout.*/
- if (chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)) != (eventmask_t)0) {
-
- if (chThdTerminatedX(utp1)) {
- chprintf((BaseSequentialStream *)&SD2, "SB1 terminated\r\n");
- }
-
- if (chThdTerminatedX(utp2)) {
- chprintf((BaseSequentialStream *)&SD2, "SB2 terminated\r\n");
- }
- }
-
+#if 0
if ((i & 1) == 0U) {
if (!chThdTerminatedX(utp1)) {
(void) sbSendMessageTimeout(&sbx1, (msg_t)i, TIME_MS2I(10));
@@ -260,5 +340,6 @@ int main(void) {
}
}
i++;
+#endif
}
}
diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/source/sdmon.c b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/source/sdmon.c
new file mode 100644
index 000000000..cc964f6f8
--- /dev/null
+++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/source/sdmon.c
@@ -0,0 +1,147 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include "ch.h"
+#include "hal.h"
+#include "vfs.h"
+
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
+#define POLLING_INTERVAL 10
+#define POLLING_DELAY 10
+
+/*===========================================================================*/
+/* Module exported variables. */
+/*===========================================================================*/
+
+event_source_t sdmon_inserted_event, sdmon_removed_event;
+bool sdmon_ready;
+
+/*===========================================================================*/
+/* Module local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local variables. */
+/*===========================================================================*/
+
+static virtual_timer_t tmr;
+static unsigned cnt;
+
+/*===========================================================================*/
+/* Module local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Insertion monitor timer callback function.
+ *
+ * @param[in] p pointer to the @p BaseBlockDevice object
+ *
+ * @notapi
+ */
+static void tmrfunc(virtual_timer_t *vtp, void *p) {
+ BaseBlockDevice *bbdp = p;
+
+ chSysLockFromISR();
+
+ if (cnt > 0) {
+ if (blkIsInserted(bbdp)) {
+ if (--cnt == 0) {
+ chEvtBroadcastI(&sdmon_inserted_event);
+ }
+ }
+ else
+ cnt = POLLING_INTERVAL;
+ }
+ else {
+ if (!blkIsInserted(bbdp)) {
+ cnt = POLLING_INTERVAL;
+ chEvtBroadcastI(&sdmon_removed_event);
+ }
+ }
+ chVTSetI(vtp, TIME_MS2I(POLLING_DELAY), tmrfunc, bbdp);
+
+ chSysUnlockFromISR();
+}
+
+/*===========================================================================*/
+/* Module exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Polling monitor start.
+ *
+ * @notapi
+ */
+void sdmonInit(void) {
+
+ /* Activates the SDC driver using default configuration.*/
+ sdcStart(&SDCD1, NULL);
+
+ chEvtObjectInit(&sdmon_inserted_event);
+ chEvtObjectInit(&sdmon_removed_event);
+
+ sdmon_ready = false;
+ cnt = POLLING_INTERVAL;
+ chVTSet(&tmr, TIME_MS2I(POLLING_DELAY), tmrfunc, (void *)&SDCD1);
+}
+
+/*
+ * Card insertion event.
+ */
+void sdmonInsertHandler(eventid_t id) {
+ msg_t err;
+
+ (void)id;
+
+#if HAL_USE_SDC
+ if (sdcConnect(&SDCD1)) {
+ return;
+ }
+#else
+ if (mmcConnect(&MMCD1)) {
+ return;
+ }
+#endif
+
+ err = drvFatFSMount("0:", 1);
+ if (CH_RET_IS_ERROR(err)) {
+#if HAL_USE_SDC
+ sdcDisconnect(&SDCD1);
+#else
+ if (mmcDisconnect(&MMCD1)) {
+#endif
+ return;
+ }
+ sdmon_ready = true;
+}
+
+/*
+ * Card removal event.
+ */
+void sdmonRemoveHandler(eventid_t id) {
+
+ (void)id;
+
+#if HAL_USE_SDC
+ sdcDisconnect(&SDCD1);
+#else
+ mmcDisconnect(&MMCD1);
+#endif
+ sdmon_ready = false;
+}
diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/source/sdmon.h b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/source/sdmon.h
new file mode 100644
index 000000000..b22f16979
--- /dev/null
+++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/source/sdmon.h
@@ -0,0 +1,63 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef SDMON_H
+#define SDMON_H
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern event_source_t sdmon_inserted_event, sdmon_removed_event;
+extern bool sdmon_ready;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdmonInit(void);
+ void sdmonInsertHandler(eventid_t id);
+ void sdmonRemoveHandler(eventid_t id);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#endif /* SDMON_H */
+
+/** @} */
diff --git a/os/rt/src/chmsg.c b/os/rt/src/chmsg.c
index ad97c865b..ce6f38e15 100644
--- a/os/rt/src/chmsg.c
+++ b/os/rt/src/chmsg.c
@@ -47,6 +47,10 @@
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/