git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12981 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
6de7825d13
commit
26b29a6925
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue