diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-03-23 10:11:58 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-03-23 10:11:58 -0600 |
commit | d15a9cedd177e357a1b6bd8adbfbedd73448906e (patch) | |
tree | bee64cfdfeccf84acf54db0e1334de370648b700 /nuttx/arch/arm/src/common | |
parent | 9acd7deb2a7d40d8134706cc0f9434375475abe1 (diff) | |
download | nuttx-d15a9cedd177e357a1b6bd8adbfbedd73448906e.tar.gz nuttx-d15a9cedd177e357a1b6bd8adbfbedd73448906e.tar.bz2 nuttx-d15a9cedd177e357a1b6bd8adbfbedd73448906e.zip |
Add logic to check interrupt stack usage
Diffstat (limited to 'nuttx/arch/arm/src/common')
-rw-r--r-- | nuttx/arch/arm/src/common/up_checkstack.c | 82 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_initialize.c | 30 |
2 files changed, 97 insertions, 15 deletions
diff --git a/nuttx/arch/arm/src/common/up_checkstack.c b/nuttx/arch/arm/src/common/up_checkstack.c index 9cf4c684f..02f95f7ba 100644 --- a/nuttx/arch/arm/src/common/up_checkstack.c +++ b/nuttx/arch/arm/src/common/up_checkstack.c @@ -44,27 +44,31 @@ #include <sched.h> #include <debug.h> -#include <nuttx/arch.h> +#include <nuttx/arch.h> #include "os_internal.h" #include "up_internal.h" -#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK) - /**************************************************************************** - * Private Types + * Pre-processor Definitions ****************************************************************************/ +#if !defined(CONFIG_DEBUG) +# undef CONFIG_DEBUG_STACK +#endif + +#if defined(CONFIG_DEBUG_STACK) + /**************************************************************************** - * Private Function Prototypes + * Public Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Private Function Prototypes ****************************************************************************/ /**************************************************************************** - * Name: up_check_stack + * Name: do_stackcheck * * Description: * Determine (approximately) how much stack has been used be searching the @@ -72,25 +76,34 @@ * stack that clobbered some recognizable marker in the stack memory. * * Input Parameters: - * None + * alloc - Allocation base address of the stack + * size - The size of the stack in bytes * * Returned value: * The estimated amount of stack space used. * ****************************************************************************/ -size_t up_check_tcbstack(FAR struct tcb_s *tcb) +size_t do_stackcheck(uintptr_t alloc, size_t size) { + FAR uintptr_t start; + FAR uintptr_t end; FAR uint32_t *ptr; size_t mark; + /* Get aligned addresses and adjusted sizes */ + + start = alloc & ~3; + end = (alloc + size + 3) & ~3; + size = end - start; + /* The ARM uses a push-down stack: the stack grows toward lower addresses * in memory. We need to start at the lowest address in the stack memory * allocation and search to higher addresses. The first word we encounter * that does not have the magic value is the high water mark. */ - for (ptr = (FAR uint32_t *)tcb->stack_alloc_ptr, mark = tcb->adj_stack_size/4; + for (ptr = (FAR uint32_t *)start, mark = (size >> 2); *ptr == STACK_COLOR && mark > 0; ptr++, mark--); @@ -105,12 +118,12 @@ size_t up_check_tcbstack(FAR struct tcb_s *tcb) */ #if 0 - if (mark + 16 > tcb->adj_stack_size/4) + if (mark + 16 > nwords) { int i, j; - ptr = (FAR uint32_t *)tcb->stack_alloc_ptr; - for (i = 0; i < tcb->adj_stack_size; i += 4*64) + ptr = (FAR uint32_t *)start; + for (i = 0; i < size; i += 4*64) { for (j = 0; j < 64; j++) { @@ -123,8 +136,10 @@ size_t up_check_tcbstack(FAR struct tcb_s *tcb) { ch = 'X'; } + up_putc(ch); } + up_putc('\n'); } } @@ -132,7 +147,32 @@ size_t up_check_tcbstack(FAR struct tcb_s *tcb) /* Return our guess about how much stack space was used */ - return mark*4; + return mark << 2; +} + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_check_stack and friends + * + * Description: + * Determine (approximately) how much stack has been used be searching the + * stack memory for a high water mark. That is, the deepest level of the + * stack that clobbered some recognizable marker in the stack memory. + * + * Input Parameters: + * None + * + * Returned value: + * The estimated amount of stack space used. + * + ****************************************************************************/ + +size_t up_check_tcbstack(FAR struct tcb_s *tcb) +{ + return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size); } ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) @@ -150,4 +190,16 @@ ssize_t up_check_stack_remain(void) return up_check_tcbstack_remain((FAR struct tcb_s*)g_readytorun.head); } -#endif /* CONFIG_DEBUG && CONFIG_DEBUG_STACK */ +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +size_t up_check_intstack(void) +{ + return do_stackcheck((uintptr_t)&g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)); +} + +size_t up_check_intstack_remain(void) +{ + return (CONFIG_ARCH_INTERRUPTSTACK & ~3) - up_check_intstack(); +} +#endif + +#endif /* CONFIG_DEBUG_STACK */ diff --git a/nuttx/arch/arm/src/common/up_initialize.c b/nuttx/arch/arm/src/common/up_initialize.c index feb5011ce..2d9bb7988 100644 --- a/nuttx/arch/arm/src/common/up_initialize.c +++ b/nuttx/arch/arm/src/common/up_initialize.c @@ -88,6 +88,32 @@ static void up_calibratedelay(void) #endif /**************************************************************************** + * Name: up_color_intstack + * + * Description: + * Set the interrupt stack to a value so that later we can determine how + * much stack space was used by interrupt handling logic + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_STACK) && CONFIG_ARCH_INTERRUPTSTACK > 3 +static inline void up_color_intstack(void) +{ + uint32_t *ptr = (uint32_t *)&g_intstackalloc; + ssize_t size; + + for (size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + size > 0; + size -= sizeof(uint32_t)) + { + *ptr++ = INTSTACK_COLOR; + } +} +#else +# define up_color_intstack() +#endif + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -118,6 +144,10 @@ void up_initialize(void) up_calibratedelay(); + /* Colorize the interrupt stack */ + + up_color_intstack(); + /* Add any extra memory fragments to the memory manager */ up_addregion(); |