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

This commit is contained in:
Giovanni Di Sirio 2019-09-12 12:38:58 +00:00
parent 6de7825d13
commit 26b29a6925
7 changed files with 427 additions and 15 deletions

View File

@ -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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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