aboutsummaryrefslogtreecommitdiffstats
path: root/os/nil
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-09-03 13:21:10 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-09-03 13:21:10 +0000
commitfa8b45cc5be41840b99d4a5468108568f93513c1 (patch)
treee04eb67455a6ad3ec6450e1cc446339060b6d44a /os/nil
parented4c276d6e9abd145b2a21afb12d58df61876a97 (diff)
downloadChibiOS-fa8b45cc5be41840b99d4a5468108568f93513c1.tar.gz
ChibiOS-fa8b45cc5be41840b99d4a5468108568f93513c1.tar.bz2
ChibiOS-fa8b45cc5be41840b99d4a5468108568f93513c1.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6255 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/nil')
-rw-r--r--os/nil/include/nil.h305
-rw-r--r--os/nil/ports/ARMCMx/compilers/GCC/niltypes.h6
-rw-r--r--os/nil/ports/ARMCMx/nilcore.c15
-rw-r--r--os/nil/ports/ARMCMx/nilcore_v6m.c2
-rw-r--r--os/nil/ports/ARMCMx/nilcore_v6m.h19
-rw-r--r--os/nil/src/nil.c66
6 files changed, 222 insertions, 191 deletions
diff --git a/os/nil/include/nil.h b/os/nil/include/nil.h
index b98ea4ecf..6a831d880 100644
--- a/os/nil/include/nil.h
+++ b/os/nil/include/nil.h
@@ -43,39 +43,21 @@
*/
#define _NIL_ /**< @brief Nil RTOS identification.*/
-#define NIL_KERNEL_VERSION "0.0.1" /**< @brief Kernel version string. */
+#define NIL_KERNEL_VERSION "0.1.0alpha"
-#define NIL_KERNEL_MAJOR 0 /**< @brief Version major number. */
-#define NIL_KERNEL_MINOR 0 /**< @brief Version minor number. */
-#define NIL_KERNEL_PATCH 1 /**< @brief Version patch number. */
+#define NIL_KERNEL_MAJOR 0
+#define NIL_KERNEL_MINOR 1
+#define NIL_KERNEL_PATCH 0
/** @} */
/**
- * @name Common constants
- */
-/**
- * @brief Generic 'false' boolean constant.
- */
-#if !defined(FALSE) || defined(__DOXYGEN__)
-#define FALSE 0
-#endif
-
-/**
- * @brief Generic 'true' boolean constant.
- */
-#if !defined(TRUE) || defined(__DOXYGEN__)
-#define TRUE !FALSE
-#endif
-/** @} */
-
-/**
- * @name Wakeup status codes
+ * @name Wakeup messages
* @{
*/
-#define NIL_MSG_OK 0 /**< @brief Normal wakeup message. */
-#define NIL_MSG_TMO -1 /**< @brief Wake-up caused by a timeout
+#define MSG_OK 0 /**< @brief Normal wakeup message. */
+#define MSG_TIMEOUT -1 /**< @brief Wake-up caused by a timeout
condition. */
-#define NIL_MSG_RST -2 /**< @brief Wake-up caused by a reset
+#define MSG_RESET -2 /**< @brief Wake-up caused by a reset
condition. */
/** @} */
@@ -295,7 +277,7 @@ typedef struct {
* @note This field is only present if some debug options have been
* activated.
*/
- const char *dbg_msg;
+ const char *dbg_panic_msg;
#endif
} nil_system_t;
@@ -304,6 +286,11 @@ typedef struct {
/*===========================================================================*/
/**
+ * @brief String quotation macro.
+ */
+#define __NIL_QUOTE(p) #p
+
+/**
* @name Threads tables definition macros
* @{
*/
@@ -325,19 +312,154 @@ typedef struct {
#define NIL_THREADS_TABLE_END() \
{"idle", 0, NULL, NULL, 0} \
};
+/** @} */
+/**
+ * @name Working Areas and Alignment
+ */
+/**
+ * @brief Enforces a correct alignment for a stack area size value.
+ *
+ * @param[in] n the stack size to be aligned to the next stack
+ * alignment boundary
+ * @return The aligned stack size.
+ *
+ * @api
+ */
+#define THD_ALIGN_STACK_SIZE(n) \
+ ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
+
+/**
+ * @brief Calculates the total Working Area size.
+ *
+ * @param[in] n the stack size to be assigned to the thread
+ * @return The total used memory in bytes.
+ *
+ * @api
+ */
+#define THD_WORKING_AREA_SIZE(n) \
+ THD_ALIGN_STACK_SIZE(sizeof(thread_t) + PORT_WA_SIZE(n))
+
+/**
+ * @brief Static working area allocation.
+ * @details This macro is used to allocate a static thread working area
+ * aligned as both position and size.
+ *
+ * @param[in] s the name to be assigned to the stack array
+ * @param[in] n the stack size to be assigned to the thread
+ *
+ * @api
+ */
+#define THD_WORKING_AREA(s, n) \
+ stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof(stkalign_t)]
/** @} */
/**
- * @name Macro Functions
+ * @name Threads abstraction macros
+ */
+/**
+ * @brief Thread declaration macro.
+ * @note Thread declarations should be performed using this macro because
+ * the port layer could define optimizations for thread functions.
+ */
+#define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg)
+/** @} */
+
+/**
+ * @name ISRs abstraction macros
+ */
+/**
+ * @brief IRQ handler enter code.
+ * @note Usually IRQ handlers functions are also declared naked.
+ * @note On some architectures this macro can be empty.
+ *
+ * @special
+ */
+#define NIL_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE()
+
+/**
+ * @brief IRQ handler exit code.
+ * @note Usually IRQ handlers function are also declared naked.
+ *
+ * @special
+ */
+#define NIL_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE()
+
+/**
+ * @brief Standard normal IRQ handler declaration.
+ * @note @p id can be a function name or a vector number depending on the
+ * port implementation.
+ *
+ * @special
+ */
+#define NIL_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
+/** @} */
+
+/**
+ * @name Fast ISRs abstraction macros
+ */
+/**
+ * @brief Standard fast IRQ handler declaration.
+ * @note @p id can be a function name or a vector number depending on the
+ * port implementation.
+ * @note Not all architectures support fast interrupts.
+ *
+ * @special
+ */
+#define NIL_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
+/** @} */
+
+/**
+ * @name Time conversion utilities
* @{
*/
/**
- * @brief System halt state.
+ * @brief Seconds to system ticks.
+ * @details Converts from seconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] sec number of seconds
+ * @return The number of ticks.
+ *
+ * @api
*/
-#define nilSysHalt() port_halt()
+#define S2ST(sec) \
+ ((systime_t)((sec) * NIL_CFG_FREQUENCY))
/**
+ * @brief Milliseconds to system ticks.
+ * @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.
+ *
+ * @api
+ */
+#define MS2ST(msec) \
+ ((systime_t)(((((uint32_t)(msec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
+ 1000UL) + 1UL))
+
+/**
+ * @brief Microseconds to system ticks.
+ * @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.
+ *
+ * @api
+ */
+#define US2ST(usec) \
+ ((systime_t)(((((uint32_t)(usec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
+ 1000000UL) + 1UL))
+/** @} */
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
* @brief Enters the kernel lock mode.
*
* @special
@@ -525,139 +647,33 @@ typedef struct {
#define nilTimeIsWithin(time, start, end) \
((end) > (start) ? ((time) >= (start)) && ((time) < (end)) : \
((time) >= (start)) || ((time) < (end)))
-/** @} */
-
-/**
- * @name Threads abstraction macros
- */
-/**
- * @brief Thread declaration macro.
- * @note Thread declarations should be performed using this macro because
- * the port layer could define optimizations for thread functions.
- */
-#define NIL_THREAD(tname, arg) PORT_THREAD(tname, arg)
#if NIL_CFG_ENABLE_ASSERTS || defined(__DOXYGEN__)
/**
* @brief Condition assertion.
- * @details If the condition check fails then the kernel panics with the
- * specified message and halts.
+ * @details If the condition check fails then the kernel panics with a
+ * message and halts.
* @note The condition is tested only if the @p NIL_CFG_ENABLE_ASSERTS
- * switch is specified in @p nilconf.h else the macro does nothing.
- * @note The convention for the message is the following:<br>
- * @<function_name@>(), #@<assert_number@>
+ * switch is specified in @p chconf.h else the macro does nothing.
* @note The remark string is not currently used except for putting a
* comment in the code about the assertion.
*
* @param[in] c the condition to be verified to be true
- * @param[in] m the text message
* @param[in] r a remark string
*
* @api
*/
#if !defined(nilDbgAssert)
-#define nilDbgAssert(c, m, r) { \
- if (!(c)) { \
- nil.dbg_msg = (m); \
- nilSysHalt(); \
- } \
+#define nilDbgAssert(c, r) { \
+ if (!(c)) \
+ nilSysHalt("A:"__NIL_QUOTE(__FUNCTION__)":"__NIL_QUOTE(__LINE__)); \
}
-#endif /* !defined(chDbgAssert) */
+#endif /* !defined(nilDbgAssert) */
#else /* !NIL_CFG_ENABLE_ASSERTS */
-#define nilDbgAssert(c, m, r) {(void)(c);}
+#define nilDbgAssert(c, r) /*{(void)(c);}*/
#endif /* !NIL_CFG_ENABLE_ASSERTS */
/** @} */
-/**
- * @name ISRs abstraction macros
- */
-/**
- * @brief IRQ handler enter code.
- * @note Usually IRQ handlers functions are also declared naked.
- * @note On some architectures this macro can be empty.
- *
- * @special
- */
-#define NIL_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE()
-
-/**
- * @brief IRQ handler exit code.
- * @note Usually IRQ handlers function are also declared naked.
- *
- * @special
- */
-#define NIL_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE()
-
-/**
- * @brief Standard normal IRQ handler declaration.
- * @note @p id can be a function name or a vector number depending on the
- * port implementation.
- *
- * @special
- */
-#define NIL_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
-/** @} */
-
-/**
- * @name Fast ISRs abstraction macros
- */
-/**
- * @brief Standard fast IRQ handler declaration.
- * @note @p id can be a function name or a vector number depending on the
- * port implementation.
- * @note Not all architectures support fast interrupts.
- *
- * @special
- */
-#define NIL_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
-/** @} */
-
-/**
- * @name Time conversion utilities
- * @{
- */
-/**
- * @brief Seconds to system ticks.
- * @details Converts from seconds to system ticks number.
- * @note The result is rounded upward to the next tick boundary.
- *
- * @param[in] sec number of seconds
- * @return The number of ticks.
- *
- * @api
- */
-#define S2ST(sec) \
- ((systime_t)((sec) * NIL_CFG_FREQUENCY))
-
-/**
- * @brief Milliseconds to system ticks.
- * @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.
- *
- * @api
- */
-#define MS2ST(msec) \
- ((systime_t)(((((uint32_t)(msec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
- 1000UL) + 1UL))
-
-/**
- * @brief Microseconds to system ticks.
- * @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.
- *
- * @api
- */
-#define US2ST(usec) \
- ((systime_t)(((((uint32_t)(usec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
- 1000000UL) + 1UL))
-/** @} */
-
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -671,6 +687,7 @@ extern const thread_config_t nil_thd_configs[NIL_CFG_NUM_THREADS + 1];
extern "C" {
#endif
void nilSysInit(void);
+ void nilSysHalt(const char *reason);
void nilSysTimerHandlerI(void);
thread_ref_t nilSchReadyI(thread_ref_t trp, msg_t msg);
msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout);
diff --git a/os/nil/ports/ARMCMx/compilers/GCC/niltypes.h b/os/nil/ports/ARMCMx/compilers/GCC/niltypes.h
index 59cd42606..88dba58b8 100644
--- a/os/nil/ports/ARMCMx/compilers/GCC/niltypes.h
+++ b/os/nil/ports/ARMCMx/compilers/GCC/niltypes.h
@@ -71,6 +71,12 @@ typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
*/
#define NOINLINE __attribute__((noinline))
+/**
+ * @brief Thread function declaration macro optimized for GCC.
+ */
+#define PORT_THD_FUNCTION(tname, arg) \
+ __attribute__((noreturn)) void tname(void *arg)
+
#endif /* _NILTYPES_H_ */
/** @} */
diff --git a/os/nil/ports/ARMCMx/nilcore.c b/os/nil/ports/ARMCMx/nilcore.c
index e50dc5b80..58b86e76b 100644
--- a/os/nil/ports/ARMCMx/nilcore.c
+++ b/os/nil/ports/ARMCMx/nilcore.c
@@ -52,19 +52,4 @@
/* Module exported functions. */
/*===========================================================================*/
-/**
- * @brief Halts the system.
- * @note The function is declared as a weak symbol, it is possible
- * to redefine it in your application code.
- */
-#if !defined(__DOXYGEN__)
-__attribute__((naked, weak))
-#endif
-void port_halt(void) {
-
- port_disable();
- while (true) {
- }
-}
-
/** @} */
diff --git a/os/nil/ports/ARMCMx/nilcore_v6m.c b/os/nil/ports/ARMCMx/nilcore_v6m.c
index d8772ca54..19f1b9111 100644
--- a/os/nil/ports/ARMCMx/nilcore_v6m.c
+++ b/os/nil/ports/ARMCMx/nilcore_v6m.c
@@ -112,7 +112,7 @@ void _port_irq_epilogue(regarm_t lr) {
port_lock_from_isr();
/* The extctx structure is pointed by the PSP register.*/
- ctxp = (struct extctx *)__get_PSP();
+ ctxp = (struct port_extctx *)__get_PSP();
/* Adding an artificial exception return context, there is no need to
populate it fully.*/
diff --git a/os/nil/ports/ARMCMx/nilcore_v6m.h b/os/nil/ports/ARMCMx/nilcore_v6m.h
index 846378b65..3e3a7f14c 100644
--- a/os/nil/ports/ARMCMx/nilcore_v6m.h
+++ b/os/nil/ports/ARMCMx/nilcore_v6m.h
@@ -202,13 +202,13 @@ struct context {
* @details This code usually setup the context switching frame represented
* by an @p port_intctx structure.
*/
-#define PORT_SETUP_CONTEXT(workspace, wsize, pf, arg) { \
- tp->p_ctx.r13 = (struct port_intctx *)((uint8_t *)workspace + \
- wsize - \
- sizeof(struct port_intctx)); \
- tp->p_ctx.r13->r4 = (regarm_t)(pf); \
- tp->p_ctx.r13->r5 = (regarm_t)(arg); \
- tp->p_ctx.r13->lr = (regarm_t)(_port_thread_start); \
+#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
+ (tp)->ctxp = (struct port_intctx *)((uint8_t *)workspace + \
+ (size_t)wsize - \
+ sizeof(struct port_intctx)); \
+ (tp)->ctxp->r4 = (regarm_t)(pf); \
+ (tp)->ctxp->r5 = (regarm_t)(arg); \
+ (tp)->ctxp->lr = (regarm_t)(_port_thread_start); \
}
/**
@@ -270,8 +270,8 @@ struct context {
}
#endif
-#if CH_CFG_TIMEDELTA > 0
-#include "chcore_timer.h"
+#if NIL_CFG_TIMEDELTA > 0
+#include "nilcore_timer.h"
#endif
/*===========================================================================*/
@@ -281,7 +281,6 @@ struct context {
#ifdef __cplusplus
extern "C" {
#endif
- void port_halt(void);
void _port_irq_epilogue(regarm_t lr);
void _port_switch_from_isr(void);
void _port_exit_from_isr(void);
diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c
index da75ce1a9..b9b44e4c9 100644
--- a/os/nil/src/nil.c
+++ b/os/nil/src/nil.c
@@ -80,7 +80,7 @@ void nilSysInit(void) {
tr->timeout = 0;
/* Port dependent thread initialization.*/
- SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg);
+ PORT_SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg);
/* Initialization hook.*/
#if defined(NIL_CFG_THREAD_EXT_INIT_HOOK)
@@ -98,6 +98,35 @@ void nilSysInit(void) {
}
/**
+ * @brief Halts the system.
+ * @details This function is invoked by the operating system when an
+ * unrecoverable error is detected, for example because a programming
+ * error in the application code that triggers an assertion while
+ * in debug mode.
+ * @note Can be invoked from any system state.
+ *
+ * @special
+ */
+void nilSysHalt(const char *reason) {
+
+ port_disable();
+
+#if NIL_DBG_ENABLED
+ nil.dbg_panic_msg = reason;
+#else
+ (void)reason;
+#endif
+
+#if defined(NIL_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
+ NIL_CFG_SYSTEM_HALT_HOOK(reason);
+#endif
+
+ /* Harmless infinite loop.*/
+ while (true)
+ ;
+}
+
+/**
* @brief Time management handler.
* @note This handler has to be invoked by a periodic ISR in order to
* reschedule the waiting threads.
@@ -113,8 +142,7 @@ void nilSysTimerHandlerI(void) {
/* Is the thread in a wait state with timeout?.*/
if (tr->timeout > 0) {
- nilDbgAssert(!NIL_THD_IS_READY(tr),
- "nilSysTimerHandlerI(), #1", "is ready");
+ nilDbgAssert(!NIL_THD_IS_READY(tr), "is ready");
/* Did the timer reach zero?*/
if (--tr->timeout == 0) {
@@ -124,7 +152,7 @@ void nilSysTimerHandlerI(void) {
tr->u1.semp->cnt++;
else if (NIL_THD_IS_SUSP(tr))
tr->u1.trp = NULL;
- nilSchReadyI(tr, NIL_MSG_TMO);
+ nilSchReadyI(tr, MSG_TIMEOUT);
}
}
/* Lock released in order to give a preemption chance on those
@@ -194,11 +222,9 @@ thread_ref_t nilSchReadyI(thread_ref_t tr, msg_t msg) {
nilDbgAssert((tr >= nil.threads) &&
(tr < &nil.threads[NIL_CFG_NUM_THREADS]),
- "nilSchReadyI(), #1", "pointer out of range");
- nilDbgAssert(!NIL_THD_IS_READY(tr),
- "nilSchReadyI(), #2", "already ready");
- nilDbgAssert(nil.next <= nil.current,
- "nilSchReadyI(), #3", "priority ordering");
+ "pointer out of range");
+ nilDbgAssert(!NIL_THD_IS_READY(tr), "already ready");
+ nilDbgAssert(nil.next <= nil.current, "priority ordering");
tr->u1.msg = msg;
tr->state = NIL_THD_READY;
@@ -249,7 +275,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
thread_ref_t ntr, otr = nil.current;
nilDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS],
- "nilSchGoSleepTimeoutS(), #1", "idle cannot sleep");
+ "idle cannot sleep");
/* Storing the wait object for the current thread.*/
otr->state = newstate;
@@ -304,7 +330,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
/* Points to the next thread in lowering priority order.*/
ntr++;
nilDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS],
- "nilSchGoSleepTimeoutS(), #2", "pointer out of range");
+ "pointer out of range");
}
}
@@ -324,7 +350,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
*/
msg_t nilThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) {
- nilDbgAssert(*trp == NULL, "nilThdSuspendTimeoutS(), #1", "not NULL");
+ nilDbgAssert(*trp == NULL, "not NULL");
*trp = nil.current;
nil.current->u1.trp = trp;
@@ -346,7 +372,7 @@ void nilThdResumeI(thread_ref_t *trp, msg_t msg) {
if (*trp != NULL) {
thread_ref_t tr = *trp;
- nilDbgAssert(NIL_THD_IS_SUSP(tr), "nilThdResumeI(), #1", "not suspended");
+ nilDbgAssert(NIL_THD_IS_SUSP(tr), "not suspended");
*trp = NULL;
nilSchReadyI(tr, msg);
@@ -476,13 +502,13 @@ msg_t nilSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) {
cnt_t cnt = sp->cnt;
if (cnt <= 0) {
if (TIME_IMMEDIATE == timeout)
- return NIL_MSG_TMO;
+ return MSG_TIMEOUT;
sp->cnt = cnt - 1;
nil.current->u1.semp = sp;
return nilSchGoSleepTimeoutS(NIL_THD_WTSEM, timeout);
}
sp->cnt = cnt - 1;
- return NIL_MSG_OK;
+ return MSG_OK;
}
/**
@@ -523,10 +549,9 @@ void nilSemSignalI(semaphore_t *sp) {
/* Is this thread waiting on this semaphore?*/
if (tr->u1.semp == sp) {
- nilDbgAssert(NIL_THD_IS_WTSEM(tr),
- "nilSemSignalI(), #1", "not waiting");
+ nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting");
- nilSchReadyI(tr, NIL_MSG_OK);
+ nilSchReadyI(tr, MSG_OK);
return;
}
tr++;
@@ -585,11 +610,10 @@ void nilSemResetI(semaphore_t *sp, cnt_t n) {
/* Is this thread waiting on this semaphore?*/
if (tr->u1.semp == sp) {
- nilDbgAssert(NIL_THD_IS_WTSEM(tr),
- "nilSemResetI(), #1", "not waiting");
+ nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting");
cnt++;
- nilSchReadyI(tr, NIL_MSG_RST);
+ nilSchReadyI(tr, MSG_RESET);
}
tr++;
}