diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/Makefile b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/Makefile index 893396059..5709ffb10 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/Makefile +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/Makefile @@ -113,6 +113,7 @@ include $(CHIBIOS)/tools/mk/autobuild.mk include $(CHIBIOS)/os/test/test.mk include $(CHIBIOS)/test/rt/rt_test.mk include $(CHIBIOS)/test/oslib/oslib_test.mk +include $(CHIBIOS)/os/hal/lib/streams/streams.mk # Define linker script file here LDSCRIPT= ./STM32G474xE_SB.ld diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c index 66de13a92..c89966ef0 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c @@ -17,6 +17,7 @@ #include "ch.h" #include "hal.h" #include "sb.h" +#include "chprintf.h" #include "rt_test_root.h" #include "oslib_test_root.h" @@ -72,10 +73,10 @@ static THD_FUNCTION(Thread1, arg) { while (true) { palClearLine(LINE_LED_GREEN); chThdSleepMilliseconds(500); - (void) sbSendMessage(&sbx1, (msg_t)i); + (void) sbSendMessageTimeout(&sbx1, (msg_t)i, TIME_MS2I(10)); palSetLine(LINE_LED_GREEN); chThdSleepMilliseconds(500); - (void) sbSendMessage(&sbx2, (msg_t)i); + (void) sbSendMessageTimeout(&sbx2, (msg_t)i, TIME_MS2I(10)); i++; } } @@ -84,7 +85,8 @@ static THD_FUNCTION(Thread1, arg) { * Application entry point. */ int main(void) { - thread_t *utp1; + thread_t *utp1, *utp2; + event_listener_t el1; /* * System initializations. @@ -92,9 +94,16 @@ int main(void) { * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. + * - SandBox manager initialization. */ halInit(); chSysInit(); + sbHostInit(); + + /* + * Listening to sandbox events. + */ + chEvtRegister(&sb.termination_es, &el1, (eventid_t)0); /* * Activates the Serial or SIO driver using the default configuration. @@ -134,7 +143,7 @@ int main(void) { } /* Starting sandboxed thread 2.*/ - utp1 = sbStartThread(&sbx2, &sb_config2, "sbx2", + utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2", waUnprivileged2, sizeof (waUnprivileged2), NORMALPRIO - 1); if (utp1 == NULL) { @@ -142,15 +151,28 @@ int main(void) { } /* - * Normal main() thread activity, in this demo it does nothing except - * sleeping in a loop and check the button state. + * Normal main() thread activity, in this demo it monitos the user button + * and checks for sandboxes state. */ while (true) { - if (palReadLine(LINE_BUTTON)) { + + /* Checking for user button, launching test suite if pressed.*/ + if (palReadLine(LINE_BUTTON)) { test_execute((BaseSequentialStream *)&LPSIOD1, &rt_test_suite); test_execute((BaseSequentialStream *)&LPSIOD1, &oslib_test_suite); } - chThdSleepMilliseconds(500); + + /* Waiting for a sandbox event or timeout.*/ + if (chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)) != (eventmask_t)0) { + + if (chThdTerminatedX(utp1)) { + chprintf((BaseSequentialStream *)&LPSIOD1, "SB1 terminated\r\n"); + } + + if (chThdTerminatedX(utp2)) { + chprintf((BaseSequentialStream *)&LPSIOD1, "SB2 terminated\r\n"); + } + } } } diff --git a/os/sb/host/compilers/GCC/sbexc.S b/os/sb/host/compilers/GCC/sbexc.S index a6b3be1dc..f38bfdfc9 100644 --- a/os/sb/host/compilers/GCC/sbexc.S +++ b/os/sb/host/compilers/GCC/sbexc.S @@ -149,7 +149,7 @@ UsageFault_Handler: /* Exception exit point.*/ .do_exit: - bl chThdExitS + bl __sb_abort .zombies2: b .zombies2 .align 2 diff --git a/os/sb/host/sbapi.c b/os/sb/host/sbapi.c index e36ce54a7..c0eddeec4 100644 --- a/os/sb/host/sbapi.c +++ b/os/sb/host/sbapi.c @@ -922,6 +922,14 @@ static void sb_undef_handler(struct port_extctx *ectxp) { /* Module exported functions. */ /*===========================================================================*/ +void __sb_abort(msg_t msg) { + +#if CH_CFG_USE_EVENTS == TRUE + chEvtBroadcastI(&sb.termination_es); +#endif + chThdExitS(msg); +} + void sb_api_stdio(struct port_extctx *ectxp) { switch (ectxp->r0) { @@ -955,7 +963,12 @@ void sb_api_stdio(struct port_extctx *ectxp) { void sb_api_exit(struct port_extctx *ectxp) { - chThdExit((msg_t )ectxp->r0); + chSysLock(); +#if CH_CFG_USE_EVENTS == TRUE + chEvtBroadcastI(&sb.termination_es); +#endif + chThdExitS((msg_t )ectxp->r0); + chSysUnlock(); /* Cannot get here.*/ ectxp->r0 = SB_ERR_ENOSYS; diff --git a/os/sb/host/sbhost.c b/os/sb/host/sbhost.c index 13c815806..48f3d28e0 100644 --- a/os/sb/host/sbhost.c +++ b/os/sb/host/sbhost.c @@ -36,6 +36,11 @@ /* Module exported variables. */ /*===========================================================================*/ +/** + * @brief Global sandbox managed state variable. + */ +sb_t sb; + /*===========================================================================*/ /* Module local types. */ /*===========================================================================*/ diff --git a/os/sb/host/sbhost.h b/os/sb/host/sbhost.h index 5a898752b..d46f68fee 100644 --- a/os/sb/host/sbhost.h +++ b/os/sb/host/sbhost.h @@ -55,6 +55,21 @@ /* Module data structures and types. */ /*===========================================================================*/ +/** + * @brief Type of a sandbox manager global structure. + */ +typedef struct { +#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) + /** + * @brief Event source for sandbox termination. + */ + event_source_t termination_es; +#endif +} sb_t; + +/** + * @brief Type of a sandbox memory region. + */ typedef struct { /** * @brief Memory range base. @@ -168,6 +183,8 @@ typedef struct { /* External declarations. */ /*===========================================================================*/ +extern sb_t sb; + #ifdef __cplusplus extern "C" { #endif @@ -190,6 +207,18 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ +/** + * @brief Initialization of the sandbox host. + * + * @init + */ +static inline void sbHostInit(void) { + +#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) + chEvtObjectInit(&sb.termination_es); +#endif +} + #if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__) /** * @brief Blocks the execution of the invoking thread until the sandbox