git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15288 27425a3e-05d8-49a3-a47f-9c15f0e5edd8

This commit is contained in:
Giovanni Di Sirio 2021-12-30 09:29:02 +00:00
parent d14f5f15e9
commit 325637c093
7 changed files with 344 additions and 44 deletions

View File

@ -29,6 +29,11 @@
<type>2</type> <type>2</type>
<locationURI>CHIBIOS/os/hal/boards/ST_NUCLEO64_G474RE</locationURI> <locationURI>CHIBIOS/os/hal/boards/ST_NUCLEO64_G474RE</locationURI>
</link> </link>
<link>
<name>fatfs</name>
<type>2</type>
<locationURI>CHIBIOS/ext/fatfs</locationURI>
</link>
<link> <link>
<name>os</name> <name>os</name>
<type>2</type> <type>2</type>

View File

@ -27,9 +27,9 @@ MEMORY
flash5 (rx) : org = 0x00000000, len = 0 flash5 (rx) : org = 0x00000000, len = 0
flash6 (rx) : org = 0x00000000, len = 0 flash6 (rx) : org = 0x00000000, len = 0
flash7 (rx) : org = 0x00000000, len = 0 flash7 (rx) : org = 0x00000000, len = 0
ram0 (wx) : org = 0x20000000, len = 640k - 384k /* Host data. */ ram0 (wx) : org = 0x20000000, len = 640k - 256k /* Host data. */
ram1 (wx) : org = 0x20040000, len = 192k /* Sandbox 1 data. */ ram1 (wx) : org = 0x20060000, len = 128k /* Sandbox 1 data. */
ram2 (wx) : org = 0x20070000, len = 192k /* Sandbox 2 data. */ ram2 (wx) : org = 0x20080000, len = 128k /* Sandbox 2 data. */
ram3 (wx) : org = 0x00000000, len = 0 ram3 (wx) : org = 0x00000000, len = 0
ram4 (wx) : org = 0x00000000, len = 0 ram4 (wx) : org = 0x00000000, len = 0
ram5 (wx) : org = 0x00000000, len = 0 ram5 (wx) : org = 0x00000000, len = 0

View File

@ -293,7 +293,7 @@
#define STM32_SERIAL_USE_USART3 FALSE #define STM32_SERIAL_USE_USART3 FALSE
#define STM32_SERIAL_USE_UART4 FALSE #define STM32_SERIAL_USE_UART4 FALSE
#define STM32_SERIAL_USE_UART5 FALSE #define STM32_SERIAL_USE_UART5 FALSE
#define STM32_SERIAL_USE_LPUART1 FALSE #define STM32_SERIAL_USE_LPUART1 TRUE
/* /*
* SIO driver system settings. * SIO driver system settings.

View File

@ -26,33 +26,49 @@
#include "startup_defs.h" #include "startup_defs.h"
#include "sdmon.h"
/*===========================================================================*/ /*===========================================================================*/
/* VFS-related. */ /* VFS-related. */
/*===========================================================================*/ /*===========================================================================*/
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE #if VFS_CFG_ENABLE_DRV_FATFS == TRUE
/* VFS FatFS driver object representing the root directory.*/ /* VFS FatFS driver used by all file systems.*/
static vfs_fatfs_driver_c root_driver; static vfs_fatfs_driver_c fatfs_driver;
#endif #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; static vfs_overlay_driver_c root_overlay_driver;
/* VFS streams driver object representing the /dev directory.*/ /* Segregated roots for the two sandboxes.*/
static vfs_streams_driver_c dev_driver; 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 /* VFS API will use this object as implicit root, defining this
symbol is expected.*/ symbol is expected.*/
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver; vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
/* Used for /dev/null.*/
static NullStream nullstream; static NullStream nullstream;
/* Stream to be exposed under /dev as files.*/ /* Streams to be exposed under /dev as files.*/
static const drv_streams_element_t streams[] = { static const drv_streams_element_t sb1_streams[] = {
{"VSD1", (BaseSequentialStream *)&SD2}, {"VSD1", (BaseSequentialStream *)&SD2},
{"null", (BaseSequentialStream *)&nullstream}, {"null", (BaseSequentialStream *)&nullstream},
{NULL, NULL} {NULL, NULL}
}; };
static const drv_streams_element_t sb2_streams[] = {
{"VSD1", (BaseSequentialStream *)&LPSD1},
{"null", (BaseSequentialStream *)&nullstream},
{NULL, NULL}
};
/*===========================================================================*/ /*===========================================================================*/
/* SB-related. */ /* SB-related. */
@ -72,7 +88,7 @@ static const sb_config_t sb_config1 = {
.writeable = true .writeable = true
} }
}, },
.vfs_driver = (vfs_driver_c *)&root_overlay_driver .vfs_driver = (vfs_driver_c *)&sb1_root_overlay_driver
}; };
/* Sandbox 2 configuration.*/ /* Sandbox 2 configuration.*/
@ -89,7 +105,7 @@ static const sb_config_t sb_config2 = {
.writeable = true .writeable = true
} }
}, },
.vfs_driver = (vfs_driver_c *)&root_overlay_driver .vfs_driver = (vfs_driver_c *)&sb2_root_overlay_driver
}; };
/* Sandbox objects.*/ /* Sandbox objects.*/
@ -98,6 +114,8 @@ sb_class_t sbx1, sbx2;
static THD_WORKING_AREA(waUnprivileged1, 512); static THD_WORKING_AREA(waUnprivileged1, 512);
static THD_WORKING_AREA(waUnprivileged2, 512); static THD_WORKING_AREA(waUnprivileged2, 512);
static thread_t *utp1, *utp2;
/*===========================================================================*/ /*===========================================================================*/
/* Main and generic code. */ /* 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. * Application entry point.
*/ */
int main(void) { int main(void) {
unsigned i = 1U; event_listener_t el0, el1, el2;
thread_t *utp1, *utp2;
event_listener_t el1;
vfs_file_node_c *fnp; vfs_file_node_c *fnp;
msg_t ret; msg_t ret;
static const evhandler_t evhndl[] = {
sdmonInsertHandler,
sdmonRemoveHandler,
SBHandler
};
/* /*
* System initializations. * System initializations.
@ -142,27 +179,64 @@ int main(void) {
sbHostInit(); 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(&SD2, NULL);
sdStart(&LPSD1, NULL);
nullObjectInit(&nullstream); nullObjectInit(&nullstream);
/*
* Activates the card insertion monitor.
*/
sdmonInit();
/* /*
* Creating a blinker thread. * Creating a blinker thread.
*/ */
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL); chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
/* /*
* Initializing an overlay VFS object as a root, no overlaid driver, * Initializing an overlay VFS object as a root on top of a FatFS driver.
* registering a streams VFS driver on the VFS overlay root as "/dev". * This is accessible from kernel space and covers the whole file system.
*/ */
drvOverlayObjectInit(&root_overlay_driver, NULL, NULL); drvOverlayObjectInit(&root_overlay_driver, (vfs_driver_c *)&fatfs_driver, NULL);
ret = drvOverlayRegisterDriver(&root_overlay_driver,
drvStreamsObjectInit(&dev_driver, &streams[0]), /*
* 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"); "dev");
if (CH_RET_IS_ERROR(ret)) { if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS"); 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. * Sandbox objects initialization.
@ -171,16 +245,26 @@ int main(void) {
sbObjectInit(&sbx2, &sb_config2); sbObjectInit(&sbx2, &sb_config2);
/* /*
* Associating standard input, output and error to sandboxes. Both sandboxes * Associating standard input, output and error to sandbox 1.
* use the same serial port in this setup.
*/ */
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)) { if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS"); chSysHalt("VFS");
} }
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp)); sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_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)); 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, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_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)); sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
@ -188,20 +272,24 @@ int main(void) {
/* /*
* Creating **static** boxes using MPU. * 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, mpuConfigureRegion(MPU_REGION_0,
0x08070000U, 0x08180000,
MPU_RASR_ATTR_AP_RO_RO | MPU_RASR_ATTR_AP_RO_RO |
MPU_RASR_ATTR_CACHEABLE_WT_NWA | MPU_RASR_ATTR_CACHEABLE_WT_NWA |
MPU_RASR_SIZE_64K | MPU_RASR_SIZE_512K |
MPU_RASR_ENABLE); MPU_RASR_ENABLE);
mpuConfigureRegion(MPU_REGION_1, mpuConfigureRegion(MPU_REGION_1,
0x2001E000U, 0x20060000,
MPU_RASR_ATTR_AP_RW_RW | MPU_RASR_ATTR_AP_RW_RW |
MPU_RASR_ATTR_CACHEABLE_WB_WA | 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); MPU_RASR_ENABLE);
/* Starting sandboxed thread 1.*/ /* Starting sandboxed thread 1.*/
@ -223,13 +311,16 @@ int main(void) {
/* /*
* Listening to sandbox events. * 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 * Normal main() thread activity, in this demo it monitors the user button
* and checks for sandboxes state. * and checks for sandboxes state.
*/ */
while (true) { while (true) {
chEvtDispatch(evhndl, chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)));
/* Checking for user button, launching test suite if pressed.*/ /* Checking for user button, launching test suite if pressed.*/
if (palReadLine(LINE_BUTTON)) { if (palReadLine(LINE_BUTTON)) {
@ -237,18 +328,7 @@ int main(void) {
test_execute((BaseSequentialStream *)&SD2, &oslib_test_suite); test_execute((BaseSequentialStream *)&SD2, &oslib_test_suite);
} }
/* Waiting for a sandbox event or timeout.*/ #if 0
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 ((i & 1) == 0U) { if ((i & 1) == 0U) {
if (!chThdTerminatedX(utp1)) { if (!chThdTerminatedX(utp1)) {
(void) sbSendMessageTimeout(&sbx1, (msg_t)i, TIME_MS2I(10)); (void) sbSendMessageTimeout(&sbx1, (msg_t)i, TIME_MS2I(10));
@ -260,5 +340,6 @@ int main(void) {
} }
} }
i++; i++;
#endif
} }
} }

View File

@ -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;
}

View File

@ -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 */
/** @} */

View File

@ -47,6 +47,10 @@
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/*===========================================================================*/ /*===========================================================================*/
/* Module exported variables. */ /* Module exported variables. */
/*===========================================================================*/ /*===========================================================================*/