From 9c7d9ba26ed4f5296770bed7f1c23dc9757cbb2d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 13 Sep 2019 08:22:10 +0000 Subject: [PATCH] More API. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12982 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/rt/src/chthreads.c | 2 +- os/sb/host/sbapi.c | 36 +++++++++- os/sb/host/sbapi.h | 2 + os/sb/host/sbhost.c | 3 + os/sb/host/sbhost.h | 46 ++++++++++++ os/sb/user/sbuser.h | 158 +++++++++++++++++++++++++++++++++++++++++- 6 files changed, 243 insertions(+), 4 deletions(-) diff --git a/os/rt/src/chthreads.c b/os/rt/src/chthreads.c index a481cbc34..8af1a4ceb 100644 --- a/os/rt/src/chthreads.c +++ b/os/rt/src/chthreads.c @@ -682,7 +682,7 @@ void chThdSleepUntil(systime_t time) { /** * @brief Suspends the invoking thread until the system time arrives to the * specified value. - * @note The system time is assumed to be between @p prev and @p time + * @note The system time is assumed to be between @p prev and @p next * else the call is assumed to have been called outside the * allowed time interval, in this case no sleep is performed. * @see chThdSleepUntil() diff --git a/os/sb/host/sbapi.c b/os/sb/host/sbapi.c index 81b1ccfe6..153587de2 100644 --- a/os/sb/host/sbapi.c +++ b/os/sb/host/sbapi.c @@ -74,8 +74,11 @@ uint32_t sb_api_get_frequency(struct port_extctx *ctxp) { } uint32_t sb_api_sleep(struct port_extctx *ctxp) { + sysinterval_t interval = (sysinterval_t)ctxp->r0; - chThdSleep((sysinterval_t)ctxp->r0); + if (interval != TIME_IMMEDIATE) { + chThdSleep(interval); + } return SB_ERR_NOERROR; } @@ -88,6 +91,7 @@ uint32_t sb_api_sleep_until_windowed(struct port_extctx *ctxp) { } uint32_t sb_api_wait_message(struct port_extctx *ctxp) { +#if CH_CFG_USE_MESSAGES == TRUE sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; (void)ctxp; @@ -101,9 +105,13 @@ uint32_t sb_api_wait_message(struct port_extctx *ctxp) { sbcp->msg_tp = NULL; return SB_ERR_API_USAGE; } +#else + return SB_ERR_NOT_IMPLEMENTED; +#endif } uint32_t sb_api_reply_message(struct port_extctx *ctxp) { +#if CH_CFG_USE_MESSAGES == TRUE sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; if (sbcp->msg_tp != NULL) { @@ -114,24 +122,50 @@ uint32_t sb_api_reply_message(struct port_extctx *ctxp) { else { return SB_ERR_API_USAGE; } +#else + return SB_ERR_NOT_IMPLEMENTED; +#endif } uint32_t sb_api_wait_one_timeout(struct port_extctx *ctxp) { +#if CH_CFG_USE_EVENTS == TRUE return (uint32_t)chEvtWaitOneTimeout((eventmask_t)ctxp->r0, (sysinterval_t)ctxp->r1); +#else + return SB_ERR_NOT_IMPLEMENTED; +#endif } uint32_t sb_api_wait_any_timeout(struct port_extctx *ctxp) { +#if CH_CFG_USE_EVENTS == TRUE return (uint32_t)chEvtWaitAnyTimeout((eventmask_t)ctxp->r0, (sysinterval_t)ctxp->r1); +#else + return SB_ERR_NOT_IMPLEMENTED; +#endif } uint32_t sb_api_wait_all_timeout(struct port_extctx *ctxp) { +#if CH_CFG_USE_EVENTS == TRUE return (uint32_t)chEvtWaitAllTimeout((eventmask_t)ctxp->r0, (sysinterval_t)ctxp->r1); +#else + return SB_ERR_NOT_IMPLEMENTED; +#endif +} + +uint32_t sb_api_broadcast_flags(struct port_extctx *ctxp) { +#if CH_CFG_USE_EVENTS == TRUE + + chEvtBroadcastFlags((event_source_t *)ctxp->r0, + (eventflags_t)ctxp->r1); + return SB_ERR_NOERROR; +#else + return SB_ERR_NOT_IMPLEMENTED; +#endif } /** @} */ diff --git a/os/sb/host/sbapi.h b/os/sb/host/sbapi.h index 8b07a6130..b1dd70baf 100644 --- a/os/sb/host/sbapi.h +++ b/os/sb/host/sbapi.h @@ -42,6 +42,7 @@ #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 +#define SB_SVC11_HANDLER sb_api_broadcast_flags /*===========================================================================*/ /* Module pre-compile time settings. */ @@ -84,6 +85,7 @@ extern "C" { 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); + uint32_t sb_api_broadcast_flags(struct port_extctx *ctxp); #ifdef __cplusplus } #endif diff --git a/os/sb/host/sbhost.c b/os/sb/host/sbhost.c index 079f25512..16f28f535 100644 --- a/os/sb/host/sbhost.c +++ b/os/sb/host/sbhost.c @@ -143,6 +143,9 @@ void sbObjectInit(sb_class_t *sbcp) { #if CH_CFG_USE_MESSAGES == TRUE sbcp->msg_tp = NULL; #endif +#if CH_CFG_USE_EVENTS == TRUE + chEvtObjectInit(sbcp->esp); +#endif } /** diff --git a/os/sb/host/sbhost.h b/os/sb/host/sbhost.h index 6da29cb40..63c9b5766 100644 --- a/os/sb/host/sbhost.h +++ b/os/sb/host/sbhost.h @@ -118,6 +118,9 @@ typedef struct { */ thread_t *msg_tp; #endif +#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) + event_source_t *esp; +#endif } sb_class_t; /** @@ -956,6 +959,7 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ +#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) /** * @brief Sends a message to a sandboxed thread. * @@ -970,6 +974,48 @@ static inline msg_t sbSendMessage(sb_class_t *sbcp, msg_t msg) { return chMsgSend(sbcp->tp, msg); } +#endif /* CH_CFG_USE_MESSAGES == TRUE */ + +#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) +/** + * @brief Adds a set of event flags directly to the specified sandbox. + * + * @param[in] sbcp pointer to the sandbox object + * @param[in] events the events set to be ORed + * + * @iclass + */ +static inline void sbEvtSignalI(sb_class_t *sbcp, eventmask_t events) { + + chEvtSignalI(sbcp->tp, events); +} + +/** + * @brief Adds a set of event flags directly to the specified sandbox. + * + * @param[in] sbcp pointer to the sandbox object + * @param[in] events the events set to be ORed + * + * @api + */ +static inline void sbEvtSignal(sb_class_t *sbcp, eventmask_t events) { + + chEvtSignal(sbcp->tp, events); +} + +/** + * @brief Returns the sandbox event source object. + * + * @param[in] sbcp pointer to the sandbox object + * @return The pointer to the event source object. + * + * @xclass + */ +static inline event_source_t *sbGetEventSourceX(sb_class_t *sbcp) { + + return sbcp->esp; +} +#endif /* CH_CFG_USE_EVENTS == TRUE */ #endif /* SBHOST_H */ diff --git a/os/sb/user/sbuser.h b/os/sb/user/sbuser.h index e616bc43d..d09730623 100644 --- a/os/sb/user/sbuser.h +++ b/os/sb/user/sbuser.h @@ -94,6 +94,11 @@ typedef uint32_t msg_t; */ typedef uint32_t eventmask_t; +/** + * @brief Type of event flags. + */ +typedef uint32_t eventflags_t; + /** * @brief Type of a sandbox API internal state variables. */ @@ -189,45 +194,116 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ +/** + * @brief Terminates the sandbox. + * + * @param[in] msg The exit message. + * + * @api + */ static inline void sbExit(msg_t msg) { __syscall1r(1, msg); } +/** + * @brief Returns the system time. + * + * @return The current system time. + */ static inline systime_t sbGetSystemTime(void) { __syscall0r(2); return (systime_t)r0; } +/** + * @brief Returns the system time frequency. + * + * @return The system time frequency. + */ static inline uint32_t sbGetFrequency(void) { __syscall0r(3); return (uint32_t)r0; } +/** + * @brief Suspends the invoking thread for the specified interval. + * + * @param[in] interval the delay in system ticks + * + * @api + */ static inline void sbSleep(sysinterval_t interval) { __syscall1r(4, interval); } -static inline void sbSleepUntil(systime_t start, systime_t end) { +/** + * @brief Suspends the invoking thread until the system time arrives to the + * specified value. + * @note The system time is assumed to be between @p start and @p next + * else the call is assumed to have been called outside the + * allowed time interval, in this case no sleep is performed. + * + * @param[in] prev absolute system time of the previous deadline + * @param[in] next absolute system time of the next deadline + * @return the @p next parameter + * + * @api + */ +static inline void sbSleepUntil(systime_t prev, systime_t next) { - __syscall2r(5, start, end); + __syscall2r(5, prev, next); } +/** + * @brief Waits for a message. + * + * @return The received message. + */ static inline msg_t sbMsgWait(void) { __syscall0r(6); return (uint32_t)r0; } +/** + * @brief Replies to a message. + * + * @param[in] msg the reply message + * + * @api + */ static inline uint32_t sbMsgReply(msg_t msg) { __syscall1r(7, msg); return (uint32_t)r0; } +/** + * @brief Waits for exactly one of the specified events. + * @details The function waits for one event among those specified in + * @p events to become pending then the event is cleared and returned. + * @note One and only one event is served in the function, the one with the + * lowest event id. The function is meant to be invoked into a loop + * in order to serve all the pending events.
+ * This means that Event Listeners with a lower event identifier have + * an higher priority. + * + * @param[in] events events that the function should wait + * for, @p ALL_EVENTS enables all the events + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The mask of the lowest event id served and cleared. + * @retval 0 if the operation has timed out. + * + * @api + */ static inline eventmask_t sbEventWaitOneTimeout(eventmask_t events, sysinterval_t timeout) { @@ -235,6 +311,24 @@ static inline eventmask_t sbEventWaitOneTimeout(eventmask_t events, return (uint32_t)r0; } +/** + * @brief Waits for any of the specified events. + * @details The function waits for any event among those specified in + * @p events to become pending then the events are cleared and + * returned. + * + * @param[in] events events that the function should wait + * for, @p ALL_EVENTS enables all the events + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The mask of the served and cleared events. + * @retval 0 if the operation has timed out. + * + * @api + */ static inline eventmask_t sbEventWaitAnyTimeout(eventmask_t events, sysinterval_t timeout) { @@ -242,6 +336,23 @@ static inline eventmask_t sbEventWaitAnyTimeout(eventmask_t events, return (uint32_t)r0; } +/** + * @brief Waits for all the specified events. + * @details The function waits for all the events specified in @p events to + * become pending then the events are cleared and returned. + * + * @param[in] events events that the function should wait + * for, @p ALL_EVENTS requires all the events + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The mask of the served and cleared events. + * @retval 0 if the operation has timed out. + * + * @api + */ static inline eventmask_t sbEventWaitAllTimeout(eventmask_t events, sysinterval_t timeout) { @@ -249,6 +360,20 @@ static inline eventmask_t sbEventWaitAllTimeout(eventmask_t events, return (uint32_t)r0; } +/** + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * + * @param[in] flags the flags set to be added to the listener flags mask + * + * @api + */ +static inline uint32_t sbEventBroadcastFlags(eventflags_t flags) { + + __syscall1r(11, flags); + return (uint32_t)r0; +} + /** * @brief Seconds to time interval. * @details Converts from seconds to system ticks number. @@ -429,16 +554,45 @@ static inline bool sbTimeIsInRangeX(systime_t time, systime_t start, systime_t e (systime_t)((systime_t)end - (systime_t)start)); } +/** + * @brief Delays the invoking thread for the specified number of seconds. + * @note The specified time is rounded up to a value allowed by the real + * system tick clock. + * + * @param[in] secs time in seconds + * + * @api + */ static inline void sbSleepSeconds(time_secs_t secs) { sbSleep(sbTimeS2I(secs)); } +/** + * @brief Delays the invoking thread for the specified number of + * milliseconds. + * @note The specified time is rounded up to a value allowed by the real + * system tick clock. + * + * @param[in] msecs time in milliseconds + * + * @api + */ static inline void sbSleepMilliseconds(time_msecs_t msecs) { sbSleep(sbTimeMS2I(msecs)); } +/** + * @brief Delays the invoking thread for the specified number of + * microseconds. + * @note The specified time is rounded up to a value allowed by the real + * system tick clock. + * + * @param[in] usecs time in microseconds + * + * @api + */ static inline void sbSleepMicroseconds(time_usecs_t usecs) { sbSleep(sbTimeUS2I(usecs));