diff options
| author | xuzhuoyi <[email protected]> | 2019-03-31 21:17:55 +0800 |
|---|---|---|
| committer | xuzhuoyi <[email protected]> | 2019-03-31 21:17:55 +0800 |
| commit | 5a460aadcd1df4fcfb14aafeb248230a47e9cbeb (patch) | |
| tree | 24a337e1683bc84161476b8c089535424f6e2690 /libcpu/arm | |
| parent | 5d166c389d6c81fbeea3e175100d4922453991ee (diff) | |
[bsp][gd32e230k-start] Update Sconscript
Diffstat (limited to 'libcpu/arm')
| -rw-r--r-- | libcpu/arm/cortex-m23/context_gcc.S | 120 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m23/context_iar.S | 90 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m23/context_rvds.S | 84 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m23/cpuport.c | 328 |
4 files changed, 183 insertions, 439 deletions
diff --git a/libcpu/arm/cortex-m23/context_gcc.S b/libcpu/arm/cortex-m23/context_gcc.S index d17a8aa12c..d9993247e2 100644 --- a/libcpu/arm/cortex-m23/context_gcc.S +++ b/libcpu/arm/cortex-m23/context_gcc.S @@ -5,26 +5,25 @@ * * Change Logs: * Date Author Notes - * 2009-10-11 Bernard First version - * 2010-12-29 onelife Modify for EFM32 - * 2011-06-17 onelife Merge all of the assembly source code into context_gcc.S - * 2011-07-12 onelife Add interrupt context check function - * 2013-06-18 aozima add restore MSP feature. - * 2013-07-09 aozima enhancement hard fault exception handler. + * 2010-01-25 Bernard first version + * 2012-06-01 aozima set pendsv priority to 0xFF. + * 2012-08-17 aozima fixed bug: store r8 - r11. + * 2013-02-20 aozima port to gcc. + * 2013-06-18 aozima add restore MSP feature. + * 2013-11-04 bright fixed hardfault bug for gcc. */ - .cpu cortex-m3 + .cpu cortex-m0 .fpu softvfp .syntax unified .thumb .text - .equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */ - .equ ICSR, 0xE000ED04 /* interrupt control state register */ - .equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */ - - .equ SHPR3, 0xE000ED20 /* system priority register (3) */ - .equ PENDSV_PRI_LOWEST, 0x00FF0000 /* PendSV priority value (lowest) */ + .equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */ + .equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */ + .equ NVIC_SHPR3, 0xE000ED20 /* system priority register (3) */ + .equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */ + .equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */ /* * rt_base_t rt_hw_interrupt_disable(); @@ -61,7 +60,7 @@ rt_hw_context_switch: LDR R3, [R2] CMP R3, #1 BEQ _reswitch - MOV R3, #1 + MOVS R3, #1 STR R3, [R2] LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */ @@ -71,8 +70,8 @@ _reswitch: LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */ STR R1, [R2] - LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */ - LDR R1, =PENDSVSET_BIT + LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR R1, =NVIC_PENDSVSET STR R1, [R0] BX LR @@ -90,36 +89,56 @@ PendSV_Handler: /* get rt_thread_switch_interrupt_flag */ LDR R0, =rt_thread_switch_interrupt_flag LDR R1, [R0] - CBZ R1, pendsv_exit /* pendsv aLReady handled */ + CMP R1, #0x00 + BEQ pendsv_exit /* pendsv aLReady handled */ /* clear rt_thread_switch_interrupt_flag to 0 */ - MOV R1, #0 + MOVS R1, #0 STR R1, [R0] LDR R0, =rt_interrupt_from_thread LDR R1, [R0] - CBZ R1, switch_to_thread /* skip register save at the first time */ + CMP R1, #0x00 + BEQ switch_to_thread /* skip register save at the first time */ - MRS R1, PSP /* get from thread stack pointer */ - STMFD R1!, {R4 - R11} /* push R4 - R11 register */ + MRS R1, PSP /* get from thread stack pointer */ + + SUBS R1, R1, #0x20 /* space for {R4 - R7} and {R8 - R11} */ LDR R0, [R0] STR R1, [R0] /* update from thread stack pointer */ + STMIA R1!, {R4 - R7} /* push thread {R4 - R7} register to thread stack */ + + MOV R4, R8 /* mov thread {R8 - R11} to {R4 - R7} */ + MOV R5, R9 + MOV R6, R10 + MOV R7, R11 + STMIA R1!, {R4 - R7} /* push thread {R8 - R11} high register to thread stack */ switch_to_thread: LDR R1, =rt_interrupt_to_thread LDR R1, [R1] LDR R1, [R1] /* load thread stack pointer */ - LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */ + LDMIA R1!, {R4 - R7} /* pop thread {R4 - R7} register from thread stack */ + PUSH {R4 - R7} /* push {R4 - R7} to MSP for copy {R8 - R11} */ + + LDMIA R1!, {R4 - R7} /* pop thread {R8 - R11} high register from thread stack to {R4 - R7} */ + MOV R8, R4 /* mov {R4 - R7} to {R8 - R11} */ + MOV R9, R5 + MOV R10, R6 + MOV R11, R7 + + POP {R4 - R7} /* pop {R4 - R7} from MSP */ + MSR PSP, R1 /* update stack pointer */ pendsv_exit: /* restore interrupt */ MSR PRIMASK, R2 - ORR LR, LR, #0x04 - BX LR - + MOVS R0, #0x04 + RSBS R0, R0, #0x00 + BX R0 /* * void rt_hw_context_switch_to(rt_uint32 to); * R0 --> to @@ -132,34 +151,33 @@ rt_hw_context_switch_to: /* set from thread to 0 */ LDR R1, =rt_interrupt_from_thread - MOV R0, #0 + MOVS R0, #0 STR R0, [R1] /* set interrupt flag to 1 */ LDR R1, =rt_thread_switch_interrupt_flag - MOV R0, #1 + MOVS R0, #1 STR R0, [R1] /* set the PendSV exception priority */ - LDR R0, =SHPR3 - LDR R1, =PENDSV_PRI_LOWEST - LDR.W R2, [R0,#0] /* read */ - ORR R1, R1, R2 /* modify */ - STR R1, [R0] /* write-back */ + LDR R0, =NVIC_SHPR3 + LDR R1, =NVIC_PENDSV_PRI + LDR R2, [R0,#0x00] /* read */ + ORRS R1, R1, R2 /* modify */ + STR R1, [R0] /* write-back */ - LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */ - LDR R1, =PENDSVSET_BIT + LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR R1, =NVIC_PENDSVSET STR R1, [R0] - + NOP /* restore MSP */ - LDR r0, =SCB_VTOR - LDR r0, [r0] - LDR r0, [r0] + LDR R0, =SCB_VTOR + LDR R0, [R0] + LDR R0, [R0] NOP - MSR msp, r0 + MSR MSP, R0 /* enable interrupts at processor level */ - CPSIE F CPSIE I /* never reach here! */ @@ -175,29 +193,11 @@ rt_hw_interrupt_thread_switch: .type HardFault_Handler, %function HardFault_Handler: /* get current context */ - MRS r0, msp /* get fault context from handler. */ - TST lr, #0x04 /* if(!EXC_RETURN[2]) */ - BEQ _get_sp_done - MRS r0, psp /* get fault context from thread. */ -_get_sp_done: - - STMFD r0!, {r4 - r11} /* push r4 - r11 register */ - STMFD r0!, {lr} /* push exec_return register */ - - TST lr, #0x04 /* if(!EXC_RETURN[2]) */ - BEQ _update_msp - MSR psp, r0 /* update stack pointer to PSP. */ - B _update_done -_update_msp: - MSR msp, r0 /* update stack pointer to MSP. */ -_update_done: - + MRS R0, PSP /* get fault thread stack pointer */ PUSH {LR} BL rt_hw_hard_fault_exception - POP {LR} + POP {PC} - ORR LR, LR, #0x04 - BX LR /* * rt_uint32_t rt_hw_interrupt_check(void); diff --git a/libcpu/arm/cortex-m23/context_iar.S b/libcpu/arm/cortex-m23/context_iar.S index 91645c48b3..50d3781359 100644 --- a/libcpu/arm/cortex-m23/context_iar.S +++ b/libcpu/arm/cortex-m23/context_iar.S @@ -5,20 +5,20 @@ ; * ; * Change Logs: ; * Date Author Notes -; * 2009-01-17 Bernard first version -; * 2009-09-27 Bernard add protect when contex switch occurs +; * 2010-01-25 Bernard first version +; * 2012-06-01 aozima set pendsv priority to 0xFF. +; * 2012-08-17 aozima fixed bug: store r8 - r11. ; * 2013-06-18 aozima add restore MSP feature. -; * 2013-07-09 aozima enhancement hard fault exception handler. ; */ ;/** -; * @addtogroup cortex-m3 +; * @addtogroup CORTEX-M0 ; */ ;/*@{*/ SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register -NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2) +NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2) NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception @@ -62,7 +62,7 @@ rt_hw_context_switch: LDR r3, [r2] CMP r3, #1 BEQ _reswitch - MOV r3, #1 + MOVS r3, #0x1 STR r3, [r2] LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread @@ -90,65 +90,91 @@ PendSV_Handler: ; get rt_thread_switch_interrupt_flag LDR r0, =rt_thread_switch_interrupt_flag LDR r1, [r0] - CBZ r1, pendsv_exit ; pendsv already handled + CMP r1, #0x00 + BEQ pendsv_exit ; pendsv already handled ; clear rt_thread_switch_interrupt_flag to 0 - MOV r1, #0x00 + MOVS r1, #0x00 STR r1, [r0] LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, switch_to_thread ; skip register save at the first time + CMP r1, #0x00 + BEQ switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer - STMFD r1!, {r4 - r11} ; push r4 - r11 register + + SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11} LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer + STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack + + MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7} + MOV r5, r9 + MOV r6, r10 + MOV r7, r11 + STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack + switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer - LDMFD r1!, {r4 - r11} ; pop r4 - r11 register + LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack + PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11} + + LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7} + MOV r8, r4 ; mov {r4 - r7} to {r8 - r11} + MOV r9, r5 + MOV r10, r6 + MOV r11, r7 + + POP {r4 - r7} ; pop {r4 - r7} from MSP + MSR psp, r1 ; update stack pointer pendsv_exit ; restore interrupt MSR PRIMASK, r2 - ORR lr, lr, #0x04 - BX lr + MOVS r0, #0x04 + RSBS r0, r0, #0x00 + BX r0 ;/* ; * void rt_hw_context_switch_to(rt_uint32 to); ; * r0 --> to +; * this fucntion is used to perform the first thread switch ; */ EXPORT rt_hw_context_switch_to rt_hw_context_switch_to: + ; set to thread LDR r1, =rt_interrupt_to_thread STR r0, [r1] ; set from thread to 0 LDR r1, =rt_interrupt_from_thread - MOV r0, #0x0 + MOVS r0, #0x0 STR r0, [r1] ; set interrupt flag to 1 LDR r1, =rt_thread_switch_interrupt_flag - MOV r0, #1 + MOVS r0, #1 STR r0, [r1] ; set the PendSV exception priority - LDR r0, =NVIC_SYSPRI2 + LDR r0, =NVIC_SHPR3 LDR r1, =NVIC_PENDSV_PRI - LDR.W r2, [r0,#0x00] ; read - ORR r1,r1,r2 ; modify + LDR r2, [r0,#0x00] ; read + ORRS r1,r1,r2 ; modify STR r1, [r0] ; write-back - LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + ; trigger the PendSV exception (causes context switch) + LDR r0, =NVIC_INT_CTRL LDR r1, =NVIC_PENDSVSET STR r1, [r0] + NOP ; restore MSP LDR r0, =SCB_VTOR @@ -158,7 +184,6 @@ rt_hw_context_switch_to: MSR msp, r0 ; enable interrupts at processor level - CPSIE F CPSIE I ; never reach here! @@ -173,30 +198,9 @@ rt_hw_interrupt_thread_switch: HardFault_Handler: ; get current context - MRS r0, msp ; get fault context from handler. - TST lr, #0x04 ; if(!EXC_RETURN[2]) - BEQ _get_sp_done - MRS r0, psp ; get fault context from thread. -_get_sp_done - - STMFD r0!, {r4 - r11} ; push r4 - r11 register - ;STMFD r0!, {lr} ; push exec_return register - SUB r0, r0, #0x04 - STR lr, [r0] - - TST lr, #0x04 ; if(!EXC_RETURN[2]) - BEQ _update_msp - MSR psp, r0 ; update stack pointer to PSP. - B _update_done -_update_msp - MSR msp, r0 ; update stack pointer to MSP. -_update_done - + MRS r0, psp ; get fault thread stack pointer PUSH {lr} BL rt_hw_hard_fault_exception - POP {lr} - - ORR lr, lr, #0x04 - BX lr + POP {pc} END diff --git a/libcpu/arm/cortex-m23/context_rvds.S b/libcpu/arm/cortex-m23/context_rvds.S index c0a2130703..54145773d3 100644 --- a/libcpu/arm/cortex-m23/context_rvds.S +++ b/libcpu/arm/cortex-m23/context_rvds.S @@ -5,9 +5,10 @@ ; * ; * Change Logs: ; * Date Author Notes -; * 2009-01-17 Bernard first version +; * 2010-01-25 Bernard first version +; * 2012-06-01 aozima set pendsv priority to 0xFF. +; * 2012-08-17 aozima fixed bug: store r8 - r11. ; * 2013-06-18 aozima add restore MSP feature. -; * 2013-07-09 aozima enhancement hard fault exception handler. ; */ ;/** @@ -17,7 +18,7 @@ SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register -NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2) +NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2) NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception @@ -45,8 +46,8 @@ rt_hw_interrupt_disable PROC ; */ rt_hw_interrupt_enable PROC EXPORT rt_hw_interrupt_enable - MSR PRIMASK, r0 - BX LR + MSR PRIMASK, r0 + BX LR ENDP ;/* @@ -64,7 +65,7 @@ rt_hw_context_switch PROC LDR r3, [r2] CMP r3, #1 BEQ _reswitch - MOV r3, #1 + MOVS r3, #0x01 STR r3, [r2] LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread @@ -83,7 +84,7 @@ _reswitch ; r0 --> switch from thread stack ; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack -PendSV_Handler PROC +PendSV_Handler PROC EXPORT PendSV_Handler ; disable interrupt to protect context switch @@ -93,35 +94,57 @@ PendSV_Handler PROC ; get rt_thread_switch_interrupt_flag LDR r0, =rt_thread_switch_interrupt_flag LDR r1, [r0] - CBZ r1, pendsv_exit ; pendsv already handled + CMP r1, #0x00 + BEQ pendsv_exit ; pendsv already handled ; clear rt_thread_switch_interrupt_flag to 0 - MOV r1, #0x00 + MOVS r1, #0x00 STR r1, [r0] LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, switch_to_thread ; skip register save at the first time + CMP r1, #0x00 + BEQ switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer - STMFD r1!, {r4 - r11} ; push r4 - r11 register + + SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11} LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer + STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack + + MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7} + MOV r5, r9 + MOV r6, r10 + MOV r7, r11 + STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack + switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer - LDMFD r1!, {r4 - r11} ; pop r4 - r11 register + LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack + PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11} + + LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7} + MOV r8, r4 ; mov {r4 - r7} to {r8 - r11} + MOV r9, r5 + MOV r10, r6 + MOV r11, r7 + + POP {r4 - r7} ; pop {r4 - r7} from MSP + MSR psp, r1 ; update stack pointer pendsv_exit ; restore interrupt MSR PRIMASK, r2 - ORR lr, lr, #0x04 - BX lr + MOVS r0, #0x04 + RSBS r0, r0, #0x00 + BX r0 ENDP ;/* @@ -137,19 +160,19 @@ rt_hw_context_switch_to PROC ; set from thread to 0 LDR r1, =rt_interrupt_from_thread - MOV r0, #0x0 + MOVS r0, #0x0 STR r0, [r1] ; set interrupt flag to 1 LDR r1, =rt_thread_switch_interrupt_flag - MOV r0, #1 + MOVS r0, #1 STR r0, [r1] ; set the PendSV exception priority - LDR r0, =NVIC_SYSPRI2 + LDR r0, =NVIC_SHPR3 LDR r1, =NVIC_PENDSV_PRI - LDR.W r2, [r0,#0x00] ; read - ORR r1,r1,r2 ; modify + LDR r2, [r0,#0x00] ; read + ORRS r1,r1,r2 ; modify STR r1, [r0] ; write-back ; trigger the PendSV exception (causes context switch) @@ -164,7 +187,6 @@ rt_hw_context_switch_to PROC MSR msp, r0 ; enable interrupts at processor level - CPSIE F CPSIE I ; never reach here! @@ -177,29 +199,15 @@ rt_hw_interrupt_thread_switch PROC ENDP IMPORT rt_hw_hard_fault_exception - EXPORT HardFault_Handler + HardFault_Handler PROC + EXPORT HardFault_Handler ; get current context - TST lr, #0x04 ; if(!EXC_RETURN[2]) - ITE EQ - MRSEQ r0, msp ; [2]=0 ==> Z=1, get fault context from handler. - MRSNE r0, psp ; [2]=1 ==> Z=0, get fault context from thread. - - STMFD r0!, {r4 - r11} ; push r4 - r11 register - STMFD r0!, {lr} ; push exec_return register - - TST lr, #0x04 ; if(!EXC_RETURN[2]) - ITE EQ - MSREQ msp, r0 ; [2]=0 ==> Z=1, update stack pointer to MSP. - MSRNE psp, r0 ; [2]=1 ==> Z=0, update stack pointer to PSP. - + MRS r0, psp ; get fault thread stack pointer PUSH {lr} BL rt_hw_hard_fault_exception - POP {lr} - - ORR lr, lr, #0x04 - BX lr + POP {pc} ENDP ALIGN 4 diff --git a/libcpu/arm/cortex-m23/cpuport.c b/libcpu/arm/cortex-m23/cpuport.c index a386747750..5d36fa11fe 100644 --- a/libcpu/arm/cortex-m23/cpuport.c +++ b/libcpu/arm/cortex-m23/cpuport.c @@ -4,13 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2009-01-05 Bernard first version - * 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. - * 2013-07-09 aozima enhancement hard fault exception handler. + * Date Author Notes + * 2010-01-25 Bernard first version + * 2012-05-31 aozima Merge all of the C source code into cpuport.c + * 2012-08-17 aozima fixed bug: store r8 - r11. + * 2012-12-23 aozima stack addr align to 8byte. */ #include <rtthread.h> @@ -29,11 +27,13 @@ struct exception_stack_frame struct stack_frame { - /* r4 ~ r11 register */ + /* r4 ~ r7 low register */ rt_uint32_t r4; rt_uint32_t r5; rt_uint32_t r6; rt_uint32_t r7; + + /* r8 ~ r11 high register */ rt_uint32_t r8; rt_uint32_t r9; rt_uint32_t r10; @@ -45,8 +45,6 @@ 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,312 +90,46 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, return stk; } +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. + * fault exception handling */ -void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context)) +void rt_hw_hard_fault_exception(struct exception_stack_frame *contex) { - rt_exception_hook = exception_handle; + 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); + + rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); + +#ifdef RT_USING_FINSH + list_thread(); +#endif + + while (1); } #define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */ #define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */ #define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */ #define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */ -#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */ +#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED00) /* Reset control Address Register */ #define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */ #define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */ #define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */ #define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */ -#ifdef RT_USING_FINSH -static void usage_fault_track(void) -{ - rt_kprintf("usage fault:\n"); - rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR); - - if(SCB_CFSR_UFSR & (1<<0)) - { - /* [0]:UNDEFINSTR */ - rt_kprintf("UNDEFINSTR "); - } - - if(SCB_CFSR_UFSR & (1<<1)) - { - /* [1]:INVSTATE */ - rt_kprintf("INVSTATE "); - } - - if(SCB_CFSR_UFSR & (1<<2)) - { - /* [2]:INVPC */ - rt_kprintf("INVPC "); - } - - if(SCB_CFSR_UFSR & (1<<3)) - { - /* [3]:NOCP */ - rt_kprintf("NOCP "); - } - - if(SCB_CFSR_UFSR & (1<<8)) - { - /* [8]:UNALIGNED */ - rt_kprintf("UNALIGNED "); - } - - if(SCB_CFSR_UFSR & (1<<9)) - { - /* [9]:DIVBYZERO */ - rt_kprintf("DIVBYZERO "); - } - - rt_kprintf("\n"); -} - -static void bus_fault_track(void) -{ - rt_kprintf("bus fault:\n"); - rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR); - - if(SCB_CFSR_BFSR & (1<<0)) - { - /* [0]:IBUSERR */ - rt_kprintf("IBUSERR "); - } - - if(SCB_CFSR_BFSR & (1<<1)) - { - /* [1]:PRECISERR */ - rt_kprintf("PRECISERR "); - } - - if(SCB_CFSR_BFSR & (1<<2)) - { - /* [2]:IMPRECISERR */ - rt_kprintf("IMPRECISERR "); - } - - if(SCB_CFSR_BFSR & (1<<3)) - { - /* [3]:UNSTKERR */ - rt_kprintf("UNSTKERR "); - } - - if(SCB_CFSR_BFSR & (1<<4)) - { - /* [4]:STKERR */ - rt_kprintf("STKERR "); - } - - if(SCB_CFSR_BFSR & (1<<7)) - { - rt_kprintf("SCB->BFAR:%08X\n", SCB_BFAR); - } - else - { - rt_kprintf("\n"); - } -} - -static void mem_manage_fault_track(void) -{ - rt_kprintf("mem manage fault:\n"); - rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR); - - if(SCB_CFSR_MFSR & (1<<0)) - { - /* [0]:IACCVIOL */ - rt_kprintf("IACCVIOL "); - } - - if(SCB_CFSR_MFSR & (1<<1)) - { - /* [1]:DACCVIOL */ - rt_kprintf("DACCVIOL "); - } - - if(SCB_CFSR_MFSR & (1<<3)) - { - /* [3]:MUNSTKERR */ - rt_kprintf("MUNSTKERR "); - } - - if(SCB_CFSR_MFSR & (1<<4)) - { - /* [4]:MSTKERR */ - rt_kprintf("MSTKERR "); - } - - if(SCB_CFSR_MFSR & (1<<7)) - { - /* [7]:MMARVALID */ - rt_kprintf("SCB->MMAR:%08X\n", SCB_MMAR); - } - else - { - rt_kprintf("\n"); - } -} - -static void hard_fault_track(void) -{ - if(SCB_HFSR & (1UL<<1)) - { - /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */ - rt_kprintf("failed vector fetch\n"); - } - - if(SCB_HFSR & (1UL<<30)) - { - /* [30]:FORCED, Indicates hard fault is taken because of bus fault, - memory management fault, or usage fault. */ - if(SCB_CFSR_BFSR) - { - bus_fault_track(); - } - - if(SCB_CFSR_MFSR) - { - mem_manage_fault_track(); - } - - if(SCB_CFSR_UFSR) - { - usage_fault_track(); - } - } - - if(SCB_HFSR & (1UL<<31)) - { - /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */ - rt_kprintf("debug event\n"); - } -} -#endif /* RT_USING_FINSH */ - -struct exception_info -{ - rt_uint32_t exc_return; - struct stack_frame stack_frame; -}; - -/* - * fault exception handler - */ -void rt_hw_hard_fault_exception(struct exception_info * exception_info) -{ - extern long list_thread(void); - struct stack_frame* context = &exception_info->stack_frame; - - if (rt_exception_hook != RT_NULL) - { - rt_err_t result; - - result = rt_exception_hook(exception_info); - if (result == RT_EOK) - return; - } - - rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr); - - rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0); - rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1); - rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2); - rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3); - rt_kprintf("r04: 0x%08x\n", context->r4); - rt_kprintf("r05: 0x%08x\n", context->r5); - rt_kprintf("r06: 0x%08x\n", context->r6); - rt_kprintf("r07: 0x%08x\n", context->r7); - rt_kprintf("r08: 0x%08x\n", context->r8); - rt_kprintf("r09: 0x%08x\n", context->r9); - rt_kprintf("r10: 0x%08x\n", context->r10); - rt_kprintf("r11: 0x%08x\n", context->r11); - rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12); - rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr); - rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc); - - if(exception_info->exc_return & (1 << 2) ) - { - rt_kprintf("hard fault on thread: %s\r\n\r\n", rt_thread_self()->name); - -#ifdef RT_USING_FINSH - list_thread(); -#endif /* RT_USING_FINSH */ - } - else - { - rt_kprintf("hard fault on handler\r\n\r\n"); - } - -#ifdef RT_USING_FINSH - hard_fault_track(); -#endif /* RT_USING_FINSH */ - - while (1); -} - -/** - * shutdown CPU - */ -void rt_hw_cpu_shutdown(void) -{ - rt_kprintf("shutdown...\n"); - - RT_ASSERT(0); -} - /** * reset CPU */ RT_WEAK void rt_hw_cpu_reset(void) { - SCB_AIRCR = SCB_RESET_VALUE; -} - -#ifdef RT_USING_CPU_FFS -/** - * This function finds the first bit set (beginning with the least significant bit) - * in value and return the index of that bit. - * - * Bits are numbered starting at 1 (the least significant bit). A return value of - * zero from any of these functions means that the argument was zero. - * - * @return return the index of the first bit set. If value is 0, then this function - * shall return 0. - */ -#if defined(__CC_ARM) -__asm int __rt_ffs(int value) -{ - CMP r0, #0x00 - BEQ exit - - RBIT r0, r0 - CLZ r0, r0 - ADDS r0, r0, #0x01 - -exit - BX lr + SCB_AIRCR = SCB_RESET_VALUE;//((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |SCB_AIRCR_SYSRESETREQ_Msk); } -#elif defined(__IAR_SYSTEMS_ICC__) -int __rt_ffs(int value) -{ - if (value == 0) return value; - - asm("RBIT %0, %1" : "=r"(value) : "r"(value)); - asm("CLZ %0, %1" : "=r"(value) : "r"(value)); - asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value)); - - return value; -} -#elif defined(__GNUC__) -int __rt_ffs(int value) -{ - return __builtin_ffs(value); -} -#endif - -#endif |
