summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/common
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-03-23 10:11:58 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-03-23 10:11:58 -0600
commitd15a9cedd177e357a1b6bd8adbfbedd73448906e (patch)
treebee64cfdfeccf84acf54db0e1334de370648b700 /nuttx/arch/arm/src/common
parent9acd7deb2a7d40d8134706cc0f9434375475abe1 (diff)
downloadnuttx-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.c82
-rw-r--r--nuttx/arch/arm/src/common/up_initialize.c30
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();