Browse Source

Add exception hook function.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2551 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 12 years ago
parent
commit
68fadd9edc
3 changed files with 66 additions and 17 deletions
  1. 6 0
      include/rthw.h
  2. 35 13
      libcpu/arm/cortex-m3/cpuport.c
  3. 25 4
      libcpu/arm/cortex-m4/cpuport.c

+ 6 - 0
include/rthw.h

@@ -12,6 +12,7 @@
  * 2006-03-18     Bernard      the first version
  * 2006-04-25     Bernard      add rt_hw_context_switch_interrupt declaration
  * 2006-09-24     Bernard      add rt_hw_context_switch_to declaration
+ * 2012-12-29     Bernard      add rt_hw_exception_install declaration
  */
 
 #ifndef __RT_HW_H__
@@ -56,6 +57,11 @@ void rt_hw_console_output(const char *str);
 void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry);
 void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size);
 
+/*
+ * exception interfaces
+ */
+void rt_hw_exception_install(void (*exception_handle)(void* context));
+
 #ifdef __cplusplus
 }
 #endif

+ 35 - 13
libcpu/arm/cortex-m3/cpuport.c

@@ -13,6 +13,7 @@
  * 2011-02-14   onelife     Modify for EFM32
  * 2011-06-17   onelife     Merge all of the C source code into cpuport.c
  * 2012-12-23   aozima      stack addr align to 8byte.
+ * 2012-12-29   Bernard     Add exception hook.
  */
 
 #include <rtthread.h>
@@ -47,6 +48,8 @@ struct stack_frame
 /* flag in interrupt handling */
 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
 rt_uint32_t rt_thread_switch_interrupt_flag;
+/* exception hook */
+static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
 
 /**
  * This function will initialize thread stack
@@ -92,23 +95,41 @@ rt_uint8_t *rt_hw_stack_init(void       *tentry,
     return stk;
 }
 
-extern long list_thread(void);
-extern rt_thread_t rt_current_thread;
 /**
- * fault exception handling
+ * This function set the hook, which is invoked on fault exception handling.
+ *
+ * @param exception_handle the exception handling hook function.
+ */
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
+{
+	rt_exception_hook = exception_handle;
+}
+
+/*
+ * fault exception handler
  */
-void rt_hw_hard_fault_exception(struct exception_stack_frame* contex)
+void rt_hw_hard_fault_exception(struct exception_stack_frame* context)
 {
-    rt_kprintf("psr: 0x%08x\n", contex->psr);
-    rt_kprintf(" pc: 0x%08x\n", contex->pc);
-    rt_kprintf(" lr: 0x%08x\n", contex->lr);
-    rt_kprintf("r12: 0x%08x\n", contex->r12);
-    rt_kprintf("r03: 0x%08x\n", contex->r3);
-    rt_kprintf("r02: 0x%08x\n", contex->r2);
-    rt_kprintf("r01: 0x%08x\n", contex->r1);
-    rt_kprintf("r00: 0x%08x\n", contex->r0);
+	extern long list_thread(void);
+
+	if (rt_exception_hook != RT_NULL)
+	{
+		rt_err_t result;
+
+		result = rt_exception_hook(context);
+		if (result == RT_EOK) return;
+	}
 
-    rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
+    rt_kprintf("psr: 0x%08x\n", context->psr);
+    rt_kprintf(" pc: 0x%08x\n", context->pc);
+    rt_kprintf(" lr: 0x%08x\n", context->lr);
+    rt_kprintf("r12: 0x%08x\n", context->r12);
+    rt_kprintf("r03: 0x%08x\n", context->r3);
+    rt_kprintf("r02: 0x%08x\n", context->r2);
+    rt_kprintf("r01: 0x%08x\n", context->r1);
+    rt_kprintf("r00: 0x%08x\n", context->r0);
+
+    rt_kprintf("hard fault on thread: %s\n", rt_thread_self()->name);
 
 #ifdef RT_USING_FINSH
     list_thread();
@@ -126,3 +147,4 @@ void rt_hw_cpu_shutdown(void)
 
     RT_ASSERT(0);
 }
+

+ 25 - 4
libcpu/arm/cortex-m4/cpuport.c

@@ -15,6 +15,7 @@
  * 2012-01-01     aozima       support context switch load/store FPU register.
  * 2012-12-11     lgnq         fixed the coding style.
  * 2012-12-23     aozima       stack addr align to 8byte.
+ * 2012-12-29     Bernard      Add exception hook.
  */
 
 #include <rtthread.h>
@@ -27,6 +28,8 @@
 rt_uint32_t rt_interrupt_from_thread;
 rt_uint32_t rt_interrupt_to_thread;
 rt_uint32_t rt_thread_switch_interrupt_flag;
+/* exception hook */
+static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
 
 struct exception_stack_frame
 {
@@ -131,11 +134,28 @@ rt_uint8_t *rt_hw_stack_init(void       *tentry,
     return stk;
 }
 
-extern void rt_hw_interrupt_thread_switch(void);
-extern long list_thread(void);
-extern rt_thread_t rt_current_thread;
+/**
+ * This function set the hook, which is invoked on fault exception handling.
+ *
+ * @param exception_handle the exception handling hook function.
+ */
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
+{
+	rt_exception_hook = exception_handle;
+}
+
 void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
 {
+	extern long list_thread(void);
+
+	if (rt_exception_hook != RT_NULL)
+	{
+		rt_err_t result;
+
+		result = rt_exception_hook(exception_stack);
+		if (result == RT_EOK) return;
+	}
+
     rt_kprintf("psr: 0x%08x\n", exception_stack->psr);
     rt_kprintf(" pc: 0x%08x\n", exception_stack->pc);
     rt_kprintf(" lr: 0x%08x\n", exception_stack->lr);
@@ -145,7 +165,7 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
     rt_kprintf("r01: 0x%08x\n", exception_stack->r1);
     rt_kprintf("r00: 0x%08x\n", exception_stack->r0);
 
-    rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
+    rt_kprintf("hard fault on thread: %s\n", rt_thread_self()->name);
 
 #ifdef RT_USING_FINSH
     list_thread();
@@ -160,3 +180,4 @@ void rt_hw_cpu_shutdown(void)
 
     RT_ASSERT(0);
 }
+