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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
@ -359,7 +368,7 @@
* may not be implemented at all.
*/
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_STACK_CHECK FALSE
#define CH_DBG_ENABLE_STACK_CHECK TRUE
#endif
/**
@ -367,7 +376,7 @@
* pattern when a thread is created.
*/
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
#define CH_DBG_FILL_THREADS FALSE
#define CH_DBG_FILL_THREADS TRUE
#endif
/**

View File

@ -335,9 +335,18 @@
/*===========================================================================*/
/**
* Debug option, if enabled all the assertions in the kernel code are
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)

View File

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

View File

@ -178,7 +178,7 @@ struct context {
/**
* 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.
@ -281,11 +281,23 @@ struct context {
/**
* 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) { \
register Thread *_otp asm ("r0") = (otp); \
register Thread *_ntp asm ("r1") = (ntp); \
asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp)); \
}
#endif /* !CH_DBG_ENABLE_STACK_CHECK */
#ifdef __cplusplus
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.
- NEW: Mailboxes (asynchronous messages) subsystem and test cases added.
- 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_DBG_FILL_THREADS.
and CH_USE_TRACE. Replaced with CH_DBG_ENABLE_CHECKS, SCH_DBG_ENABLE_ASSERTS,
CH_DBG_ENABLE_TRACE and CH_DBG_FILL_THREADS.
- NEW: Added a debug option CH_DBG_THREADS_PROFILING for threads profiling.
A field into the Thread structure counts the consumed time. The information
is not used into the kernel, it is meant for debugging.
- 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.
Currently no ports implement it.
Currently no port implements it.
- NEW: Unified makefiles for ARM7 and ARMCM3 projects, the new makefiles
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

View File

@ -42,6 +42,8 @@
*/
void chCondInit(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondInit");
queue_init(&cp->c_queue);
}
@ -52,11 +54,11 @@ void chCondInit(CondVar *cp) {
*/
void chCondSignal(CondVar *cp) {
chSysLock();
chDbgCheck(cp != NULL, "chCondSignal");
chSysLock();
if (notempty(&cp->c_queue)) /* any thread ? */
chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK);
chSysUnlock();
}
@ -67,6 +69,8 @@ void chCondSignal(CondVar *cp) {
*/
void chCondSignalI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondSignalI");
if (notempty(&cp->c_queue)) /* any thread ? */
chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_OK;
}
@ -79,10 +83,8 @@ void chCondSignalI(CondVar *cp) {
void chCondBroadcast(CondVar *cp) {
chSysLock();
chCondBroadcastI(cp);
chSchRescheduleS();
chSysUnlock();
}
@ -93,6 +95,8 @@ void chCondBroadcast(CondVar *cp) {
*/
void chCondBroadcastI(CondVar *cp) {
chDbgCheck(cp != NULL, "chCondBroadcastI");
/* 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
* order to make a chCondBroadcast() detectable from a chCondSignal(). */
@ -116,9 +120,7 @@ msg_t chCondWait(CondVar *cp) {
msg_t msg;
chSysLock();
msg = chCondWaitS(cp);
chSysUnlock();
return msg;
}
@ -139,7 +141,10 @@ msg_t chCondWaitS(CondVar *cp) {
Mutex *mp;
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 */
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;
chSysLock();
msg = chCondWaitTimeoutS(cp, time);
chSysUnlock();
return msg;
}
@ -196,7 +199,10 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
Mutex *mp;
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 */
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 */
#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.
* @details This pointer is meant to be accessed through the debugger, it is
@ -74,10 +74,8 @@ char *panic_msg;
void chDbgPanic(char *msg) {
panic_msg = msg;
chSysPuts("PANIC: ");
chSysPuts(msg);
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) {
chSysLock();
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask");
chSysLock();
elp->el_next = esp->es_next;
esp->es_next = elp;
elp->el_listener = currp;
elp->el_mask = emask;
chSysUnlock();
}
@ -59,10 +59,12 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask)
* found on top of the list).
*/
void chEvtUnregister(EventSource *esp, EventListener *elp) {
EventListener *p = (EventListener *)esp;
EventListener *p;
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtUnregister");
p = (EventListener *)esp;
chSysLock();
while (p->el_next != (EventListener *)esp) {
if (p->el_next == elp) {
p->el_next = elp->el_next;
@ -70,7 +72,6 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) {
}
p = p->el_next;
}
chSysUnlock();
}
@ -117,10 +118,10 @@ eventmask_t chEvtPend(eventmask_t mask) {
*/
void chEvtSignal(Thread *tp, eventmask_t mask) {
chDbgCheck(tp != NULL, "chEvtSignal");
chSysLock();
chEvtSignalI(tp, mask);
chSysUnlock();
}
@ -132,8 +133,9 @@ void chEvtSignal(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.*/
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)))
@ -149,10 +151,8 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) {
void chEvtBroadcast(EventSource *esp) {
chSysLock();
chEvtBroadcastI(esp);
chSchRescheduleS();
chSysUnlock();
}
@ -165,6 +165,8 @@ void chEvtBroadcast(EventSource *esp) {
void chEvtBroadcastI(EventSource *esp) {
EventListener *elp;
chDbgCheck(esp != NULL, "chEvtBroadcastI");
elp = esp->es_next;
while (elp != (EventListener *)esp) {
chEvtSignalI(elp->el_listener, elp->el_mask);
@ -183,9 +185,14 @@ void chEvtBroadcastI(EventSource *esp) {
void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) {
eventid_t eid;
chDbgCheck(handlers != NULL, "chEvtDispatch");
eid = 0;
while (mask) {
if (mask & EVENT_MASK(eid)) {
chDbgAssert(handlers[eid] != NULL,
"chEvtDispatch(), #1",
"null handler");
mask &= ~EVENT_MASK(eid);
handlers[eid](eid);
}

View File

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

View File

@ -27,7 +27,6 @@
#include <ch.h>
#if CH_USE_MAILBOXES
/**
* @brief Initializes a Mailbox object.
*
@ -37,6 +36,8 @@
*/
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_top = &buf[n];
chSemInit(&mbp->mb_emptysem, n);
@ -52,6 +53,8 @@ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) {
*/
void chMBReset(Mailbox *mbp) {
chDbgCheck(mbp != NULL, "chMBReset");
chSysLock();
mbp->mb_wrptr = mbp->mb_rdptr = 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 rdymsg;
chDbgCheck(mbp != NULL, "chMBPost");
chSysLock();
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout);
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 rdymsg;
chDbgCheck(mbp != NULL, "chMBPostAhead");
chSysLock();
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout);
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 rdymsg;
chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetch");
chSysLock();
rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, timeout);
if (rdymsg == RDY_OK) {

View File

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

View File

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

View File

@ -38,6 +38,8 @@
*/
void chMtxInit(Mutex *mp) {
chDbgCheck(mp != NULL, "chMtxInit");
queue_init(&mp->m_queue);
mp->m_owner = NULL;
}
@ -64,6 +66,9 @@ void chMtxLock(Mutex *mp) {
* block.
*/
void chMtxLockS(Mutex *mp) {
chDbgCheck(mp != NULL, "chMtxLockS");
/* the mutex is already locked? */
if (mp->m_owner != NULL) {
/*
@ -112,7 +117,7 @@ void chMtxLockS(Mutex *mp) {
/* thread remembers the mutex where it is waiting on */
currp->p_wtmtxp = mp;
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.
@ -156,6 +161,8 @@ bool_t chMtxTryLock(Mutex *mp) {
*/
bool_t chMtxTryLockS(Mutex *mp) {
chDbgCheck(mp != NULL, "chMtxTryLockS");
if (mp->m_owner != NULL)
return FALSE;
mp->m_owner = currp;
@ -173,10 +180,12 @@ Mutex *chMtxUnlock(void) {
Mutex *ump, *mp;
chSysLock();
chDbgAssert((currp->p_mtxlist != NULL) && (currp->p_mtxlist->m_owner == currp),
"chmtx.c, chMtxUnlock()");
chDbgAssert(currp->p_mtxlist != NULL,
"chMtxUnlock(), #1",
"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 */
ump = currp->p_mtxlist;
currp->p_mtxlist = ump->m_next;
@ -221,8 +230,12 @@ Mutex *chMtxUnlock(void) {
Mutex *chMtxUnlockS(void) {
Mutex *ump, *mp;
chDbgAssert((currp->p_mtxlist != NULL) && (currp->p_mtxlist->m_owner == currp),
"chmtx.c, chMtxUnlockS()");
chDbgAssert(currp->p_mtxlist != NULL,
"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.
@ -261,7 +274,6 @@ Mutex *chMtxUnlockS(void) {
void chMtxUnlockAll(void) {
chSysLock();
if (currp->p_mtxlist != NULL) {
do {
Mutex *mp = currp->p_mtxlist;
@ -273,7 +285,6 @@ void chMtxUnlockAll(void) {
currp->p_prio = currp->p_realprio;
chSchRescheduleS();
}
chSysUnlock();
}

View File

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

View File

@ -46,6 +46,9 @@ void chFDDInit(FullDuplexDriver *sd,
uint8_t *ib, size_t isize, qnotify_t inotify,
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);
chEvtInit(&sd->sd_ievent);
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,
qnotify_t inotify, qnotify_t onotify) {
chDbgCheck((sd != NULL) && (b != NULL) && (size > 0), "chHDDInit");
chHDQInit(&sd->sd_queue, b, size, inotify, onotify);
chEvtInit(&sd->sd_ievent);
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 *tp = workspace;
chDbgAssert((wsize >= THD_WA_SIZE(0)) && (prio <= HIGHPRIO) &&
(workspace != NULL) && (pf != NULL),
"chthreads.c, chThdInit()");
chDbgCheck((workspace != NULL) && (wsize >= THD_WA_SIZE(0)) &&
(prio <= HIGHPRIO) && (pf != NULL),
"chThdInit");
#if CH_DBG_FILL_THREADS
memfill(workspace, wsize, MEM_FILL_PATTERN);
#endif
@ -181,6 +181,8 @@ Thread *chThdCreateFromHeap(size_t wsize, tprio_t prio,
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
tfunc_t pf, void *arg) {
chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool");
void *workspace = chPoolAlloc(mp);
if (workspace == NULL)
return NULL;
@ -204,9 +206,10 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
tprio_t chThdSetPriority(tprio_t newprio) {
tprio_t oldprio;
chDbgAssert(newprio <= HIGHPRIO, "chthreads.c, chThdSetPriority()");
chSysLock();
chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO),
"chThdSetPriority");
chSysLock();
#if CH_USE_MUTEXES
oldprio = currp->p_realprio;
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;
#endif
chSchRescheduleS();
chSysUnlock();
return oldprio;
}
@ -233,7 +235,9 @@ tprio_t chThdSetPriority(tprio_t newprio) {
Thread *chThdResume(Thread *tp) {
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);
chSysUnlock();
return tp;
@ -329,9 +333,13 @@ void chThdExit(msg_t msg) {
msg_t chThdWait(Thread *tp) {
msg_t msg;
chDbgCheck(tp != NULL, "chThdWait");
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) {
tp->p_waiting = currp;
chSchGoSleepS(PRWAIT);

View File

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

View File

@ -60,27 +60,53 @@ typedef struct {
CtxSwcEvent tb_buffer[TRACE_BUFFER_SIZE]; /**< Ring buffer.*/
} 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
/**
* Condition assertion, if the condition check fails then the kernel panics
* with the specified message.
* @param c the condition to be verified to be true
* @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
* 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)) \
chDbgPanic(m); \
}
#else /* !CH_DBG_ENABLE_ASSERTS */
#define chDbgPanic(msg) {}
#define chDbgAssert(c, m) {(void)(c);}
#define chDbgAssert(c, m, r) {(void)(c);}
#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
extern "C" {
#endif
@ -89,7 +115,7 @@ extern "C" {
void trace_init(void);
void chDbgTrace(Thread *otp, Thread *ntp);
#endif
#if CH_DBG_ENABLE_ASSERTS
#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
extern char *panic_msg;
void chDbgPanic(char *msg);
#endif

View File

@ -335,9 +335,18 @@
/*===========================================================================*/
/**
* Debug option, if enabled all the assertions in the kernel code are
* activated. This includes function parameters checks and consistency
* checks inside the kernel.
* Debug option, if enabled then the checks on the API functions input
* parameters are activated.
* @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.
*/
#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.
* Mailboxes subsystem (lwIP requires them).
* Multiple debug switches.
- Split asserts from parameters checks.
- Add checks to all APIs.
* Split asserts from parameters checks.
* Add checks to all APIs.
X Stack checks option.
* Threads profiling option.
* Idle loop hook macro.
* 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:
- Threads Pools manager in the library.