Skip to content

Commit 7f25f7a

Browse files
committed
Issue #1086 - Fixed HardFault_Handler for Cortex-M0 targets
1 parent b82cb6f commit 7f25f7a

File tree

3 files changed

+159
-54
lines changed

3 files changed

+159
-54
lines changed

src/boards/B-L072Z-LRWAN1/sysIrqHandlers.c

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,31 +71,66 @@ void HardFault_Handler_C( unsigned int *args )
7171
}
7272

7373
#if defined(__CC_ARM)
74-
__asm void HardFault_Handler(void)
75-
{
76-
TST LR, #4
77-
ITE EQ
78-
MRSEQ r0, MSP
79-
MRSNE r0, PSP
80-
B __cpp(HardFault_Handler_C)
81-
}
74+
#warning "HardFault_Handler: ARMCC does not allow some of the required instructions to be inlined under C code."
75+
// To mimic the behavior provided for IAR and GCC one needs to create a hard_fault_handler.s file and add it to the Keil project.
76+
// Something similar to the below code should be added to hard_fault_handler.s
77+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
78+
// @code
79+
// AREA OSKERNEL, CODE, READONLY, ALIGN=2
80+
// PRESERVE8
81+
//
82+
// EXPORT HardFault_Handler
83+
// IMPORT HardFault_Handler_C
84+
//
85+
// THUMB
86+
//
87+
// HardFault_Handler PROC
88+
// MOVS R0, #4
89+
// MOV R1, LR
90+
// TST R0, R1 // Check EXC_RETURN in Link register bit 2.
91+
// BNE Uses_PSP
92+
// MRS R0, MSP // Stacking was using MSP.
93+
// B Pass_StackPtr
94+
// Uses_PSP:
95+
// MRS R0, PSP // Stacking was using PSP
96+
// Pass_StackPtr:
97+
// ALIGN
98+
// LDR R2,=HardFault_Handler_C
99+
// BX R2
100+
// ENDP
101+
// END
102+
// @code
82103
#elif defined(__ICCARM__)
83104
void HardFault_Handler(void)
84105
{
85-
__asm("TST LR, #4");
86-
__asm("ITE EQ");
87-
__asm("MRSEQ r0, MSP");
88-
__asm("MRSNE r0, PSP");
89-
__asm("B HardFault_Handler_C");
106+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
107+
__asm("MOVS R0, #4");
108+
__asm("MOV R1, LR");
109+
__asm("TST R0, R1"); // Check EXC_RETURN in Link register bit 2.
110+
__asm("BNE Uses_PSP");
111+
__asm("MRS R0, MSP"); // Stacking was using MSP.
112+
__asm("B Pass_StackPtr");
113+
__asm("Uses_PSP:");
114+
__asm("MRS R0, PSP"); // Stacking was using PSP
115+
__asm("Pass_StackPtr:");
116+
__asm("LDR R2,=HardFault_Handler_C");
117+
__asm("BX R2");
90118
}
91119
#elif defined(__GNUC__)
92120
void HardFault_Handler(void)
93121
{
94-
__asm volatile( "TST LR, #4" );
95-
__asm volatile( "ITE EQ" );
96-
__asm volatile( "MRSEQ R0, MSP" );
97-
__asm volatile( "MRSNE R0, PSP" );
98-
__asm volatile( "B HardFault_Handler_C" );
122+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
123+
__asm volatile("MOVS R0, #4");
124+
__asm volatile("MOV R1, LR");
125+
__asm volatile("TST R0, R1"); // Check EXC_RETURN in Link register bit 2.
126+
__asm volatile("BNE Uses_PSP");
127+
__asm volatile("MRS R0, MSP");// Stacking was using MSP.
128+
__asm volatile("B Pass_StackPtr");
129+
__asm volatile("Uses_PSP:");
130+
__asm volatile("MRS R0, PSP"); // Stacking was using PSP
131+
__asm volatile("Pass_StackPtr:");
132+
__asm volatile("LDR R2,=HardFault_Handler_C");
133+
__asm volatile("BX R2");
99134
}
100135
#else
101136
#warning Not supported compiler type

src/boards/NucleoL073/sysIrqHandlers.c

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,31 +71,66 @@ void HardFault_Handler_C( unsigned int *args )
7171
}
7272

7373
#if defined(__CC_ARM)
74-
__asm void HardFault_Handler(void)
75-
{
76-
TST LR, #4
77-
ITE EQ
78-
MRSEQ r0, MSP
79-
MRSNE r0, PSP
80-
B __cpp(HardFault_Handler_C)
81-
}
74+
#warning "HardFault_Handler: ARMCC does not allow some of the required instructions to be inlined under C code."
75+
// To mimic the behavior provided for IAR and GCC one needs to create a hard_fault_handler.s file and add it to the Keil project.
76+
// Something similar to the below code should be added to hard_fault_handler.s
77+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
78+
// @code
79+
// AREA OSKERNEL, CODE, READONLY, ALIGN=2
80+
// PRESERVE8
81+
//
82+
// EXPORT HardFault_Handler
83+
// IMPORT HardFault_Handler_C
84+
//
85+
// THUMB
86+
//
87+
// HardFault_Handler PROC
88+
// MOVS R0, #4
89+
// MOV R1, LR
90+
// TST R0, R1 // Check EXC_RETURN in Link register bit 2.
91+
// BNE Uses_PSP
92+
// MRS R0, MSP // Stacking was using MSP.
93+
// B Pass_StackPtr
94+
// Uses_PSP:
95+
// MRS R0, PSP // Stacking was using PSP
96+
// Pass_StackPtr:
97+
// ALIGN
98+
// LDR R2,=HardFault_Handler_C
99+
// BX R2
100+
// ENDP
101+
// END
102+
// @code
82103
#elif defined(__ICCARM__)
83104
void HardFault_Handler(void)
84105
{
85-
__asm("TST LR, #4");
86-
__asm("ITE EQ");
87-
__asm("MRSEQ r0, MSP");
88-
__asm("MRSNE r0, PSP");
89-
__asm("B HardFault_Handler_C");
106+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
107+
__asm("MOVS R0, #4");
108+
__asm("MOV R1, LR");
109+
__asm("TST R0, R1"); // Check EXC_RETURN in Link register bit 2.
110+
__asm("BNE Uses_PSP");
111+
__asm("MRS R0, MSP"); // Stacking was using MSP.
112+
__asm("B Pass_StackPtr");
113+
__asm("Uses_PSP:");
114+
__asm("MRS R0, PSP"); // Stacking was using PSP
115+
__asm("Pass_StackPtr:");
116+
__asm("LDR R2,=HardFault_Handler_C");
117+
__asm("BX R2");
90118
}
91119
#elif defined(__GNUC__)
92120
void HardFault_Handler(void)
93121
{
94-
__asm volatile( "TST LR, #4" );
95-
__asm volatile( "ITE EQ" );
96-
__asm volatile( "MRSEQ R0, MSP" );
97-
__asm volatile( "MRSNE R0, PSP" );
98-
__asm volatile( "B HardFault_Handler_C" );
122+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
123+
__asm volatile("MOVS R0, #4");
124+
__asm volatile("MOV R1, LR");
125+
__asm volatile("TST R0, R1"); // Check EXC_RETURN in Link register bit 2.
126+
__asm volatile("BNE Uses_PSP");
127+
__asm volatile("MRS R0, MSP");// Stacking was using MSP.
128+
__asm volatile("B Pass_StackPtr");
129+
__asm volatile("Uses_PSP:");
130+
__asm volatile("MRS R0, PSP"); // Stacking was using PSP
131+
__asm volatile("Pass_StackPtr:");
132+
__asm volatile("LDR R2,=HardFault_Handler_C");
133+
__asm volatile("BX R2");
99134
}
100135
#else
101136
#warning Not supported compiler type

src/boards/SKiM881AXL/sysIrqHandlers.c

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,31 +71,66 @@ void HardFault_Handler_C( unsigned int *args )
7171
}
7272

7373
#if defined(__CC_ARM)
74-
__asm void HardFault_Handler(void)
75-
{
76-
TST LR, #4
77-
ITE EQ
78-
MRSEQ r0, MSP
79-
MRSNE r0, PSP
80-
B __cpp(HardFault_Handler_C)
81-
}
74+
#warning "HardFault_Handler: ARMCC does not allow some of the required instructions to be inlined under C code."
75+
// To mimic the behavior provided for IAR and GCC one needs to create a hard_fault_handler.s file and add it to the Keil project.
76+
// Something similar to the below code should be added to hard_fault_handler.s
77+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
78+
// @code
79+
// AREA OSKERNEL, CODE, READONLY, ALIGN=2
80+
// PRESERVE8
81+
//
82+
// EXPORT HardFault_Handler
83+
// IMPORT HardFault_Handler_C
84+
//
85+
// THUMB
86+
//
87+
// HardFault_Handler PROC
88+
// MOVS R0, #4
89+
// MOV R1, LR
90+
// TST R0, R1 // Check EXC_RETURN in Link register bit 2.
91+
// BNE Uses_PSP
92+
// MRS R0, MSP // Stacking was using MSP.
93+
// B Pass_StackPtr
94+
// Uses_PSP:
95+
// MRS R0, PSP // Stacking was using PSP
96+
// Pass_StackPtr:
97+
// ALIGN
98+
// LDR R2,=HardFault_Handler_C
99+
// BX R2
100+
// ENDP
101+
// END
102+
// @code
82103
#elif defined(__ICCARM__)
83104
void HardFault_Handler(void)
84105
{
85-
__asm("TST LR, #4");
86-
__asm("ITE EQ");
87-
__asm("MRSEQ r0, MSP");
88-
__asm("MRSNE r0, PSP");
89-
__asm("B HardFault_Handler_C");
106+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
107+
__asm("MOVS R0, #4");
108+
__asm("MOV R1, LR");
109+
__asm("TST R0, R1"); // Check EXC_RETURN in Link register bit 2.
110+
__asm("BNE Uses_PSP");
111+
__asm("MRS R0, MSP"); // Stacking was using MSP.
112+
__asm("B Pass_StackPtr");
113+
__asm("Uses_PSP:");
114+
__asm("MRS R0, PSP"); // Stacking was using PSP
115+
__asm("Pass_StackPtr:");
116+
__asm("LDR R2,=HardFault_Handler_C");
117+
__asm("BX R2");
90118
}
91119
#elif defined(__GNUC__)
92120
void HardFault_Handler(void)
93121
{
94-
__asm volatile( "TST LR, #4" );
95-
__asm volatile( "ITE EQ" );
96-
__asm volatile( "MRSEQ R0, MSP" );
97-
__asm volatile( "MRSNE R0, PSP" );
98-
__asm volatile( "B HardFault_Handler_C" );
122+
// Refer to https://www.segger.com/downloads/application-notes/AN00016
123+
__asm volatile("MOVS R0, #4");
124+
__asm volatile("MOV R1, LR");
125+
__asm volatile("TST R0, R1"); // Check EXC_RETURN in Link register bit 2.
126+
__asm volatile("BNE Uses_PSP");
127+
__asm volatile("MRS R0, MSP");// Stacking was using MSP.
128+
__asm volatile("B Pass_StackPtr");
129+
__asm volatile("Uses_PSP:");
130+
__asm volatile("MRS R0, PSP"); // Stacking was using PSP
131+
__asm volatile("Pass_StackPtr:");
132+
__asm volatile("LDR R2,=HardFault_Handler_C");
133+
__asm volatile("BX R2");
99134
}
100135
#else
101136
#warning Not supported compiler type

0 commit comments

Comments
 (0)