git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@791 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2009-02-20 20:14:42 +00:00
parent 83762f45fd
commit daabc2b079
28 changed files with 325 additions and 140 deletions

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
@ -359,7 +368,7 @@
* may not be implemented at all. * may not be implemented at all.
*/ */
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_STACK_CHECK FALSE #define CH_DBG_ENABLE_STACK_CHECK TRUE
#endif #endif
/** /**
@ -367,7 +376,7 @@
* pattern when a thread is created. * pattern when a thread is created.
*/ */
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
#define CH_DBG_FILL_THREADS FALSE #define CH_DBG_FILL_THREADS TRUE
#endif #endif
/** /**

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -162,7 +162,7 @@ struct context {
"bx r0 \n\t" \ "bx r0 \n\t" \
".code 16"); \ ".code 16"); \
} }
#else /* THUMB */ #else /* !THUMB */
#define PORT_IRQ_PROLOGUE() { \ #define PORT_IRQ_PROLOGUE() { \
asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \ asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \
} }
@ -179,7 +179,7 @@ struct context {
asm volatile ("ldr r0, =_port_irq_common \n\t" \ asm volatile ("ldr r0, =_port_irq_common \n\t" \
"bx r0"); \ "bx r0"); \
} }
#else /* THUMB */ #else /* !THUMB */
#define PORT_IRQ_EPILOGUE() { \ #define PORT_IRQ_EPILOGUE() { \
asm volatile ("b _port_irq_common"); \ asm volatile ("b _port_irq_common"); \
} }
@ -203,7 +203,7 @@ struct context {
#define port_lock() { \ #define port_lock() { \
asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \
} }
#else /* THUMB */ #else /* !THUMB */
#define port_lock() asm volatile ("msr CPSR_c, #0x9F") #define port_lock() asm volatile ("msr CPSR_c, #0x9F")
#endif /* !THUMB */ #endif /* !THUMB */
@ -215,7 +215,7 @@ struct context {
#define port_unlock() { \ #define port_unlock() { \
asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \
} }
#else /* THUMB */ #else /* !THUMB */
#define port_unlock() asm volatile ("msr CPSR_c, #0x1F") #define port_unlock() asm volatile ("msr CPSR_c, #0x1F")
#endif /* !THUMB */ #endif /* !THUMB */
@ -239,7 +239,7 @@ struct context {
#define port_disable() { \ #define port_disable() { \
asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \
} }
#else /* THUMB */ #else /* !THUMB */
#define port_disable() { \ #define port_disable() { \
asm volatile ("mrs r3, CPSR \n\t" \ asm volatile ("mrs r3, CPSR \n\t" \
"orr r3, #0x80 \n\t" \ "orr r3, #0x80 \n\t" \
@ -256,7 +256,7 @@ struct context {
#define port_suspend() { \ #define port_suspend() { \
asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \
} }
#else /* THUMB */ #else /* !THUMB */
#define port_suspend() asm volatile ("msr CPSR_c, #0x9F") #define port_suspend() asm volatile ("msr CPSR_c, #0x9F")
#endif /* !THUMB */ #endif /* !THUMB */
@ -267,7 +267,7 @@ struct context {
#define port_enable() { \ #define port_enable() { \
asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \
} }
#else /* THUMB */ #else /* !THUMB */
#define port_enable() asm volatile ("msr CPSR_c, #0x1F") #define port_enable() asm volatile ("msr CPSR_c, #0x1F")
#endif /* !THUMB */ #endif /* !THUMB */
@ -278,7 +278,7 @@ struct context {
*/ */
#ifdef THUMB #ifdef THUMB
#define port_switch(otp, ntp) _port_switch_thumb(otp, ntp) #define port_switch(otp, ntp) _port_switch_thumb(otp, ntp)
#else /* THUMB */ #else /* !THUMB */
#define port_switch(otp, ntp) _port_switch_arm(otp, ntp) #define port_switch(otp, ntp) _port_switch_arm(otp, ntp)
#endif /* !THUMB */ #endif /* !THUMB */
@ -289,7 +289,7 @@ extern "C" {
void port_halt(void); void port_halt(void);
#ifdef THUMB #ifdef THUMB
void _port_switch_thumb(Thread *otp, Thread *ntp); void _port_switch_thumb(Thread *otp, Thread *ntp);
#else /* THUMB */ #else /* !THUMB */
void _port_switch_arm(Thread *otp, Thread *ntp); void _port_switch_arm(Thread *otp, Thread *ntp);
#endif /* !THUMB */ #endif /* !THUMB */
void _port_thread_start(void); void _port_thread_start(void);

View File

@ -178,7 +178,7 @@ struct context {
/** /**
* Enforces a correct alignment for a stack area size value. * Enforces a correct alignment for a stack area size value.
*/ */
#define STACK_ALIGN(n) ((((n) - 1) | sizeof(stkalign_t)) + 1) #define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
/** /**
* Computes the thread working area global size. * Computes the thread working area global size.
@ -281,11 +281,23 @@ struct context {
/** /**
* This port function is implemented as inlined code for performance reasons. * This port function is implemented as inlined code for performance reasons.
*/ */
#if CH_DBG_ENABLE_STACK_CHECK
#define port_switch(otp, ntp) { \
register Thread *_otp asm ("r0") = (otp); \
register Thread *_ntp asm ("r1") = (ntp); \
register char *sp asm ("sp"); \
if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \
asm volatile ("movs r0, #0 \n\t" \
"b chDbgPanic"); \
asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp)); \
}
#else /* !CH_DBG_ENABLE_STACK_CHECK */
#define port_switch(otp, ntp) { \ #define port_switch(otp, ntp) { \
register Thread *_otp asm ("r0") = (otp); \ register Thread *_otp asm ("r0") = (otp); \
register Thread *_ntp asm ("r1") = (ntp); \ register Thread *_ntp asm ("r1") = (ntp); \
asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp)); \ asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp)); \
} }
#endif /* !CH_DBG_ENABLE_STACK_CHECK */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -82,14 +82,14 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process,
- FIX: Fixed a small problem in the chcore.c template file. - FIX: Fixed a small problem in the chcore.c template file.
- NEW: Mailboxes (asynchronous messages) subsystem and test cases added. - NEW: Mailboxes (asynchronous messages) subsystem and test cases added.
- NEW: Mode flexible debug configuration options, removed the old CH_USE_DEBUG - NEW: Mode flexible debug configuration options, removed the old CH_USE_DEBUG
and CH_USE_TRACE. Replaced with CH_DBG_ENABLE_ASSERTS, CH_DBG_ENABLE_TRACE and CH_USE_TRACE. Replaced with CH_DBG_ENABLE_CHECKS, SCH_DBG_ENABLE_ASSERTS,
and CH_DBG_FILL_THREADS. CH_DBG_ENABLE_TRACE and CH_DBG_FILL_THREADS.
- NEW: Added a debug option CH_DBG_THREADS_PROFILING for threads profiling. - NEW: Added a debug option CH_DBG_THREADS_PROFILING for threads profiling.
A field into the Thread structure counts the consumed time. The information A field into the Thread structure counts the consumed time. The information
is not used into the kernel, it is meant for debugging. is not used into the kernel, it is meant for debugging.
- NEW: Added a debug option CH_DBG_ENABLE_STACK_CHECK for stack overflow - NEW: Added a debug option CH_DBG_ENABLE_STACK_CHECK for stack overflow
checking. The check is not performed in the kernel but in the port code. checking. The check is not performed in the kernel but in the port code.
Currently no ports implement it. Currently no port implements it.
- NEW: Unified makefiles for ARM7 and ARMCM3 projects, the new makefiles - NEW: Unified makefiles for ARM7 and ARMCM3 projects, the new makefiles
share a common part making them easier to maintain. Also reorganized the share a common part making them easier to maintain. Also reorganized the
demo-specific part of the makefile, now it is easier to configure and the demo-specific part of the makefile, now it is easier to configure and the

View File

@ -42,6 +42,8 @@
*/ */
void chCondInit(CondVar *cp) { void chCondInit(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondInit");
queue_init(&cp->c_queue); queue_init(&cp->c_queue);
} }
@ -52,11 +54,11 @@ void chCondInit(CondVar *cp) {
*/ */
void chCondSignal(CondVar *cp) { void chCondSignal(CondVar *cp) {
chSysLock(); chDbgCheck(cp != NULL, "chCondSignal");
chSysLock();
if (notempty(&cp->c_queue)) /* any thread ? */ if (notempty(&cp->c_queue)) /* any thread ? */
chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK); chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK);
chSysUnlock(); chSysUnlock();
} }
@ -67,6 +69,8 @@ void chCondSignal(CondVar *cp) {
*/ */
void chCondSignalI(CondVar *cp) { void chCondSignalI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondSignalI");
if (notempty(&cp->c_queue)) /* any thread ? */ if (notempty(&cp->c_queue)) /* any thread ? */
chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_OK; chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_OK;
} }
@ -79,10 +83,8 @@ void chCondSignalI(CondVar *cp) {
void chCondBroadcast(CondVar *cp) { void chCondBroadcast(CondVar *cp) {
chSysLock(); chSysLock();
chCondBroadcastI(cp); chCondBroadcastI(cp);
chSchRescheduleS(); chSchRescheduleS();
chSysUnlock(); chSysUnlock();
} }
@ -93,6 +95,8 @@ void chCondBroadcast(CondVar *cp) {
*/ */
void chCondBroadcastI(CondVar *cp) { void chCondBroadcastI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondBroadcastI");
/* empties the condition variable queue and inserts all the Threads into the /* empties the condition variable queue and inserts all the Threads into the
* ready list in FIFO order. The wakeup message is set to @p RDY_RESET in * ready list in FIFO order. The wakeup message is set to @p RDY_RESET in
* order to make a chCondBroadcast() detectable from a chCondSignal(). */ * order to make a chCondBroadcast() detectable from a chCondSignal(). */
@ -116,9 +120,7 @@ msg_t chCondWait(CondVar *cp) {
msg_t msg; msg_t msg;
chSysLock(); chSysLock();
msg = chCondWaitS(cp); msg = chCondWaitS(cp);
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -139,7 +141,10 @@ msg_t chCondWaitS(CondVar *cp) {
Mutex *mp; Mutex *mp;
msg_t msg; msg_t msg;
chDbgAssert(currp->p_mtxlist != NULL, "chcond.c, chCondWaitS()"); chDbgCheck(cp != NULL, "chCondWaitS");
chDbgAssert(currp->p_mtxlist != NULL,
"chCondWaitS(), #1",
"not owning a mutex");
mp = chMtxUnlockS(); /* unlocks the condvar mutex */ mp = chMtxUnlockS(); /* unlocks the condvar mutex */
prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ prio_insert(currp, &cp->c_queue); /* enters the condvar queue */
@ -170,9 +175,7 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
msg_t msg; msg_t msg;
chSysLock(); chSysLock();
msg = chCondWaitTimeoutS(cp, time); msg = chCondWaitTimeoutS(cp, time);
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -196,7 +199,10 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
Mutex *mp; Mutex *mp;
msg_t msg; msg_t msg;
chDbgAssert(currp->p_mtxlist != NULL, "chcond.c, chCondWaitS()"); chDbgCheck(cp != NULL, "chCondWaitTimeoutS");
chDbgAssert(currp->p_mtxlist != NULL,
"chCondWaitTimeoutS(), #1",
"not owning a mutex");
mp = chMtxUnlockS(); /* unlocks the condvar mutex */ mp = chMtxUnlockS(); /* unlocks the condvar mutex */
prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ prio_insert(currp, &cp->c_queue); /* enters the condvar queue */

View File

@ -58,7 +58,7 @@ void chDbgTrace(Thread *otp, Thread *ntp) {
} }
#endif /* CH_DBG_ENABLE_TRACE */ #endif /* CH_DBG_ENABLE_TRACE */
#if CH_DBG_ENABLE_ASSERTS #if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
/** /**
* @brief Pointer to the panic message. * @brief Pointer to the panic message.
* @details This pointer is meant to be accessed through the debugger, it is * @details This pointer is meant to be accessed through the debugger, it is
@ -74,10 +74,8 @@ char *panic_msg;
void chDbgPanic(char *msg) { void chDbgPanic(char *msg) {
panic_msg = msg; panic_msg = msg;
chSysPuts("PANIC: ");
chSysPuts(msg);
chSysHalt(); chSysHalt();
} }
#endif /* CH_DBG_ENABLE_ASSERTS */ #endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */
/** @} */ /** @} */

View File

@ -37,13 +37,13 @@
*/ */
void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) { void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) {
chSysLock(); chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask");
chSysLock();
elp->el_next = esp->es_next; elp->el_next = esp->es_next;
esp->es_next = elp; esp->es_next = elp;
elp->el_listener = currp; elp->el_listener = currp;
elp->el_mask = emask; elp->el_mask = emask;
chSysUnlock(); chSysUnlock();
} }
@ -59,10 +59,12 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask)
* found on top of the list). * found on top of the list).
*/ */
void chEvtUnregister(EventSource *esp, EventListener *elp) { void chEvtUnregister(EventSource *esp, EventListener *elp) {
EventListener *p = (EventListener *)esp; EventListener *p;
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtUnregister");
p = (EventListener *)esp;
chSysLock(); chSysLock();
while (p->el_next != (EventListener *)esp) { while (p->el_next != (EventListener *)esp) {
if (p->el_next == elp) { if (p->el_next == elp) {
p->el_next = elp->el_next; p->el_next = elp->el_next;
@ -70,7 +72,6 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) {
} }
p = p->el_next; p = p->el_next;
} }
chSysUnlock(); chSysUnlock();
} }
@ -117,10 +118,10 @@ eventmask_t chEvtPend(eventmask_t mask) {
*/ */
void chEvtSignal(Thread *tp, eventmask_t mask) { void chEvtSignal(Thread *tp, eventmask_t mask) {
chDbgCheck(tp != NULL, "chEvtSignal");
chSysLock(); chSysLock();
chEvtSignalI(tp, mask); chEvtSignalI(tp, mask);
chSysUnlock(); chSysUnlock();
} }
@ -132,8 +133,9 @@ void chEvtSignal(Thread *tp, eventmask_t mask) {
*/ */
void chEvtSignalI(Thread *tp, eventmask_t mask) { void chEvtSignalI(Thread *tp, eventmask_t mask) {
tp->p_epending |= mask; chDbgCheck(tp != NULL, "chEvtSignalI");
tp->p_epending |= mask;
/* Test on the AND/OR conditions wait states.*/ /* Test on the AND/OR conditions wait states.*/
if (((tp->p_state == PRWTOREVT) && ((tp->p_epending & tp->p_ewmask) != 0)) || if (((tp->p_state == PRWTOREVT) && ((tp->p_epending & tp->p_ewmask) != 0)) ||
((tp->p_state == PRWTANDEVT) && ((tp->p_epending & tp->p_ewmask) == tp->p_ewmask))) ((tp->p_state == PRWTANDEVT) && ((tp->p_epending & tp->p_ewmask) == tp->p_ewmask)))
@ -149,10 +151,8 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) {
void chEvtBroadcast(EventSource *esp) { void chEvtBroadcast(EventSource *esp) {
chSysLock(); chSysLock();
chEvtBroadcastI(esp); chEvtBroadcastI(esp);
chSchRescheduleS(); chSchRescheduleS();
chSysUnlock(); chSysUnlock();
} }
@ -165,6 +165,8 @@ void chEvtBroadcast(EventSource *esp) {
void chEvtBroadcastI(EventSource *esp) { void chEvtBroadcastI(EventSource *esp) {
EventListener *elp; EventListener *elp;
chDbgCheck(esp != NULL, "chEvtBroadcastI");
elp = esp->es_next; elp = esp->es_next;
while (elp != (EventListener *)esp) { while (elp != (EventListener *)esp) {
chEvtSignalI(elp->el_listener, elp->el_mask); chEvtSignalI(elp->el_listener, elp->el_mask);
@ -183,9 +185,14 @@ void chEvtBroadcastI(EventSource *esp) {
void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) {
eventid_t eid; eventid_t eid;
chDbgCheck(handlers != NULL, "chEvtDispatch");
eid = 0; eid = 0;
while (mask) { while (mask) {
if (mask & EVENT_MASK(eid)) { if (mask & EVENT_MASK(eid)) {
chDbgAssert(handlers[eid] != NULL,
"chEvtDispatch(), #1",
"null handler");
mask &= ~EVENT_MASK(eid); mask &= ~EVENT_MASK(eid);
handlers[eid](eid); handlers[eid](eid);
} }

View File

@ -153,16 +153,20 @@ void *chHeapAlloc(size_t size) {
void chHeapFree(void *p) { void chHeapFree(void *p) {
struct header *qp, *hp; struct header *qp, *hp;
chDbgCheck(p != NULL, "chHeapFree");
hp = (struct header *)p - 1; hp = (struct header *)p - 1;
chDbgAssert(hp->h_magic == MAGIC,
chDbgAssert(hp->h_magic == MAGIC, "chheap.c, chHeapFree() #1"); "chHeapFree(), #1",
"it is not magic");
qp = &heap.free; qp = &heap.free;
H_LOCK(); H_LOCK();
while (TRUE) { while (TRUE) {
chDbgAssert((hp < qp) || (hp >= LIMIT(qp)), "chheap.c, chHeapFree() #2"); chDbgAssert((hp < qp) || (hp >= LIMIT(qp)),
"chHeapFree(), #2",
"within free block");
if (((qp == &heap.free) || (hp > qp)) && if (((qp == &heap.free) || (hp > qp)) &&
((qp->h_next == NULL) || (hp < qp->h_next))) { ((qp->h_next == NULL) || (hp < qp->h_next))) {
@ -244,19 +248,17 @@ void *chHeapAlloc(size_t size) {
void *p; void *p;
H_LOCK(); H_LOCK();
p = malloc(size); p = malloc(size);
H_UNLOCK(); H_UNLOCK();
return p; return p;
} }
void chHeapFree(void *p) { void chHeapFree(void *p) {
chDbgCheck(p != NULL, "chHeapFree");
H_LOCK(); H_LOCK();
free(p); free(p);
H_UNLOCK(); H_UNLOCK();
} }

View File

@ -27,7 +27,6 @@
#include <ch.h> #include <ch.h>
#if CH_USE_MAILBOXES #if CH_USE_MAILBOXES
/** /**
* @brief Initializes a Mailbox object. * @brief Initializes a Mailbox object.
* *
@ -37,6 +36,8 @@
*/ */
void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) { void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) {
chDbgCheck((mbp != NULL) && (buf != NULL) && (n > 0), "chMBInit");
mbp->mb_buffer = mbp->mb_wrptr = mbp->mb_rdptr = buf; mbp->mb_buffer = mbp->mb_wrptr = mbp->mb_rdptr = buf;
mbp->mb_top = &buf[n]; mbp->mb_top = &buf[n];
chSemInit(&mbp->mb_emptysem, n); chSemInit(&mbp->mb_emptysem, n);
@ -52,6 +53,8 @@ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) {
*/ */
void chMBReset(Mailbox *mbp) { void chMBReset(Mailbox *mbp) {
chDbgCheck(mbp != NULL, "chMBReset");
chSysLock(); chSysLock();
mbp->mb_wrptr = mbp->mb_rdptr = mbp->mb_buffer; mbp->mb_wrptr = mbp->mb_rdptr = mbp->mb_buffer;
chSemResetI(&mbp->mb_emptysem, mbp->mb_top - mbp->mb_buffer); chSemResetI(&mbp->mb_emptysem, mbp->mb_top - mbp->mb_buffer);
@ -77,6 +80,8 @@ void chMBReset(Mailbox *mbp) {
msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout) { msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout) {
msg_t rdymsg; msg_t rdymsg;
chDbgCheck(mbp != NULL, "chMBPost");
chSysLock(); chSysLock();
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout); rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout);
if (rdymsg == RDY_OK) { if (rdymsg == RDY_OK) {
@ -106,6 +111,8 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout) {
msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout) { msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout) {
msg_t rdymsg; msg_t rdymsg;
chDbgCheck(mbp != NULL, "chMBPostAhead");
chSysLock(); chSysLock();
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout); rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout);
if (rdymsg == RDY_OK) { if (rdymsg == RDY_OK) {
@ -135,6 +142,8 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout) {
msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout) { msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout) {
msg_t rdymsg; msg_t rdymsg;
chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetch");
chSysLock(); chSysLock();
rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, timeout); rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, timeout);
if (rdymsg == RDY_OK) { if (rdymsg == RDY_OK) {

View File

@ -36,8 +36,7 @@
*/ */
void chPoolInit(MemoryPool *mp, size_t size) { void chPoolInit(MemoryPool *mp, size_t size) {
chDbgAssert((mp != NULL) && (size >= sizeof(void *)), chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit");
"chpools.c, chPoolInit()");
mp->mp_next = NULL; mp->mp_next = NULL;
mp->mp_object_size = size; mp->mp_object_size = size;
@ -53,7 +52,7 @@ void chPoolInit(MemoryPool *mp, size_t size) {
void *chPoolAllocI(MemoryPool *mp) { void *chPoolAllocI(MemoryPool *mp) {
void *objp; void *objp;
chDbgAssert(mp != NULL, "chmempools.c, chPoolAllocI()"); chDbgCheck(mp != NULL, "chPoolAllocI");
if ((objp = mp->mp_next) != NULL) if ((objp = mp->mp_next) != NULL)
mp->mp_next = mp->mp_next->ph_next; mp->mp_next = mp->mp_next->ph_next;
@ -88,8 +87,7 @@ void *chPoolAlloc(MemoryPool *mp) {
void chPoolFreeI(MemoryPool *mp, void *objp) { void chPoolFreeI(MemoryPool *mp, void *objp) {
struct pool_header *php = objp; struct pool_header *php = objp;
chDbgAssert((mp != NULL) && (objp != NULL), chDbgCheck((mp != NULL) && (objp != NULL), "chPoolFreeI");
"chmempools.c, chPoolFreeI()");
php->ph_next = mp->mp_next; php->ph_next = mp->mp_next;
mp->mp_next = php; mp->mp_next = php;

View File

@ -45,8 +45,9 @@
*/ */
msg_t chMsgSend(Thread *tp, msg_t msg) { msg_t chMsgSend(Thread *tp, msg_t msg) {
chSysLock(); chDbgCheck(tp != NULL, "chMsgSend");
chSysLock();
msg_insert(currp, &tp->p_msgqueue); msg_insert(currp, &tp->p_msgqueue);
currp->p_msg = msg; currp->p_msg = msg;
currp->p_wtthdp = tp; currp->p_wtthdp = tp;
@ -54,7 +55,6 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
chSchReadyI(tp); chSchReadyI(tp);
chSchGoSleepS(PRSNDMSG); chSchGoSleepS(PRSNDMSG);
msg = currp->p_rdymsg; msg = currp->p_rdymsg;
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -76,17 +76,18 @@ msg_t chMsgSend(Thread *tp, msg_t msg) {
*/ */
msg_t chMsgSendWithEvent(Thread *tp, msg_t msg, eventmask_t mask) { msg_t chMsgSendWithEvent(Thread *tp, msg_t msg, eventmask_t mask) {
chDbgCheck(tp != NULL, "chMsgSendWithEvent");
chSysLock(); chSysLock();
chDbgAssert(tp->p_state != PRWTMSG,
chDbgAssert(tp->p_state != PRWTMSG, "chmsg.c, chMsgSendWithEvent()"); "chMsgSendWithEvent(), #1",
"waiting for messages not events");
chEvtSignalI(tp, mask); chEvtSignalI(tp, mask);
msg_insert(currp, &tp->p_msgqueue); msg_insert(currp, &tp->p_msgqueue);
currp->p_wtthdp = tp; currp->p_wtthdp = tp;
currp->p_msg = msg; currp->p_msg = msg;
chSchGoSleepS(PRSNDMSG); chSchGoSleepS(PRSNDMSG);
msg = currp->p_rdymsg; msg = currp->p_rdymsg;
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -105,11 +106,9 @@ msg_t chMsgWait(void) {
msg_t msg; msg_t msg;
chSysLock(); chSysLock();
if (!chMsgIsPendingI(currp)) if (!chMsgIsPendingI(currp))
chSchGoSleepS(PRWTMSG); chSchGoSleepS(PRWTMSG);
msg = chMsgGetI(currp); msg = chMsgGetI(currp);
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -129,9 +128,7 @@ msg_t chMsgGet(void) {
msg_t msg; msg_t msg;
chSysLock(); chSysLock();
msg = chMsgIsPendingI(currp) ? chMsgGetI(currp) : (msg_t)NULL; msg = chMsgIsPendingI(currp) ? chMsgGetI(currp) : (msg_t)NULL;
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -150,10 +147,10 @@ msg_t chMsgGet(void) {
void chMsgRelease(msg_t msg) { void chMsgRelease(msg_t msg) {
chSysLock(); chSysLock();
chDbgAssert(chMsgIsPendingI(currp),
chDbgAssert(chMsgIsPendingI(currp), "chmsg.c, chMsgRelease()"); "chMsgRelease(), #1",
"no message pending");
chSchWakeupS(fifo_remove(&currp->p_msgqueue), msg); chSchWakeupS(fifo_remove(&currp->p_msgqueue), msg);
chSysUnlock(); chSysUnlock();
} }

View File

@ -38,6 +38,8 @@
*/ */
void chMtxInit(Mutex *mp) { void chMtxInit(Mutex *mp) {
chDbgCheck(mp != NULL, "chMtxInit");
queue_init(&mp->m_queue); queue_init(&mp->m_queue);
mp->m_owner = NULL; mp->m_owner = NULL;
} }
@ -64,6 +66,9 @@ void chMtxLock(Mutex *mp) {
* block. * block.
*/ */
void chMtxLockS(Mutex *mp) { void chMtxLockS(Mutex *mp) {
chDbgCheck(mp != NULL, "chMtxLockS");
/* the mutex is already locked? */ /* the mutex is already locked? */
if (mp->m_owner != NULL) { if (mp->m_owner != NULL) {
/* /*
@ -112,7 +117,7 @@ void chMtxLockS(Mutex *mp) {
/* thread remembers the mutex where it is waiting on */ /* thread remembers the mutex where it is waiting on */
currp->p_wtmtxp = mp; currp->p_wtmtxp = mp;
chSchGoSleepS(PRWTMTX); chSchGoSleepS(PRWTMTX);
chDbgAssert(mp->m_owner == NULL, "chmtx.c, chMtxLockS()"); chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned");
} }
/* /*
* The mutex is now inserted in the owned mutexes list. * The mutex is now inserted in the owned mutexes list.
@ -156,6 +161,8 @@ bool_t chMtxTryLock(Mutex *mp) {
*/ */
bool_t chMtxTryLockS(Mutex *mp) { bool_t chMtxTryLockS(Mutex *mp) {
chDbgCheck(mp != NULL, "chMtxTryLockS");
if (mp->m_owner != NULL) if (mp->m_owner != NULL)
return FALSE; return FALSE;
mp->m_owner = currp; mp->m_owner = currp;
@ -173,10 +180,12 @@ Mutex *chMtxUnlock(void) {
Mutex *ump, *mp; Mutex *ump, *mp;
chSysLock(); chSysLock();
chDbgAssert(currp->p_mtxlist != NULL,
chDbgAssert((currp->p_mtxlist != NULL) && (currp->p_mtxlist->m_owner == currp), "chMtxUnlock(), #1",
"chmtx.c, chMtxUnlock()"); "owned mutexes list empty");
chDbgAssert(currp->p_mtxlist->m_owner == currp,
"chMtxUnlock(), #2",
"ownership failure");
/* remove the top Mutex from the Threads's owned mutexes list */ /* remove the top Mutex from the Threads's owned mutexes list */
ump = currp->p_mtxlist; ump = currp->p_mtxlist;
currp->p_mtxlist = ump->m_next; currp->p_mtxlist = ump->m_next;
@ -221,8 +230,12 @@ Mutex *chMtxUnlock(void) {
Mutex *chMtxUnlockS(void) { Mutex *chMtxUnlockS(void) {
Mutex *ump, *mp; Mutex *ump, *mp;
chDbgAssert((currp->p_mtxlist != NULL) && (currp->p_mtxlist->m_owner == currp), chDbgAssert(currp->p_mtxlist != NULL,
"chmtx.c, chMtxUnlockS()"); "chMtxUnlockS(), #1",
"owned mutexes list empty");
chDbgAssert(currp->p_mtxlist->m_owner == currp,
"chMtxUnlockS(), #2",
"ownership failure");
/* /*
* Removes the top Mutex from the owned mutexes list and marks it as not owned. * Removes the top Mutex from the owned mutexes list and marks it as not owned.
@ -261,7 +274,6 @@ Mutex *chMtxUnlockS(void) {
void chMtxUnlockAll(void) { void chMtxUnlockAll(void) {
chSysLock(); chSysLock();
if (currp->p_mtxlist != NULL) { if (currp->p_mtxlist != NULL) {
do { do {
Mutex *mp = currp->p_mtxlist; Mutex *mp = currp->p_mtxlist;
@ -273,7 +285,6 @@ void chMtxUnlockAll(void) {
currp->p_prio = currp->p_realprio; currp->p_prio = currp->p_realprio;
chSchRescheduleS(); chSchRescheduleS();
} }
chSysUnlock(); chSysUnlock();
} }

View File

@ -45,7 +45,8 @@
*/ */
void chSemInit(Semaphore *sp, cnt_t n) { void chSemInit(Semaphore *sp, cnt_t n) {
chDbgAssert(n >= 0, "chsem.c, chSemInit()"); chDbgCheck((sp != NULL) && (n >= 0), "chSemInit");
queue_init(&sp->s_queue); queue_init(&sp->s_queue);
sp->s_cnt = n; sp->s_cnt = n;
} }
@ -62,10 +63,8 @@ void chSemInit(Semaphore *sp, cnt_t n) {
void chSemReset(Semaphore *sp, cnt_t n) { void chSemReset(Semaphore *sp, cnt_t n) {
chSysLock(); chSysLock();
chSemResetI(sp, n); chSemResetI(sp, n);
chSchRescheduleS(); chSchRescheduleS();
chSysUnlock(); chSysUnlock();
} }
@ -82,7 +81,8 @@ void chSemReset(Semaphore *sp, cnt_t n) {
void chSemResetI(Semaphore *sp, cnt_t n) { void chSemResetI(Semaphore *sp, cnt_t n) {
cnt_t cnt; cnt_t cnt;
chDbgAssert(n >= 0, "chsem.c, chSemResetI()"); chDbgCheck((sp != NULL) && (n >= 0), "chSemResetI");
cnt = sp->s_cnt; cnt = sp->s_cnt;
sp->s_cnt = n; sp->s_cnt = n;
while (cnt++ < 0) while (cnt++ < 0)
@ -100,9 +100,7 @@ msg_t chSemWait(Semaphore *sp) {
msg_t msg; msg_t msg;
chSysLock(); chSysLock();
msg = chSemWaitS(sp); msg = chSemWaitS(sp);
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -118,6 +116,8 @@ msg_t chSemWait(Semaphore *sp) {
*/ */
msg_t chSemWaitS(Semaphore *sp) { msg_t chSemWaitS(Semaphore *sp) {
chDbgCheck(sp != NULL, "chSemWaitS");
if (--sp->s_cnt < 0) { if (--sp->s_cnt < 0) {
sem_insert(currp, &sp->s_queue); sem_insert(currp, &sp->s_queue);
currp->p_wtsemp = sp; currp->p_wtsemp = sp;
@ -144,9 +144,7 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
msg_t msg; msg_t msg;
chSysLock(); chSysLock();
msg = chSemWaitTimeoutS(sp, time); msg = chSemWaitTimeoutS(sp, time);
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }
@ -165,6 +163,8 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
*/ */
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
chDbgCheck(sp != NULL, "chSemWaitTimeoutS");
if (--sp->s_cnt < 0) { if (--sp->s_cnt < 0) {
sem_insert(currp, &sp->s_queue); sem_insert(currp, &sp->s_queue);
currp->p_wtsemp = sp; currp->p_wtsemp = sp;
@ -183,11 +183,11 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
*/ */
void chSemSignal(Semaphore *sp) { void chSemSignal(Semaphore *sp) {
chSysLock(); chDbgCheck(sp != NULL, "chSemSignal");
chSysLock();
if (sp->s_cnt++ < 0) if (sp->s_cnt++ < 0)
chSchWakeupS(fifo_remove(&sp->s_queue), RDY_OK); chSchWakeupS(fifo_remove(&sp->s_queue), RDY_OK);
chSysUnlock(); chSysUnlock();
} }
@ -201,6 +201,8 @@ void chSemSignal(Semaphore *sp) {
*/ */
void chSemSignalI(Semaphore *sp) { void chSemSignalI(Semaphore *sp) {
chDbgCheck(sp != NULL, "chSemSignalI");
if (sp->s_cnt++ < 0) { if (sp->s_cnt++ < 0) {
/* NOTE: It is done this way in order to allow a tail call on /* NOTE: It is done this way in order to allow a tail call on
chSchReadyI().*/ chSchReadyI().*/
@ -224,11 +226,11 @@ void chSemSignalI(Semaphore *sp) {
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) {
msg_t msg; msg_t msg;
chSysLock(); chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait");
chSysLock();
if (sps->s_cnt++ < 0) if (sps->s_cnt++ < 0)
chSchReadyI(fifo_remove(&sps->s_queue))->p_rdymsg = RDY_OK; chSchReadyI(fifo_remove(&sps->s_queue))->p_rdymsg = RDY_OK;
if (--spw->s_cnt < 0) { if (--spw->s_cnt < 0) {
sem_insert(currp, &spw->s_queue); sem_insert(currp, &spw->s_queue);
currp->p_wtsemp = spw; currp->p_wtsemp = spw;
@ -239,7 +241,6 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) {
chSchRescheduleS(); chSchRescheduleS();
msg = RDY_OK; msg = RDY_OK;
} }
chSysUnlock(); chSysUnlock();
return msg; return msg;
} }

View File

@ -46,6 +46,9 @@ void chFDDInit(FullDuplexDriver *sd,
uint8_t *ib, size_t isize, qnotify_t inotify, uint8_t *ib, size_t isize, qnotify_t inotify,
uint8_t *ob, size_t osize, qnotify_t onotify) { uint8_t *ob, size_t osize, qnotify_t onotify) {
chDbgCheck((sd != NULL) && (ib != NULL) && (ob != NULL) &&
(isize > 0) && (osize > 0), "chFDDInit");
chIQInit(&sd->sd_iqueue, ib, isize, inotify); chIQInit(&sd->sd_iqueue, ib, isize, inotify);
chEvtInit(&sd->sd_ievent); chEvtInit(&sd->sd_ievent);
chOQInit(&sd->sd_oqueue, ob, osize, onotify); chOQInit(&sd->sd_oqueue, ob, osize, onotify);
@ -134,6 +137,8 @@ dflags_t chFDDGetAndClearFlags(FullDuplexDriver *sd) {
void chHDDInit(HalfDuplexDriver *sd, uint8_t *b, size_t size, void chHDDInit(HalfDuplexDriver *sd, uint8_t *b, size_t size,
qnotify_t inotify, qnotify_t onotify) { qnotify_t inotify, qnotify_t onotify) {
chDbgCheck((sd != NULL) && (b != NULL) && (size > 0), "chHDDInit");
chHDQInit(&sd->sd_queue, b, size, inotify, onotify); chHDQInit(&sd->sd_queue, b, size, inotify, onotify);
chEvtInit(&sd->sd_ievent); chEvtInit(&sd->sd_ievent);
chEvtInit(&sd->sd_oevent); chEvtInit(&sd->sd_oevent);

View File

@ -91,9 +91,9 @@ Thread *chThdInit(void *workspace, size_t wsize,
/* thread structure is layed out in the lower part of the thread workspace */ /* thread structure is layed out in the lower part of the thread workspace */
Thread *tp = workspace; Thread *tp = workspace;
chDbgAssert((wsize >= THD_WA_SIZE(0)) && (prio <= HIGHPRIO) && chDbgCheck((workspace != NULL) && (wsize >= THD_WA_SIZE(0)) &&
(workspace != NULL) && (pf != NULL), (prio <= HIGHPRIO) && (pf != NULL),
"chthreads.c, chThdInit()"); "chThdInit");
#if CH_DBG_FILL_THREADS #if CH_DBG_FILL_THREADS
memfill(workspace, wsize, MEM_FILL_PATTERN); memfill(workspace, wsize, MEM_FILL_PATTERN);
#endif #endif
@ -181,6 +181,8 @@ Thread *chThdCreateFromHeap(size_t wsize, tprio_t prio,
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
tfunc_t pf, void *arg) { tfunc_t pf, void *arg) {
chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool");
void *workspace = chPoolAlloc(mp); void *workspace = chPoolAlloc(mp);
if (workspace == NULL) if (workspace == NULL)
return NULL; return NULL;
@ -204,9 +206,10 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
tprio_t chThdSetPriority(tprio_t newprio) { tprio_t chThdSetPriority(tprio_t newprio) {
tprio_t oldprio; tprio_t oldprio;
chDbgAssert(newprio <= HIGHPRIO, "chthreads.c, chThdSetPriority()"); chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO),
chSysLock(); "chThdSetPriority");
chSysLock();
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
oldprio = currp->p_realprio; oldprio = currp->p_realprio;
if ((currp->p_prio == currp->p_realprio) || (newprio > currp->p_prio)) if ((currp->p_prio == currp->p_realprio) || (newprio > currp->p_prio))
@ -217,7 +220,6 @@ tprio_t chThdSetPriority(tprio_t newprio) {
currp->p_prio = newprio; currp->p_prio = newprio;
#endif #endif
chSchRescheduleS(); chSchRescheduleS();
chSysUnlock(); chSysUnlock();
return oldprio; return oldprio;
} }
@ -233,7 +235,9 @@ tprio_t chThdSetPriority(tprio_t newprio) {
Thread *chThdResume(Thread *tp) { Thread *chThdResume(Thread *tp) {
chSysLock(); chSysLock();
chDbgAssert(tp->p_state == PRSUSPENDED, "chthreads.c, chThdResume()"); chDbgAssert(tp->p_state == PRSUSPENDED,
"chThdResume(), #1",
"thread not in PRSUSPENDED state");
chSchWakeupS(tp, RDY_OK); chSchWakeupS(tp, RDY_OK);
chSysUnlock(); chSysUnlock();
return tp; return tp;
@ -329,9 +333,13 @@ void chThdExit(msg_t msg) {
msg_t chThdWait(Thread *tp) { msg_t chThdWait(Thread *tp) {
msg_t msg; msg_t msg;
chDbgCheck(tp != NULL, "chThdWait");
chSysLock(); chSysLock();
chDbgAssert((tp != NULL) && (tp != currp) && (tp->p_waiting == NULL),
"chthreads.c, chThdWait()"); chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self");
chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", "some other thread waiting");
if (tp->p_state != PREXIT) { if (tp->p_state != PREXIT) {
tp->p_waiting = currp; tp->p_waiting = currp;
chSchGoSleepS(PRWAIT); chSchGoSleepS(PRWAIT);

View File

@ -55,7 +55,7 @@ void vt_init(void) {
void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
VirtualTimer *p; VirtualTimer *p;
chDbgAssert(time != 0, "chvt.c, chVTSetI()"); chDbgCheck((vtp != NULL) && (time != 0) && (vtfunc != NULL), "chVTSetI");
vtp->vt_par = par; vtp->vt_par = par;
vtp->vt_func = vtfunc; vtp->vt_func = vtfunc;
@ -80,6 +80,10 @@ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
*/ */
void chVTResetI(VirtualTimer *vtp) { void chVTResetI(VirtualTimer *vtp) {
chDbgCheck(vtp != NULL, "chVTResetI");
chDbgAssert(vtp->vt_func != NULL, "chVTResetI(), #1",
"timer already triggered");
if (vtp->vt_next != (void *)&vtlist) if (vtp->vt_next != (void *)&vtlist)
vtp->vt_next->vt_time += vtp->vt_time; vtp->vt_next->vt_time += vtp->vt_time;
vtp->vt_prev->vt_next = vtp->vt_next; vtp->vt_prev->vt_next = vtp->vt_next;

View File

@ -60,27 +60,53 @@ typedef struct {
CtxSwcEvent tb_buffer[TRACE_BUFFER_SIZE]; /**< Ring buffer.*/ CtxSwcEvent tb_buffer[TRACE_BUFFER_SIZE]; /**< Ring buffer.*/
} TraceBuffer; } TraceBuffer;
#define __QUOTE_THIS(p) #p
#if CH_DBG_ENABLE_CHECKS
/**
* Function parameter check, if the condition check fails then the kernel
* panics.
* @param c the condition to be verified to be true
* @param m the undecorated function name
* @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch is
* specified in @p chconf.h else the macro does nothing.
*/
#define chDbgCheck(c, func) { \
if (!(c)) \
chDbgPanic(__QUOTE_THIS(func)"(), line "__QUOTE_THIS(__LINE__)); \
}
#else /* !CH_DBG_ENABLE_CHECKS */
#define chDbgCheck(c, func) { \
(void)(c), (void)__QUOTE_THIS(func)"(), line "__QUOTE_THIS(__LINE__); \
}
#endif /* !CH_DBG_ENABLE_CHECKS */
#if CH_DBG_ENABLE_ASSERTS #if CH_DBG_ENABLE_ASSERTS
/** /**
* Condition assertion, if the condition check fails then the kernel panics * Condition assertion, if the condition check fails then the kernel panics
* with the specified message. * with the specified message.
* @param c the condition to be verified to be true * @param c the condition to be verified to be true
* @param m the text message * @param m the text message
* @param r a remark string
* @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch is * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch is
* specified in @p chconf.h else the macro does nothing. * specified in @p chconf.h else the macro does nothing.
* @note The convention for the message is the following:<br>
* @<function_name@>(), #@<assert_number@>
* @note The remark string is not currently used except for putting a comment
* in the code about the assert.
*/ */
#define chDbgAssert(c, m) { \ #define chDbgAssert(c, m, r) { \
if (!(c)) \ if (!(c)) \
chDbgPanic(m); \ chDbgPanic(m); \
} }
#else /* !CH_DBG_ENABLE_ASSERTS */ #else /* !CH_DBG_ENABLE_ASSERTS */
#define chDbgAssert(c, m, r) {(void)(c);}
#define chDbgPanic(msg) {}
#define chDbgAssert(c, m) {(void)(c);}
#endif /* !CH_DBG_ENABLE_ASSERTS */ #endif /* !CH_DBG_ENABLE_ASSERTS */
#if !(CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK)
#define chDbgPanic(msg) {}
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -89,7 +115,7 @@ extern "C" {
void trace_init(void); void trace_init(void);
void chDbgTrace(Thread *otp, Thread *ntp); void chDbgTrace(Thread *otp, Thread *ntp);
#endif #endif
#if CH_DBG_ENABLE_ASSERTS #if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
extern char *panic_msg; extern char *panic_msg;
void chDbgPanic(char *msg); void chDbgPanic(char *msg);
#endif #endif

View File

@ -335,9 +335,18 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* Debug option, if enabled all the assertions in the kernel code are * Debug option, if enabled then the checks on the API functions input
* activated. This includes function parameters checks and consistency * parameters are activated.
* checks inside the kernel. * @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* Debug option, if enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel, runtime
* anomalies and port-defined checks.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

@ -13,12 +13,14 @@ After 1.0.0:
implemented this as the new Suspended and Disabled states in 1.1. implemented this as the new Suspended and Disabled states in 1.1.
* Mailboxes subsystem (lwIP requires them). * Mailboxes subsystem (lwIP requires them).
* Multiple debug switches. * Multiple debug switches.
- Split asserts from parameters checks. * Split asserts from parameters checks.
- Add checks to all APIs. * Add checks to all APIs.
X Stack checks option. X Stack checks option.
* Threads profiling option. * Threads profiling option.
* Idle loop hook macro. * Idle loop hook macro.
* Switch the configuration options to TRUE/FALSE rather than def/undef. * Switch the configuration options to TRUE/FALSE rather than def/undef.
X Remove port_puts() from all the ports.
- Look into the wrong mutex assert.
After 1.2.0: After 1.2.0:
- Threads Pools manager in the library. - Threads Pools manager in the library.