From b9933c2089f5f0cd93738ae9081c45fcf3df54b7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 11 Aug 2011 17:51:37 +0000 Subject: 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 --- os/kernel/src/chdebug.c | 163 +++++++++++++++++++++++++++++++++++++++++++++--- os/kernel/src/chmtx.c | 1 + os/kernel/src/chschd.c | 3 - os/kernel/src/chsys.c | 22 +------ 4 files changed, 157 insertions(+), 32 deletions(-) (limited to 'os/kernel/src') 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 */ - /** @} */ -- cgit v1.2.3