Fixed stack limit conditions in RT4.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9224 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
e8f67437d0
commit
71f174d00d
|
@ -104,7 +104,9 @@ static void sd1_handler(eventid_t id) {
|
||||||
flags = chEvtGetAndClearFlags(&sd1fel);
|
flags = chEvtGetAndClearFlags(&sd1fel);
|
||||||
if ((flags & CHN_CONNECTED) && (shelltp1 == NULL)) {
|
if ((flags & CHN_CONNECTED) && (shelltp1 == NULL)) {
|
||||||
cputs("Init: connection on SD1");
|
cputs("Init: connection on SD1");
|
||||||
shelltp1 = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO + 1);
|
shelltp1 = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
|
||||||
|
"shell1", NORMALPRIO + 10,
|
||||||
|
shellThread, (void *)&shell_cfg1);
|
||||||
}
|
}
|
||||||
if (flags & CHN_DISCONNECTED) {
|
if (flags & CHN_DISCONNECTED) {
|
||||||
cputs("Init: disconnection on SD1");
|
cputs("Init: disconnection on SD1");
|
||||||
|
@ -127,7 +129,9 @@ static void sd2_handler(eventid_t id) {
|
||||||
flags = chEvtGetAndClearFlags(&sd2fel);
|
flags = chEvtGetAndClearFlags(&sd2fel);
|
||||||
if ((flags & CHN_CONNECTED) && (shelltp2 == NULL)) {
|
if ((flags & CHN_CONNECTED) && (shelltp2 == NULL)) {
|
||||||
cputs("Init: connection on SD2");
|
cputs("Init: connection on SD2");
|
||||||
shelltp2 = shellCreate(&shell_cfg2, SHELL_WA_SIZE, NORMALPRIO + 10);
|
shelltp2 = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
|
||||||
|
"shell2", NORMALPRIO + 10,
|
||||||
|
shellThread, (void *)&shell_cfg2);
|
||||||
}
|
}
|
||||||
if (flags & CHN_DISCONNECTED) {
|
if (flags & CHN_DISCONNECTED) {
|
||||||
cputs("Init: disconnection on SD2");
|
cputs("Init: disconnection on SD2");
|
||||||
|
|
|
@ -337,7 +337,7 @@ struct port_context {
|
||||||
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
register struct port_intctx *r13 asm ("r13"); \
|
register struct port_intctx *r13 asm ("r13"); \
|
||||||
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
|
if ((stkalign_t *)(r13 - 1) < otp->wabase) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch_thumb(ntp, otp); \
|
_port_switch_thumb(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ struct port_context {
|
||||||
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
register struct port_intctx *r13 asm ("r13"); \
|
register struct port_intctx *r13 asm ("r13"); \
|
||||||
if ((stkalign_t *)(r13 - 1) < otp->stklimit) \
|
if ((stkalign_t *)(r13 - 1) < otp->wabase) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch_arm(ntp, otp); \
|
_port_switch_arm(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,7 +285,7 @@ struct port_intctx {
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||||
if ((stkalign_t *)(r13 - 1) < (otp)->stklimit) { \
|
if ((stkalign_t *)(r13 - 1) < (otp)->wabase) { \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
} \
|
} \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
|
|
|
@ -440,7 +440,7 @@ struct port_intctx {
|
||||||
#if PORT_ENABLE_GUARD_PAGES == FALSE
|
#if PORT_ENABLE_GUARD_PAGES == FALSE
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||||
if ((stkalign_t *)(r13 - 1) < (otp)->stklimit) { \
|
if ((stkalign_t *)(r13 - 1) < (otp)->wabase) { \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
} \
|
} \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
|
@ -451,7 +451,7 @@ struct port_intctx {
|
||||||
\
|
\
|
||||||
/* Setting up the guard page for the switched-in thread.*/ \
|
/* Setting up the guard page for the switched-in thread.*/ \
|
||||||
mpuConfigureRegion(MPU_REGION_0, \
|
mpuConfigureRegion(MPU_REGION_0, \
|
||||||
chThdGetSelfX()->stklimit, \
|
chThdGetSelfX()->wabase, \
|
||||||
MPU_RASR_ATTR_AP_NA_NA | \
|
MPU_RASR_ATTR_AP_NA_NA | \
|
||||||
MPU_RASR_ATTR_NON_CACHEABLE | \
|
MPU_RASR_ATTR_NON_CACHEABLE | \
|
||||||
MPU_RASR_SIZE_32 | \
|
MPU_RASR_SIZE_32 | \
|
||||||
|
|
|
@ -392,7 +392,7 @@ struct port_context {
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
register struct port_intctx *sp asm ("%r1"); \
|
register struct port_intctx *sp asm ("%r1"); \
|
||||||
if ((stkalign_t *)(sp - 1) < otp->stklimit) \
|
if ((stkalign_t *)(sp - 1) < otp->wabase) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ struct port_context {
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
register struct port_intctx *sp asm ("%r1"); \
|
register struct port_intctx *sp asm ("%r1"); \
|
||||||
if ((stkalign_t *)(sp - 1) < otp->stklimit) \
|
if ((stkalign_t *)(sp - 1) < otp->wabase) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,7 +492,7 @@ struct nil_thread {
|
||||||
eventmask_t epmask; /**< @brief Pending events mask. */
|
eventmask_t epmask; /**< @brief Pending events mask. */
|
||||||
#endif
|
#endif
|
||||||
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
|
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
|
||||||
stkalign_t *stklimit; /**< @brief Thread stack boundary. */
|
stkalign_t *wabase; /**< @brief Thread stack boundary. */
|
||||||
#endif
|
#endif
|
||||||
/* Optional extra fields.*/
|
/* Optional extra fields.*/
|
||||||
CH_CFG_THREAD_EXT_FIELDS
|
CH_CFG_THREAD_EXT_FIELDS
|
||||||
|
|
|
@ -234,7 +234,7 @@ void chSysInit(void) {
|
||||||
tcp = nil_thd_configs;
|
tcp = nil_thd_configs;
|
||||||
while (tp < &nil.threads[CH_CFG_NUM_THREADS]) {
|
while (tp < &nil.threads[CH_CFG_NUM_THREADS]) {
|
||||||
#if CH_DBG_ENABLE_STACK_CHECK
|
#if CH_DBG_ENABLE_STACK_CHECK
|
||||||
tp->stklimit = (stkalign_t *)tcp->wbase;
|
tp->wabase = (stkalign_t *)tcp->wbase;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Port dependent thread initialization.*/
|
/* Port dependent thread initialization.*/
|
||||||
|
@ -250,7 +250,7 @@ void chSysInit(void) {
|
||||||
#if CH_DBG_ENABLE_STACK_CHECK
|
#if CH_DBG_ENABLE_STACK_CHECK
|
||||||
/* The idle thread is a special case because its stack is set up by the
|
/* The idle thread is a special case because its stack is set up by the
|
||||||
runtime environment.*/
|
runtime environment.*/
|
||||||
tp->stklimit = THD_IDLE_BASE;
|
tp->wabase = THD_IDLE_BASE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interrupts partially enabled. It is equivalent to entering the
|
/* Interrupts partially enabled. It is equivalent to entering the
|
||||||
|
|
|
@ -169,11 +169,15 @@ struct ch_thread {
|
||||||
*/
|
*/
|
||||||
const char *name;
|
const char *name;
|
||||||
#endif
|
#endif
|
||||||
|
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
|
||||||
|
defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Thread stack boundary.
|
* @brief Working area base address.
|
||||||
* @note This pointer matches with the working area base address.
|
* @note This pointer is used for stack overflow checks and for
|
||||||
|
* dynamic threading.
|
||||||
*/
|
*/
|
||||||
stkalign_t *stklimit;
|
stkalign_t *wabase;
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* @brief Current thread state.
|
* @brief Current thread state.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -307,18 +307,21 @@ static inline systime_t chThdGetTicksX(thread_t *tp) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
|
||||||
|
defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Returns the stack limit of the specified thread.
|
* @brief Returns the working area base of the specified thread.
|
||||||
*
|
*
|
||||||
* @param[in] tp pointer to the thread
|
* @param[in] tp pointer to the thread
|
||||||
* @return The stack limit pointer.
|
* @return The working area base pointer.
|
||||||
*
|
*
|
||||||
* @xclass
|
* @xclass
|
||||||
*/
|
*/
|
||||||
static inline stkalign_t *chthdGetStackLimitX(thread_t *tp) {
|
static inline stkalign_t *chThdGetWorkingAreaX(thread_t *tp) {
|
||||||
|
|
||||||
return tp->stklimit;
|
return tp->wabase;
|
||||||
}
|
}
|
||||||
|
#endif /* CH_DBG_ENABLE_STACK_CHECK == TRUE */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Verifies if the specified thread is in the @p CH_STATE_FINAL state.
|
* @brief Verifies if the specified thread is in the @p CH_STATE_FINAL state.
|
||||||
|
|
|
@ -95,8 +95,8 @@ ROMCONST chdebug_t ch_debug = {
|
||||||
(uint8_t)_offsetof(thread_t, newer),
|
(uint8_t)_offsetof(thread_t, newer),
|
||||||
(uint8_t)_offsetof(thread_t, older),
|
(uint8_t)_offsetof(thread_t, older),
|
||||||
(uint8_t)_offsetof(thread_t, name),
|
(uint8_t)_offsetof(thread_t, name),
|
||||||
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE)
|
||||||
(uint8_t)_offsetof(thread_t, stklimit),
|
(uint8_t)_offsetof(thread_t, wabase),
|
||||||
#else
|
#else
|
||||||
(uint8_t)0,
|
(uint8_t)0,
|
||||||
#endif
|
#endif
|
||||||
|
@ -233,6 +233,8 @@ thread_t *chRegFindThreadByPointer(thread_t *tp) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
|
||||||
|
defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Confirms that a working area is being used by some active thread.
|
* @brief Confirms that a working area is being used by some active thread.
|
||||||
* @note The reference counter of the found thread is increased by one so
|
* @note The reference counter of the found thread is increased by one so
|
||||||
|
@ -251,7 +253,7 @@ thread_t *chRegFindThreadByWorkingArea(stkalign_t *wa) {
|
||||||
/* Scanning registry.*/
|
/* Scanning registry.*/
|
||||||
ctp = chRegFirstThread();
|
ctp = chRegFirstThread();
|
||||||
do {
|
do {
|
||||||
if (ctp->stklimit == wa) {
|
if (chThdGetWorkingAreaX(ctp) == wa) {
|
||||||
return ctp;
|
return ctp;
|
||||||
}
|
}
|
||||||
ctp = chRegNextThread(ctp);
|
ctp = chRegNextThread(ctp);
|
||||||
|
@ -259,6 +261,7 @@ thread_t *chRegFindThreadByWorkingArea(stkalign_t *wa) {
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CH_CFG_USE_REGISTRY == TRUE */
|
#endif /* CH_CFG_USE_REGISTRY == TRUE */
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,6 @@ static void _idle_thread(void *p) {
|
||||||
* @special
|
* @special
|
||||||
*/
|
*/
|
||||||
void chSysInit(void) {
|
void chSysInit(void) {
|
||||||
extern stkalign_t __main_thread_stack_base__;
|
|
||||||
|
|
||||||
_scheduler_init();
|
_scheduler_init();
|
||||||
_vt_init();
|
_vt_init();
|
||||||
|
@ -135,8 +134,16 @@ void chSysInit(void) {
|
||||||
currp = _thread_init(&ch.mainthread, "idle", IDLEPRIO);
|
currp = _thread_init(&ch.mainthread, "idle", IDLEPRIO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setting up the base address of the static main thread stack.*/
|
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||||
currp->stklimit = &__main_thread_stack_base__;
|
{
|
||||||
|
/* Setting up the base address of the static main thread stack, the
|
||||||
|
symbol must be provided externally.*/
|
||||||
|
extern stkalign_t __main_thread_stack_base__;
|
||||||
|
currp->wabase = &__main_thread_stack_base__;
|
||||||
|
}
|
||||||
|
#elif CH_CFG_USE_DYNAMIC == TRUE
|
||||||
|
currp->wabase = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Setting up the caller as current thread.*/
|
/* Setting up the caller as current thread.*/
|
||||||
currp->state = CH_STATE_CURRENT;
|
currp->state = CH_STATE_CURRENT;
|
||||||
|
|
|
@ -182,8 +182,10 @@ thread_t *chThdCreateSuspendedI(const thread_descriptor_t *tdp) {
|
||||||
tp = (thread_t *)((uint8_t *)tdp->wend -
|
tp = (thread_t *)((uint8_t *)tdp->wend -
|
||||||
MEM_ALIGN_NEXT(sizeof (thread_t), PORT_STACK_ALIGN));
|
MEM_ALIGN_NEXT(sizeof (thread_t), PORT_STACK_ALIGN));
|
||||||
|
|
||||||
|
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE)
|
||||||
/* Stack boundary.*/
|
/* Stack boundary.*/
|
||||||
tp->stklimit = tdp->wbase;
|
tp->wabase = tdp->wbase;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Setting up the port-dependent part of the working area.*/
|
/* Setting up the port-dependent part of the working area.*/
|
||||||
PORT_SETUP_CONTEXT(tp, tdp->wbase, tp, tdp->funcp, tdp->arg);
|
PORT_SETUP_CONTEXT(tp, tdp->wbase, tp, tdp->funcp, tdp->arg);
|
||||||
|
@ -348,8 +350,10 @@ thread_t *chThdCreateStatic(void *wsp, size_t size,
|
||||||
tp = (thread_t *)((uint8_t *)wsp + size -
|
tp = (thread_t *)((uint8_t *)wsp + size -
|
||||||
MEM_ALIGN_NEXT(sizeof (thread_t), PORT_STACK_ALIGN));
|
MEM_ALIGN_NEXT(sizeof (thread_t), PORT_STACK_ALIGN));
|
||||||
|
|
||||||
|
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE)
|
||||||
/* Stack boundary.*/
|
/* Stack boundary.*/
|
||||||
tp->stklimit = (stkalign_t *)wsp;
|
tp->wabase = (stkalign_t *)wsp;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Setting up the port-dependent part of the working area.*/
|
/* Setting up the port-dependent part of the working area.*/
|
||||||
PORT_SETUP_CONTEXT(tp, wsp, tp, pf, arg);
|
PORT_SETUP_CONTEXT(tp, wsp, tp, pf, arg);
|
||||||
|
@ -436,12 +440,12 @@ void chThdRelease(thread_t *tp) {
|
||||||
switch (tp->flags & CH_FLAG_MODE_MASK) {
|
switch (tp->flags & CH_FLAG_MODE_MASK) {
|
||||||
#if CH_CFG_USE_HEAP == TRUE
|
#if CH_CFG_USE_HEAP == TRUE
|
||||||
case CH_FLAG_MODE_HEAP:
|
case CH_FLAG_MODE_HEAP:
|
||||||
chHeapFree(chthdGetStackLimitX(tp));
|
chHeapFree(chThdGetWorkingAreaX(tp));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if CH_CFG_USE_MEMPOOLS == TRUE
|
#if CH_CFG_USE_MEMPOOLS == TRUE
|
||||||
case CH_FLAG_MODE_MPOOL:
|
case CH_FLAG_MODE_MPOOL:
|
||||||
chPoolFree(tp->mpool, chthdGetStackLimitX(tp));
|
chPoolFree(tp->mpool, chThdGetWorkingAreaX(tp));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -161,8 +161,13 @@ static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) {
|
||||||
chprintf(chp, "stklimit stack addr refs prio state name\r\n");
|
chprintf(chp, "stklimit stack addr refs prio state name\r\n");
|
||||||
tp = chRegFirstThread();
|
tp = chRegFirstThread();
|
||||||
do {
|
do {
|
||||||
|
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||||
|
uint32_t stklimit = (uint32_t)tp->stklimit;
|
||||||
|
#else
|
||||||
|
uint32_t stklimit = 0U;
|
||||||
|
#endif
|
||||||
chprintf(chp, "%08lx %08lx %08lx %4lu %4lu %9s %12s\r\n",
|
chprintf(chp, "%08lx %08lx %08lx %4lu %4lu %9s %12s\r\n",
|
||||||
(uint32_t)tp->stklimit, (uint32_t)tp->ctx.sp, (uint32_t)tp,
|
stklimit, (uint32_t)tp->ctx.sp, (uint32_t)tp,
|
||||||
(uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state],
|
(uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state],
|
||||||
tp->name == NULL ? "" : tp->name);
|
tp->name == NULL ? "" : tp->name);
|
||||||
tp = chRegNextThread(tp);
|
tp = chRegNextThread(tp);
|
||||||
|
|
Loading…
Reference in New Issue