From 26b29a69250ee66c14cee6ea584511d28b37135e Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 12 Sep 2019 12:38:58 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12981 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../RT-STM32L476-DISCOVERY-SB_CLIENT/main.c | 3 + os/sb/host/sbapi.c | 49 ++- os/sb/host/sbapi.h | 11 +- os/sb/host/sbhost.c | 13 +- os/sb/host/sbhost.h | 24 +- os/sb/user/sbuser.c | 16 + os/sb/user/sbuser.h | 326 +++++++++++++++++- 7 files changed, 427 insertions(+), 15 deletions(-) diff --git a/demos/STM32/RT-STM32L476-DISCOVERY-SB_CLIENT/main.c b/demos/STM32/RT-STM32L476-DISCOVERY-SB_CLIENT/main.c index 4cc040435..6b6aa87fb 100644 --- a/demos/STM32/RT-STM32L476-DISCOVERY-SB_CLIENT/main.c +++ b/demos/STM32/RT-STM32L476-DISCOVERY-SB_CLIENT/main.c @@ -24,6 +24,9 @@ */ int main(void) { + /* API layer initialization.*/ + sbApiInit(); + /* * Normal main() activity, in this demo it does nothing except * sleeping in a loop. diff --git a/os/sb/host/sbapi.c b/os/sb/host/sbapi.c index 51a5d3e35..81b1ccfe6 100644 --- a/os/sb/host/sbapi.c +++ b/os/sb/host/sbapi.c @@ -75,7 +75,7 @@ uint32_t sb_api_get_frequency(struct port_extctx *ctxp) { uint32_t sb_api_sleep(struct port_extctx *ctxp) { - chThdSleepMilliseconds((sysinterval_t)ctxp->r0); + chThdSleep((sysinterval_t)ctxp->r0); return SB_ERR_NOERROR; } @@ -87,4 +87,51 @@ uint32_t sb_api_sleep_until_windowed(struct port_extctx *ctxp) { return SB_ERR_NOERROR; } +uint32_t sb_api_wait_message(struct port_extctx *ctxp) { + sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; + + (void)ctxp; + + if (sbcp->msg_tp == NULL) { + sbcp->msg_tp = chMsgWait(); + return (uint32_t)chMsgGet(sbcp->msg_tp); + } + else { + chMsgRelease(sbcp->msg_tp, MSG_RESET); + sbcp->msg_tp = NULL; + return SB_ERR_API_USAGE; + } +} + +uint32_t sb_api_reply_message(struct port_extctx *ctxp) { + sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; + + if (sbcp->msg_tp != NULL) { + chMsgRelease(sbcp->msg_tp, (msg_t)ctxp->r0); + sbcp->msg_tp = NULL; + return SB_ERR_API_USAGE; + } + else { + return SB_ERR_API_USAGE; + } +} + +uint32_t sb_api_wait_one_timeout(struct port_extctx *ctxp) { + + return (uint32_t)chEvtWaitOneTimeout((eventmask_t)ctxp->r0, + (sysinterval_t)ctxp->r1); +} + +uint32_t sb_api_wait_any_timeout(struct port_extctx *ctxp) { + + return (uint32_t)chEvtWaitAnyTimeout((eventmask_t)ctxp->r0, + (sysinterval_t)ctxp->r1); +} + +uint32_t sb_api_wait_all_timeout(struct port_extctx *ctxp) { + + return (uint32_t)chEvtWaitAllTimeout((eventmask_t)ctxp->r0, + (sysinterval_t)ctxp->r1); +} + /** @} */ diff --git a/os/sb/host/sbapi.h b/os/sb/host/sbapi.h index f485ba2e5..8b07a6130 100644 --- a/os/sb/host/sbapi.h +++ b/os/sb/host/sbapi.h @@ -37,6 +37,11 @@ #define SB_SVC3_HANDLER sb_api_get_frequency #define SB_SVC4_HANDLER sb_api_sleep #define SB_SVC5_HANDLER sb_api_sleep_until_windowed +#define SB_SVC6_HANDLER sb_api_wait_message +#define SB_SVC7_HANDLER sb_api_reply_message +#define SB_SVC8_HANDLER sb_api_wait_one_timeout +#define SB_SVC9_HANDLER sb_api_wait_any_timeout +#define SB_SVC10_HANDLER sb_api_wait_all_timeout /*===========================================================================*/ /* Module pre-compile time settings. */ @@ -62,7 +67,6 @@ /* Module macros. */ /*===========================================================================*/ - /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -75,6 +79,11 @@ extern "C" { uint32_t sb_api_get_frequency(struct port_extctx *ctxp); uint32_t sb_api_sleep(struct port_extctx *ctxp); uint32_t sb_api_sleep_until_windowed(struct port_extctx *ctxp); + uint32_t sb_api_wait_message(struct port_extctx *ctxp); + uint32_t sb_api_reply_message(struct port_extctx *ctxp); + uint32_t sb_api_wait_one_timeout(struct port_extctx *ctxp); + uint32_t sb_api_wait_any_timeout(struct port_extctx *ctxp); + uint32_t sb_api_wait_all_timeout(struct port_extctx *ctxp); #ifdef __cplusplus } #endif diff --git a/os/sb/host/sbhost.c b/os/sb/host/sbhost.c index a53aa03db..079f25512 100644 --- a/os/sb/host/sbhost.c +++ b/os/sb/host/sbhost.c @@ -131,20 +131,29 @@ uint32_t sb_undef_handler(struct port_extctx *ectxp) { /** * @brief Sandbox object initialization. + * + * @param[out] sbcp pointer to the sandbox object + * + * @init */ void sbObjectInit(sb_class_t *sbcp) { sbcp->config = NULL; sbcp->tp = NULL; +#if CH_CFG_USE_MESSAGES == TRUE + sbcp->msg_tp = NULL; +#endif } /** * @brief Starts a sandboxed thread. * - * @param[in] sbcp pointer to the sandbox configuration structure + * @param[in] sbcp pointer to the sandbox object * @return The function returns only if the operation failed. + * + * @api */ -void sbStart(sb_class_t * sbcp, const sb_config_t *config) { +void sbStart(sb_class_t *sbcp, const sb_config_t *config) { uint32_t pc, psp; const sb_header_t *sbhp; diff --git a/os/sb/host/sbhost.h b/os/sb/host/sbhost.h index d41f5a17b..6da29cb40 100644 --- a/os/sb/host/sbhost.h +++ b/os/sb/host/sbhost.h @@ -46,12 +46,13 @@ /** @} */ /** - * @brief Sandbox error codes + * @brief Sandbox API error codes * @{ */ #define SB_ERR_NOERROR 0U #define SB_ERR_NOT_IMPLEMENTED 0xFFFFFFFFU #define SB_ERR_MEMORY_FAULT 0xFFFFFFFEU +#define SB_ERR_API_USAGE 0xFFFFFFFDU /** @} */ /*===========================================================================*/ @@ -111,6 +112,12 @@ typedef struct { * @brief Thread running in the sandbox. */ thread_t *tp; +#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) + /** + * @brief Thread sending a message to the sandbox. + */ + thread_t *msg_tp; +#endif } sb_class_t; /** @@ -949,6 +956,21 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ +/** + * @brief Sends a message to a sandboxed thread. + * + * @param[in] sbcp pointer to the sandbox object + * @param[in] msg message to be sent + * @return The returned message. + * @retval MSG_RESET Sandboxed thread API usage error, exchange aborted. + * + * @api + */ +static inline msg_t sbSendMessage(sb_class_t *sbcp, msg_t msg) { + + return chMsgSend(sbcp->tp, msg); +} + #endif /* SBHOST_H */ /** @} */ diff --git a/os/sb/user/sbuser.c b/os/sb/user/sbuser.c index fc0dbc6de..0dc588234 100644 --- a/os/sb/user/sbuser.c +++ b/os/sb/user/sbuser.c @@ -38,6 +38,11 @@ /* Module exported variables. */ /*===========================================================================*/ +/** + * @brief Sandbox API internal state. + */ +sbapi_state_t sb; + /*===========================================================================*/ /* Module local types. */ /*===========================================================================*/ @@ -54,4 +59,15 @@ /* Module exported functions. */ /*===========================================================================*/ +/** + * @brief API layer initialization. + * @note To be called before any other call to the "sb" functions. + * + * @init + */ +void sbApiInit(void) { + + sb.frequency = sbGetFrequency(); +} + /** @} */ diff --git a/os/sb/user/sbuser.h b/os/sb/user/sbuser.h index b773fca25..e616bc43d 100644 --- a/os/sb/user/sbuser.h +++ b/os/sb/user/sbuser.h @@ -32,6 +32,16 @@ /* Module constants. */ /*===========================================================================*/ +/** + * @brief Sandbox API error codes + * @{ + */ +#define SB_ERR_NOERROR 0U +#define SB_ERR_NOT_IMPLEMENTED 0xFFFFFFFFU +#define SB_ERR_MEMORY_FAULT 0xFFFFFFFEU +#define SB_ERR_API_USAGE 0xFFFFFFFDU +/** @} */ + /*===========================================================================*/ /* Module pre-compile time settings. */ /*===========================================================================*/ @@ -47,20 +57,86 @@ /** * @brief Type of system time counter. */ -typedef uint32_t sb_systime_t; +typedef uint32_t systime_t; + +/** + * @brief Type of system time interval. + */ +typedef uint32_t sysinterval_t; + +/** + * @brief Type of a wide time conversion variable. + */ +typedef uint64_t time_conv_t; + +/** + * @brief Type of time in microseconds. + */ +typedef uint32_t time_usecs_t; + +/** + * @brief Type of time in milliseconds. + */ +typedef uint32_t time_msecs_t; + +/** + * @brief Type of time in seconds. + */ +typedef uint32_t time_secs_t; /** * @brief Type of a message. */ -typedef uint32_t sb_msg_t; +typedef uint32_t msg_t; + +/** + * @brief Type of an event mask. + */ +typedef uint32_t eventmask_t; + +/** + * @brief Type of a sandbox API internal state variables. + */ +typedef struct { + /** + * @brief System tick frequency. + */ + time_conv_t frequency; +} sbapi_state_t; /*===========================================================================*/ /* Module macros. */ /*===========================================================================*/ +/** + * @name Messages-related macros + * @{ + */ +#define MSG_OK (msg_t)0 +#define MSG_TIMEOUT (msg_t)-1 +#define MSG_RESET (msg_t)-2 +/** @} */ + +/** + * @name Events-related macros + * @{ + */ +#define ALL_EVENTS ((eventmask_t)-1) +#define EVENT_MASK(eid) ((eventmask_t)1 << (eventmask_t)(eid)) +/** @} */ + +/** + * @name Time and intervals related macros + * @{ + */ +#define TIME_IMMEDIATE ((sysinterval_t)0) +#define TIME_INFINITE ((sysinterval_t)-1) +#define TIME_MAX_INTERVAL ((sysinterval_t)-2) +#define TIME_MAX_SYSTIME ((systime_t)-1) +/** @} */ + /** * @name SVC instruction wrappers. - * * @{ */ #define __syscall0(x) \ @@ -99,10 +175,12 @@ typedef uint32_t sb_msg_t; /* External declarations. */ /*===========================================================================*/ +extern sbapi_state_t sb; + #ifdef __cplusplus extern "C" { #endif - + void sbApiInit(void); #ifdef __cplusplus } #endif @@ -111,15 +189,15 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ -static inline void sbExit(sb_msg_t msg) { +static inline void sbExit(msg_t msg) { __syscall1r(1, msg); } -static inline sb_systime_t sbGetSystemTime(void) { +static inline systime_t sbGetSystemTime(void) { __syscall0r(2); - return (sb_systime_t)r0; + return (systime_t)r0; } static inline uint32_t sbGetFrequency(void) { @@ -128,16 +206,244 @@ static inline uint32_t sbGetFrequency(void) { return (uint32_t)r0; } -static inline void sbSleepMilliseconds(uint32_t milliseconds) { +static inline void sbSleep(sysinterval_t interval) { - __syscall1r(4, milliseconds); + __syscall1r(4, interval); } -static inline void sbSleepUntil(sb_systime_t start, sb_systime_t end) { +static inline void sbSleepUntil(systime_t start, systime_t end) { __syscall2r(5, start, end); } +static inline msg_t sbMsgWait(void) { + + __syscall0r(6); + return (uint32_t)r0; +} + +static inline uint32_t sbMsgReply(msg_t msg) { + + __syscall1r(7, msg); + return (uint32_t)r0; +} + +static inline eventmask_t sbEventWaitOneTimeout(eventmask_t events, + sysinterval_t timeout) { + + __syscall2r(8, events, timeout); + return (uint32_t)r0; +} + +static inline eventmask_t sbEventWaitAnyTimeout(eventmask_t events, + sysinterval_t timeout) { + + __syscall2r(9, events, timeout); + return (uint32_t)r0; +} + +static inline eventmask_t sbEventWaitAllTimeout(eventmask_t events, + sysinterval_t timeout) { + + __syscall2r(10, events, timeout); + return (uint32_t)r0; +} + +/** + * @brief Seconds to time interval. + * @details Converts from seconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + * + * @param[in] secs number of seconds + * @return The number of ticks. + * + * @special + */ +static inline sysinterval_t sbTimeS2I(time_secs_t secs) { + time_conv_t ticks; + + ticks = (time_conv_t)secs * sb.frequency; + +/* sbDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, + "conversion overflow");*/ + + return (sysinterval_t)ticks; +} + +/** + * @brief Milliseconds to time interval. + * @details Converts from milliseconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + * + * @param[in] msec number of milliseconds + * @return The number of ticks. + * + * @special + */ +static inline sysinterval_t sbTimeMS2I(time_msecs_t msec) { + time_conv_t ticks; + + ticks = (((time_conv_t)msec * sb.frequency) + + (time_conv_t)999) / (time_conv_t)1000; + +/* chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, + "conversion overflow");*/ + + return (sysinterval_t)ticks; +} + +/** + * @brief Microseconds to time interval. + * @details Converts from microseconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + * + * @param[in] usec number of microseconds + * @return The number of ticks. + * + * @special + */ +static inline sysinterval_t sbTimeUS2I(time_usecs_t usec) { + time_conv_t ticks; + + ticks = (((time_conv_t)usec * sb.frequency) + + (time_conv_t)999999) / (time_conv_t)1000000; + +/* chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, + "conversion overflow");*/ + + return (sysinterval_t)ticks; +} + +/** + * @brief Time interval to seconds. + * @details Converts from system interval to seconds. + * @note The result is rounded up to the next second boundary. + * + * @param[in] interval interval in ticks + * @return The number of seconds. + * + * @special + */ +static inline time_secs_t sbTimeI2S(sysinterval_t interval) { + time_conv_t secs; + + secs = ((time_conv_t)interval + + sb.frequency - + (time_conv_t)1) / sb.frequency; + +/* sbDbgAssert(secs < (time_conv_t)((time_secs_t)-1), + "conversion overflow");*/ + + return (time_secs_t)secs; +} + +/** + * @brief Time interval to milliseconds. + * @details Converts from system interval to milliseconds. + * @note The result is rounded up to the next millisecond boundary. + * + * @param[in] interval interval in ticks + * @return The number of milliseconds. + * + * @special + */ +static inline time_msecs_t sbTimeI2MS(sysinterval_t interval) { + time_conv_t msecs; + + msecs = (((time_conv_t)interval * (time_conv_t)1000) + + sb.frequency - (time_conv_t)1) / + sb.frequency; + +/* sbDbgAssert(msecs < (time_conv_t)((time_msecs_t)-1), + "conversion overflow");*/ + + return (time_msecs_t)msecs; +} + +/** + * @brief Time interval to microseconds. + * @details Converts from system interval to microseconds. + * @note The result is rounded up to the next microsecond boundary. + * + * @param[in] interval interval in ticks + * @return The number of microseconds. + * + * @special + */ +static inline time_usecs_t sbTimeI2US(sysinterval_t interval) { + time_conv_t usecs; + + usecs = (((time_conv_t)interval * (time_conv_t)1000000) + + sb.frequency - (time_conv_t)1) / sb.frequency; + +/* sbDbgAssert(usecs <= (time_conv_t)((time_usecs_t)-1), + "conversion overflow");*/ + + return (time_usecs_t)usecs; +} + +/** + * @brief Adds an interval to a system time returning a system time. + * + * @param[in] systime base system time + * @param[in] interval interval to be added + * @return The new system time. + * + * @xclass + */ +static inline systime_t sbTimeAddX(systime_t systime, sysinterval_t interval) { + + return systime + (systime_t)interval; +} + +/** + * @brief Subtracts two system times returning an interval. + * + * @param[in] start first system time + * @param[in] end second system time + * @return The interval representing the time difference. + * + * @xclass + */ +static inline sysinterval_t sbTimeDiffX(systime_t start, systime_t end) { + + return (sysinterval_t)((systime_t)(end - start)); +} + +/** + * @brief Checks if the specified time is within the specified time range. + * @note When start==end then the function returns always true because the + * whole time range is specified. + * + * @param[in] time the time to be verified + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval true current time within the specified time window. + * @retval false current time not within the specified time window. + * + * @xclass + */ +static inline bool sbTimeIsInRangeX(systime_t time, systime_t start, systime_t end) { + + return (bool)((systime_t)((systime_t)time - (systime_t)start) < + (systime_t)((systime_t)end - (systime_t)start)); +} + +static inline void sbSleepSeconds(time_secs_t secs) { + + sbSleep(sbTimeS2I(secs)); +} + +static inline void sbSleepMilliseconds(time_msecs_t msecs) { + + sbSleep(sbTimeMS2I(msecs)); +} + +static inline void sbSleepMicroseconds(time_usecs_t usecs) { + + sbSleep(sbTimeUS2I(usecs)); +} + #endif /* SBUSER_H */ /** @} */