diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-08-11 17:51:37 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-08-11 17:51:37 +0000 |
commit | b9933c2089f5f0cd93738ae9081c45fcf3df54b7 (patch) | |
tree | c98941094d7d03cb42ffc46d258bccc0ffba4ca0 /os/kernel/src | |
parent | 50a41618beccf297631423b10aba8daa3be1e901 (diff) | |
download | ChibiOS-b9933c2089f5f0cd93738ae9081c45fcf3df54b7.tar.gz ChibiOS-b9933c2089f5f0cd93738ae9081c45fcf3df54b7.tar.bz2 ChibiOS-b9933c2089f5f0cd93738ae9081c45fcf3df54b7.zip |
Implemented system state checker debug option, remove the option CH_USE_NESTED_LOCKS. Documentation improvements and fixes.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3221 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/kernel/src')
-rw-r--r-- | os/kernel/src/chdebug.c | 163 | ||||
-rw-r--r-- | os/kernel/src/chmtx.c | 1 | ||||
-rw-r--r-- | os/kernel/src/chschd.c | 3 | ||||
-rw-r--r-- | os/kernel/src/chsys.c | 22 |
4 files changed, 157 insertions, 32 deletions
diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 0e378cc6d..28d4f7520 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -24,18 +24,161 @@ *
* @addtogroup debug
* @details Debug APIs and services:
+ * - Runtime system state and call protocol check. The following
+ * panic messages can be generated:
+ * - SV#1, misplaced @p chSysDisable().
+ * - SV#2, misplaced @p chSysSuspend()
+ * - SV#3, misplaced @p chSysEnable().
+ * - SV#4, misplaced @p chSysLock().
+ * - SV#5, misplaced @p chSysUnlock().
+ * - SV#6, misplaced @p chSysLockFromIsr().
+ * - SV#7, misplaced @p chSysUnlockFromIsr().
+ * - SV#8, misplaced @p CH_IRQ_PROLOGUE().
+ * - SV#9, misplaced @p CH_IRQ_EPILOGUE().
+ * .
* - Trace buffer.
* - Parameters check.
* - Kernel assertions.
+ * - Kernel panics.
* .
- * @pre In order to use the debug APIs the @p CH_DBG_ENABLE_TRACE,
- * @p CH_DBG_ENABLE_ASSERTS, @p CH_DBG_ENABLE_CHECKS options must
- * be enabled in @p chconf.h.
+ * @note Stack checks are not implemented in this module but in the port
+ * layer in an architecture-dependent way.
* @{
*/
#include "ch.h"
+/*===========================================================================*/
+/* System state checker related code and variables. */
+/*===========================================================================*/
+
+#if CH_DBG_SYSTEM_STATE_CHECK || defined(__DOXYGEN__)
+
+/**
+ * @brief ISR nesting level.
+ */
+cnt_t dbg_isr_cnt;
+
+/**
+ * @brief Lock nesting level.
+ */
+cnt_t dbg_lock_cnt;
+
+/**
+ * @brief Guard code for @p chSysDisable().
+ *
+ * @notapi
+ */
+void dbg_check_disable(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#1");
+}
+
+/**
+ * @brief Guard code for @p chSysSuspend().
+ *
+ * @notapi
+ */
+void dbg_check_suspend(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#2");
+}
+
+/**
+ * @brief Guard code for @p chSysEnable().
+ *
+ * @notapi
+ */
+void dbg_check_enable(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#3");
+}
+
+/**
+ * @brief Guard code for @p chSysLock().
+ *
+ * @notapi
+ */
+void dbg_check_lock(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#4");
+ dbg_lock_cnt = 1;
+}
+
+/**
+ * @brief Guard code for @p chSysUnlock().
+ *
+ * @notapi
+ */
+void dbg_check_unlock(void) {
+
+ if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0))
+ chDbgPanic("SV#5");
+ dbg_lock_cnt = 0;
+}
+
+/**
+ * @brief Guard code for @p chSysLockFromIsr().
+ *
+ * @notapi
+ */
+void dbg_check_lock_from_isr(void) {
+
+ if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0))
+ chDbgPanic("SV#6");
+ dbg_lock_cnt = 1;
+}
+
+/**
+ * @brief Guard code for @p chSysUnlockFromIsr().
+ *
+ * @notapi
+ */
+void dbg_check_unlock_from_isr(void) {
+
+ if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt <= 0))
+ chDbgPanic("SV#7");
+ dbg_lock_cnt = 0;
+}
+
+/**
+ * @brief Guard code for @p CH_IRQ_PROLOGUE().
+ *
+ * @notapi
+ */
+void dbg_check_enter_isr(void) {
+
+ port_lock_from_isr();
+ if (dbg_isr_cnt < 0)
+ chDbgPanic("SV#8");
+ dbg_isr_cnt++;
+ port_unlock_from_isr();
+}
+
+/**
+ * @brief Guard code for @p CH_IRQ_EPILOGUE().
+ *
+ * @notapi
+ */
+void dbg_check_leave_isr(void) {
+
+ port_lock_from_isr();
+ if (dbg_isr_cnt <= 0)
+ chDbgPanic("SV#9");
+ dbg_isr_cnt--;
+ port_unlock_from_isr();
+}
+
+#endif /* CH_DBG_SYSTEM_STATE_CHECK */
+
+/*===========================================================================*/
+/* Trace related code and variables. */
+/*===========================================================================*/
+
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
/**
* @brief Public trace buffer.
@@ -59,7 +202,7 @@ void _trace_init(void) { *
* @notapi
*/
-void chDbgTrace(Thread *otp) {
+void dbg_trace(Thread *otp) {
dbg_trace_buffer.tb_ptr->se_time = chTimeNow();
dbg_trace_buffer.tb_ptr->se_tp = currp;
@@ -71,13 +214,15 @@ void chDbgTrace(Thread *otp) { }
#endif /* CH_DBG_ENABLE_TRACE */
-#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \
- CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
+/*===========================================================================*/
+/* Panic related code and variables. */
+/*===========================================================================*/
+
+#if CH_DBG_ENABLED || defined(__DOXYGEN__)
/**
* @brief Pointer to the panic message.
* @details This pointer is meant to be accessed through the debugger, it is
- * written once and then the system is halted. This variable can be
- * set to @p NULL if the halt is caused by a stack overflow.
+ * written once and then the system is halted.
*/
char *dbg_panic_msg;
@@ -91,6 +236,6 @@ void chDbgPanic(char *msg) { dbg_panic_msg = msg;
chSysHalt();
}
-#endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */
+#endif /* CH_DBG_ENABLED */
/** @} */
diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index df71d1cc6..21b92e388 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -157,6 +157,7 @@ void chMtxLockS(Mutex *mp) { #endif
/* Re-enqueues tp with its new priority on the ready list.*/
chSchReadyI(dequeue(tp));
+ break;
}
break;
}
diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index d41649b4c..e989f4039 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -113,7 +113,6 @@ void chSchGoSleepS(tstate_t newstate) { #endif
setcurrp(fifo_remove(&rlist.r_queue));
currp->p_state = THD_STATE_CURRENT;
- chDbgTrace(otp);
chSysSwitchI(currp, otp);
}
#endif /* !defined(PORT_OPTIMIZED_GOSLEEPS) */
@@ -222,7 +221,6 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { #endif
setcurrp(ntp);
ntp->p_state = THD_STATE_CURRENT;
- chDbgTrace(otp);
chSysSwitchI(ntp, otp);
}
}
@@ -247,7 +245,6 @@ void chSchDoRescheduleI(void) { setcurrp(fifo_remove(&rlist.r_queue));
currp->p_state = THD_STATE_CURRENT;
chSchReadyI(otp);
- chDbgTrace(otp);
chSysSwitchI(currp, otp);
}
#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */
diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 4c8cd708d..6c63e113f 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -98,6 +98,8 @@ void chSysInit(void) { setcurrp(_thread_init(&mainthread, NORMALPRIO));
currp->p_state = THD_STATE_CURRENT;
#if CH_DBG_ENABLE_STACK_CHECK
+ /* This is a special case because the main thread Thread structure is not
+ adjacent to its stack area.*/
currp->p_stklimit = &__main_thread_stack_base__;
#endif
chSysEnable();
@@ -141,24 +143,4 @@ void chSysTimerHandlerI(void) { #endif
}
-#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED
-void chSysLock(void) {
-
- chDbgAssert(currp->p_locks >= 0,
- "chSysLock(), #1",
- "negative nesting counter");
- if (currp->p_locks++ == 0)
- port_lock();
-}
-
-void chSysUnlock(void) {
-
- chDbgAssert(currp->p_locks > 0,
- "chSysUnlock(), #1",
- "non-positive nesting counter");
- if (--currp->p_locks == 0)
- port_unlock();
-}
-#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */
-
/** @} */
|