1 /*
2  * Copyright 2019 NXP
3  *
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_common.h"
9 #include "fsl_component_exception_handling.h"
10 
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 
15 /* Firstly check the current LR value, All a valid LR EXC_RETURN values have bits[31:5] set to one.
16  * If the bits[31:5] of LR is one, then use check the LR to get faulted SP.
17  * If bits[31:5] is not all one, then LR have been pushed to current MSP, will loop check MSP to get
18  * valid LR value, and use the LR value to get which SP happen faulted.
19  * Then check bit[2] of LR to get which SP faulted happen, if bit[2] of LR is one, then fault happen
20  * with PSP, if bit[2] of LR is zero, then fault happen with MSP. */
21 #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)
22 #define COPY_TO_STACK()                                  \
23     __asm volatile("push {r0-r1}");                      \
24     __asm volatile("push {r0-r5}");                      \
25     __asm volatile("mrs  r1, msp");                      \
26     __asm volatile("adds r1, r1, #32");                  \
27     __asm volatile("mov  r5, r1");                       \
28     __asm volatile("and  r2, lr,#0xffffffe0");           \
29     __asm volatile("cmp  r2, #0xffffffe0");              \
30     __asm volatile(                                      \
31         "beq  _lr_case \n"                               \
32         "_loop_check: \n"                                \
33         "mov r4, #4\n"                                   \
34         "adds r1, r1, #4\n"                              \
35         "ldr  r3,[r1]\n"                                 \
36         "and  r2, r3,#0xffffffe0 \n"                     \
37         "cmp  r2, #0xffffffe0 \n"                        \
38         "bne  _loop_check \n"                            \
39         "b _handle_lr\n"                                 \
40         "_lr_case: \n"                                   \
41         "mov r4, #0\n"                                   \
42         "mov r3, lr\n"                                   \
43         "_handle_lr: ");                                 \
44     __asm volatile("adds  r1, r1, r4");                  \
45     __asm volatile("msr   msp, r1");                     \
46     __asm volatile("tst  r3,#4");                        \
47     __asm volatile(                                      \
48         "ite    eq \n"                                   \
49         "mrseq r0, msp \n"                               \
50         "mrsne r0, psp");                                \
51     __asm volatile("push  {r0}");                        \
52     __asm volatile("mrs   r0, ipsr");                    \
53     __asm volatile("push  {r0}");                        \
54     __asm volatile("ldr   r0, =g_exceptionStackStruct"); \
55     __asm volatile("str   sp, [r0]");                    \
56     __asm volatile("sub   r5, r5, #32");                 \
57     __asm volatile("msr   msp, r5");                     \
58     __asm volatile("pop   {r0-r5}");
59 
60 #elif defined(__ARMCC_VERSION)
COPY_TO_STACK(void)61 __ASM void COPY_TO_STACK(void)
62 {
63     PRESERVE8
64     EXTERN g_exceptionStackStruct
65 
66     push {r0-r1}
67     push {r0-r5}
68     mrs r1, msp
69     adds r1, r1, #32
70     mov r5, r1
71     and r2, lr, #0xffffffe0
72     cmp r2, #0xffffffe0
73     beq _lr_case
74 _loop_check
75     mov r4, #4
76     adds r1, r1, #4
77     ldr r3, [r1]
78     and r2, r3, #0xffffffe0
79     cmp r2, #0xffffffe0
80     bne _loop_check
81     b _handle_lr
82 _lr_case
83     mov r4, #0
84     mov r3, lr
85 _handle_lr
86     adds r1, r1, r4
87     msr msp, r1
88     tst r3, #4
89     ite eq
90         mrseq r0, msp
91         mrsne r0, psp
92     push{r0}
93     mrs r0, ipsr
94     push{r0}
95     ldr r0, = g_exceptionStackStruct
96     str sp,[r0]
97     sub r5, r5, #32
98     msr msp, r5
99     pop {r0-r5}
100     bx lr
101 
102     ALIGN
103 }
104 #endif
105 
106 /*******************************************************************************
107  * Variables
108  ******************************************************************************/
109 
110 #ifndef __ARMCC_VERSION
111 static
112 #endif
113 exception_stack_data_t *g_exceptionStackStruct = NULL;
114 
115 static const scb_data_text_t scb_data_text[] = {{32, 0x000, "CPUID   - CPUID Base Register"},
116                                          {32, 0x004, "ICSR    - Interrupt Control and State Register"},
117                                          {32, 0x008, "VTOR    - Vector Table Offset Register"},
118                                          {32, 0x00C, "AIRCR   - Application Interrupt and Reset Control Register"},
119                                          {32, 0x010, "SCR     - System Control Register"},
120                                          {32, 0x014, "CCR     - Configuration Control Register"},
121                                          {8, 0x018, "SHPR[0] - System Handlers Priority Registers 0"},
122                                          {8, 0x019, "SHPR[1] - System Handlers Priority Registers 1"},
123                                          {8, 0x01a, "SHPR[2] - System Handlers Priority Registers 2"},
124                                          {8, 0x01b, "SHPR[3] - System Handlers Priority Registers 3"},
125                                          {8, 0x01C, "SHPR[4] - System Handlers Priority Registers 4"},
126                                          {8, 0x01d, "SHPR[5] - System Handlers Priority Registers 5"},
127                                          {8, 0x01e, "SHPR[6] - System Handlers Priority Registers 6"},
128                                          {8, 0x01f, "SHPR[7] - System Handlers Priority Registers 7"},
129                                          {8, 0x020, "SHPR[8] - System Handlers Priority Registers 8"},
130                                          {8, 0x021, "SHPR[9] - System Handlers Priority Registers 9"},
131                                          {8, 0x022, "SHPR[10] - System Handlers Priority Registers 10"},
132                                          {8, 0x023, "SHPR[11] - System Handlers Priority Registers 11"},
133                                          {32, 0x024, "SHCSR    - System Handler Control and State Register"},
134                                          {32, 0x028, "CFSR     - Configurable Fault Status Register"},
135                                          {32, 0x02C, "HFSR     - HardFault Status Register"},
136                                          {32, 0x030, "DFSR     - Debug Fault Status Register"},
137                                          {32, 0x034, "MMFAR    - MemManage Fault Address Register"},
138                                          {32, 0x038, "BFAR     - BusFault Address Register"},
139                                          {32, 0x03C, "AFSR     - Auxiliary Fault Status Register"},
140                                          {32, 0x040, "ID_PFR[0]  - Processor Feature Register"},
141                                          {32, 0x044, "ID_PFR[1]  - Processor Feature Register"},
142                                          {32, 0x048, "ID_DFR     - Debug Feature Register"},
143                                          {32, 0x04C, "ID_AFR     - Auxiliary Feature Register"},
144                                          {32, 0x050, "ID_MFR[0]  - Memory Model Feature Register"},
145                                          {32, 0x054, "ID_MFR[1]  - Memory Model Feature Register"},
146                                          {32, 0x058, "ID_MFR[2]  - Memory Model Feature Register"},
147                                          {32, 0x05C, "ID_MFR[3]  - Memory Model Feature Register"},
148                                          {32, 0x060, "ID_ISAR[0] - Instruction Set Attributes Register"},
149                                          {32, 0x064, "ID_ISAR[1] - Instruction Set Attributes Register"},
150                                          {32, 0x068, "ID_ISAR[2] - Instruction Set Attributes Register"},
151                                          {32, 0x06C, "ID_ISAR[3] - Instruction Set Attributes Register"},
152                                          {32, 0x070, "ID_ISAR[4] - Instruction Set Attributes Register"},
153                                          {32, 0x078, "CLIDR  - Cache Level ID register"},
154                                          {32, 0x07C, "CTR    - Cache Type register"},
155                                          {32, 0x080, "CCSIDR - Cache Size ID Register"},
156                                          {32, 0x084, "CSSELR - Cache Size Selection Register"},
157                                          {32, 0x088, "CPACR  - Coprocessor Access Control Register"},
158                                          {32, 0x240, "MVFR0  - Media and VFP Feature Register 0"},
159                                          {32, 0x244, "MVFR1  - Media and VFP Feature Register 1"},
160                                          {32, 0x248, "MVFR2  - Media and VFP Feature Register 2"},
161                                          {32, 0x290, "ITCMCR - Instruction Tightly-Coupled Memory Control Register"},
162                                          {32, 0x294, "DTCMCR - Data Tightly-Coupled Memory Control Registers"},
163                                          {32, 0x298, "AHBPCR - AHBP Control Register"},
164                                          {32, 0x29C, "CACR   - L1 Cache Control Register"},
165                                          {32, 0x2A0, "AHBSCR - AHB Slave Control Register"},
166                                          {32, 0x2A8, "ABFSR  - Auxiliary Bus Fault Status Register"}};
167 
168 /*******************************************************************************
169  * Prototypes
170  ******************************************************************************/
171 
172 /*******************************************************************************
173  * Code
174  ******************************************************************************/
175 
176 #if (defined(EXCEPTION_HANDLING_LOG_ENABLE) && (EXCEPTION_HANDLING_LOG_ENABLE == 1U))
EXCEPTION_ConfigurableFaultStatusRegisterPrint(void)177 static void EXCEPTION_ConfigurableFaultStatusRegisterPrint(void)
178 {
179     uint32_t cfsr = SCB->CFSR;
180 
181     /* Configurable Fault Status Register */
182     (void)EXCEPTION_PRINTF("0x%08X - CFSR     - Configurable Fault Status Register\r\n", cfsr);
183     /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */
184     if (0U != (cfsr & SCB_CFSR_IACCVIOL_Msk)) /* SCB CFSR (MMFSR): IACCVIOL Mask */
185     {
186         (void)EXCEPTION_PRINTF(
187             " > The processor attempted an instruction fetch from a location that does not permit execution\r\n");
188     }
189     if (0U != (cfsr & SCB_CFSR_DACCVIOL_Msk)) /* SCB CFSR (MMFSR): DACCVIOL Mask */
190     {
191         (void)EXCEPTION_PRINTF(
192             " > The processor attempted a load or store at a location that does not permit the operation\r\n");
193     }
194     if (0U != (cfsr & SCB_CFSR_MSTKERR_Msk)) /* SCB CFSR (MMFSR): MSTKERR Mask */
195     {
196         (void)EXCEPTION_PRINTF(" > Unstack for an exception return has caused one or more access violations\r\n");
197     }
198     if (0U != (cfsr & SCB_CFSR_MUNSTKERR_Msk)) /* SCB CFSR (MMFSR): MUNSTKERR Mask */
199     {
200         (void)EXCEPTION_PRINTF(" > Stacking for an exception entry has caused one or more access violations\r\n");
201     }
202     if (0U != (cfsr & SCB_CFSR_MLSPERR_Msk)) /* SCB CFSR (MMFSR): MLSPERR Mask */
203     {
204         (void)EXCEPTION_PRINTF(" > A MemManage fault occurred during floating-point lazy state preservation\r\n");
205     }
206     if (0U != (cfsr & SCB_CFSR_MMARVALID_Msk)) /* SCB CFSR (MMFSR): MMARVALID Mask */
207     {
208         (void)EXCEPTION_PRINTF(" > MMAR holds a valid fault address: ");
209         (void)EXCEPTION_PRINTF("0x%08X - MMFAR    - MemManage Fault Address Register\r\n", SCB->MMFAR);
210     }
211 
212     /* BusFault Status Register (part of SCB Configurable Fault Status Register) */
213     if (0U != (cfsr & SCB_CFSR_IBUSERR_Msk)) /* SCB CFSR (BFSR): IBUSERR Mask */
214     {
215         (void)EXCEPTION_PRINTF(" > Instruction bus error\r\n");
216     }
217     if (0U != (cfsr & SCB_CFSR_PRECISERR_Msk)) /* SCB CFSR (BFSR): PRECISERR Mask */
218     {
219         (void)EXCEPTION_PRINTF(
220             " > A data bus error has occurred, PC value stacked for the exception return points to the instruction "
221             "that caused the fault\r\n");
222     }
223     if (0U != (cfsr & SCB_CFSR_IMPRECISERR_Msk)) /* SCB CFSR (BFSR): IMPRECISERR Mask */
224     {
225         (void)EXCEPTION_PRINTF(
226             " > A data bus error has occurred, return address in the stack frame is not related to the instruction "
227             "that caused the error\r\n");
228     }
229     if (0U != (cfsr & SCB_CFSR_UNSTKERR_Msk)) /* SCB CFSR (BFSR): UNSTKERR Mask */
230     {
231         (void)EXCEPTION_PRINTF(" > Unstack for an exception return has caused one or more BusFaults\r\n");
232     }
233     if (0U != (cfsr & SCB_CFSR_STKERR_Msk)) /* SCB CFSR (BFSR): STKERR Mask */
234     {
235         (void)EXCEPTION_PRINTF(" > Stacking for an exception entry has caused one or more BusFaults\r\n");
236     }
237     if (0U != (cfsr & SCB_CFSR_LSPERR_Msk)) /* SCB CFSR (BFSR): LSPERR Mask */
238     {
239         (void)EXCEPTION_PRINTF(" > A bus fault occurred during floating-point lazy state preservation\r\n");
240     }
241     if (0U != (cfsr & SCB_CFSR_BFARVALID_Msk)) /* SCB CFSR (BFSR): BFARVALID Mask */
242     {
243         (void)EXCEPTION_PRINTF(" > BFAR holds a valid fault address: ");
244         (void)EXCEPTION_PRINTF("0x%08X - BFAR     - BusFault Address Register\r\n", SCB->BFAR);
245     }
246 
247     /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */
248     if (0U != (cfsr & SCB_CFSR_UNDEFINSTR_Msk)) /* SCB CFSR (UFSR): UNDEFINSTR Mask */
249     {
250         (void)EXCEPTION_PRINTF(" > The processor has attempted to execute an undefined instruction\r\n");
251     }
252     if (0U != (cfsr & SCB_CFSR_INVSTATE_Msk)) /* SCB CFSR (UFSR): INVSTATE Mask */
253     {
254         (void)EXCEPTION_PRINTF(
255             " > The processor has attempted to execute an instruction that makes illegal use of the EPSR\r\n");
256     }
257     if (0U != (cfsr & SCB_CFSR_INVPC_Msk)) /* SCB CFSR (UFSR): INVPC Mask */
258     {
259         (void)EXCEPTION_PRINTF(" > The processor has attempted an illegal load of EXC_RETURN to the PC\r\n");
260     }
261     if (0U != (cfsr & SCB_CFSR_NOCP_Msk)) /* SCB CFSR (UFSR): NOCP Mask */
262     {
263         (void)EXCEPTION_PRINTF(" > The processor has attempted to access a coprocessor\r\n");
264     }
265     if (0U != (cfsr & SCB_CFSR_UNALIGNED_Msk)) /* SCB CFSR (UFSR): UNALIGNED Mask */
266     {
267         (void)EXCEPTION_PRINTF(" > The processor has made an unaligned memory access\r\n");
268     }
269     if (0U != (cfsr & SCB_CFSR_DIVBYZERO_Msk)) /* SCB CFSR (UFSR): DIVBYZERO Mask */
270     {
271         (void)EXCEPTION_PRINTF(" > The processor has executed an SDIV or UDIV instruction with a divisor of 0\r\n");
272     }
273 }
274 
EXCEPTION_HardFaultStatusRegisterPrint(void)275 static void EXCEPTION_HardFaultStatusRegisterPrint(void)
276 {
277     uint32_t hfsr = SCB->HFSR;
278     /* HardFault Status Register */
279     (void)EXCEPTION_PRINTF("0x%08X - HFSR     - HardFault Status Register\r\n", hfsr);
280 
281     /* SCB Hard Fault Status Register Definitions (part of SCB Configurable Fault Status Register) */
282     if (0U != (hfsr & SCB_HFSR_VECTTBL_Msk)) /* SCB HFSR: VECTTBL Mask */
283     {
284         (void)EXCEPTION_PRINTF(" > BusFault on vector table read\r\n");
285     }
286     if (0U != (hfsr & SCB_HFSR_FORCED_Msk)) /* SCB HFSR: FORCED Mask */
287     {
288         (void)EXCEPTION_PRINTF(" > Forced HardFault\r\n");
289     }
290     if (0U != (hfsr & SCB_HFSR_DEBUGEVT_Msk)) /* SCB HFSR: DEBUGEVT Mask */
291     {
292         (void)EXCEPTION_PRINTF(
293             " > Reserved for Debug use. When writing to the register you must write 1 to this bit, otherwise behavior "
294             "is unpredictable\r\n");
295     }
296 }
297 
EXCEPTION_HardFaultRegisterPrint(void)298 static void EXCEPTION_HardFaultRegisterPrint(void)
299 {
300     (void)EXCEPTION_ConfigurableFaultStatusRegisterPrint();
301     (void)EXCEPTION_HardFaultStatusRegisterPrint();
302     for (uint32_t i = 0; i < ARRAY_SIZE(scb_data_text); i++)
303     {
304         if (32U == scb_data_text[i].type)
305         {
306             (void)EXCEPTION_PRINTF("0x%08X - %s\r\n", *(uint32_t *)(SCB_BASE + scb_data_text[i].offset),
307                              scb_data_text[i].str);
308         }
309         else if (8U == scb_data_text[i].type)
310         {
311             (void)EXCEPTION_PRINTF("0x%08X - %s\r\n", *(uint8_t *)(SCB_BASE + scb_data_text[i].offset), scb_data_text[i].str);
312         }
313         else
314         {
315             /* MISRA C-2012 Rule 15.7 */
316         }
317     }
318 }
319 #endif
320 
EXCEPTION_StackFramePrint(void)321 static void EXCEPTION_StackFramePrint(void)
322 {
323 #if (defined(EXCEPTION_HANDLING_LOG_ENABLE) && (EXCEPTION_HANDLING_LOG_ENABLE == 1U))
324     (void)EXCEPTION_PRINTF("\r\n--- Stack frame -------------------------------------------------------\r\n");
325     (void)EXCEPTION_PRINTF(" IPSR= 0x%08X >>>>> ", g_exceptionStackStruct->IPSR);
326     switch (g_exceptionStackStruct->IPSR & 0xFFU)
327     {
328         case 0:
329             (void)EXCEPTION_PRINTF("Thread mode");
330             break;
331         case 1:
332             (void)EXCEPTION_PRINTF("Reserved 1");
333             break;
334         case 2:
335             (void)EXCEPTION_PRINTF("NMI");
336             break;
337         case 3:
338             (void)EXCEPTION_PRINTF("HardFault");
339             break;
340         case 4:
341             (void)EXCEPTION_PRINTF("MemManage");
342             break;
343         case 5:
344             (void)EXCEPTION_PRINTF("BusFault");
345             break;
346         case 6:
347             (void)EXCEPTION_PRINTF("UsageFault");
348             break;
349         case 7:
350             (void)EXCEPTION_PRINTF("Reserved 7");
351             break;
352         case 8:
353             (void)EXCEPTION_PRINTF("Reserved 8");
354             break;
355         case 9:
356             (void)EXCEPTION_PRINTF("Reserved 9");
357             break;
358         case 10:
359             (void)EXCEPTION_PRINTF("Reserved 10");
360             break;
361         case 11:
362             (void)EXCEPTION_PRINTF("SVCall");
363             break;
364         case 12:
365             (void)EXCEPTION_PRINTF("Reserved for Debug");
366             break;
367         case 13:
368             (void)EXCEPTION_PRINTF("Reserved 13");
369             break;
370         case 14:
371             (void)EXCEPTION_PRINTF("PendSV");
372             break;
373         case 15:
374             (void)EXCEPTION_PRINTF("SysTick");
375             break;
376         default:
377             (void)EXCEPTION_PRINTF("IRQ%d", (g_exceptionStackStruct->IPSR & 0xFFU) - 16U);
378             break;
379     }
380     (void)EXCEPTION_PRINTF(" <<<<<\r\n");
381 
382     (void)EXCEPTION_PRINTF(" R0  = 0x%08X   ", g_exceptionStackStruct->R0);
383     (void)EXCEPTION_PRINTF(" R1  = 0x%08X   ", g_exceptionStackStruct->R1);
384     (void)EXCEPTION_PRINTF(" R2  = 0x%08X   ", g_exceptionStackStruct->R2);
385     (void)EXCEPTION_PRINTF(" R3  = 0x%08X\r\n", g_exceptionStackStruct->R3);
386     (void)EXCEPTION_PRINTF(" R12 = 0x%08X   ", g_exceptionStackStruct->R12);
387     (void)EXCEPTION_PRINTF(" LR  = 0x%08X   ", g_exceptionStackStruct->LR);
388     (void)EXCEPTION_PRINTF(" PC  = 0x%08X   ", g_exceptionStackStruct->PC);
389     (void)EXCEPTION_PRINTF(" PSR = 0x%08X\r\n", g_exceptionStackStruct->xPSR);
390     (void)EXCEPTION_PRINTF(" SP (when faulted)  = 0x%08X\r\n", g_exceptionStackStruct->SP);
391     (void)EXCEPTION_PRINTF("\n--- System Control Block (SCB) ----------------------------------------\r\n");
392     (void)EXCEPTION_HardFaultRegisterPrint();
393     while (0U != (g_exceptionStackStruct->IPSR & 0xFFU))
394     {
395     }
396 
397 #endif
398 }
399 
EXCEPTION_CopyToStack(void)400 static void EXCEPTION_CopyToStack(void)
401 {
402     /* Push SP (when faulted) and IPSR to MSP and save MSP contain the exception Stack Struct to
403      * g_exceptionStackStruct*/
404     COPY_TO_STACK();
405 }
406 
407 void NMI_Handler(void);
NMI_Handler(void)408 void NMI_Handler(void)
409 #if (defined(EXCEPTION_HANDLING_LOG_ENABLE) && (EXCEPTION_HANDLING_LOG_ENABLE == 1U))
410 {
411     EXCEPTION_DataPrint();
412 }
413 #else
414 {
415     while (1)
416     {
417     }
418 }
419 #endif
420 
421 #if (defined(__MCUXPRESSO) && defined(__SEMIHOST_HARDFAULT_DISABLE)) || (!defined(__MCUXPRESSO))
422 void HardFault_Handler(void);
HardFault_Handler(void)423 void HardFault_Handler(void)
424 #if (defined(EXCEPTION_HANDLING_LOG_ENABLE) && (EXCEPTION_HANDLING_LOG_ENABLE == 1U))
425 {
426     EXCEPTION_DataPrint();
427 }
428 #else
429 {
430     while (1)
431     {
432     }
433 }
434 #endif
435 #endif
436 void MemManage_Handler(void);
MemManage_Handler(void)437 void MemManage_Handler(void)
438 #if (defined(EXCEPTION_HANDLING_LOG_ENABLE) && (EXCEPTION_HANDLING_LOG_ENABLE == 1U))
439 {
440     EXCEPTION_DataPrint();
441 }
442 #else
443 {
444     while (1)
445     {
446     }
447 }
448 #endif
449 void BusFault_Handler(void);
BusFault_Handler(void)450 void BusFault_Handler(void)
451 #if (defined(EXCEPTION_HANDLING_LOG_ENABLE) && (EXCEPTION_HANDLING_LOG_ENABLE == 1U))
452 {
453     EXCEPTION_DataPrint();
454 }
455 #else
456 {
457     while (1)
458     {
459     }
460 }
461 #endif
462 void UsageFault_Handler(void);
UsageFault_Handler(void)463 void UsageFault_Handler(void)
464 #if (defined(EXCEPTION_HANDLING_LOG_ENABLE) && (EXCEPTION_HANDLING_LOG_ENABLE == 1U))
465 {
466     EXCEPTION_DataPrint();
467 }
468 #else
469 {
470     while (1)
471     {
472     }
473 }
474 #endif
475 
476 /*!
477  * @brief Exception data print function.
478  *
479  * This function should be called at first place in the ISR where the R0-R3, R12, LR, PC and xPSR
480  * have been saved in the stack by ARM,
481  * so that the SP and IPSR could be saved right after them. By default, exception handling module will
482  * overwrite the following ISR as the reference:
483  * NMI_Handler, HardFault_Handler, MemManage_Handler, BusFault_Handler, UsageFault_Handler.
484  * The users can refer to these ISRs to have their owner ISRs to output the stack frame information.
485  *
486  * At last, all the stack frame information would be output from UART instance initialized in the debug
487  * console if EXCEPTION_HANDLING_LOG_ENABLE is set to 1.
488  * USB CDC could not be supported.
489  * SWO is not supported yet.
490  * If no UART instance is initialized because debug console is not enabled or there is no HW UART instance available,
491  * the users need to route EXCEPTION_PRINTF to an available IO function to output the stack frame information.
492  * This function should NOT be called in the task context.
493  *
494  * @note For MCUXpresso IDE, make sure unselect Include semihost Hardfault handler feature on SDK import wizard,
495  * otherwise HardFault_Handler function of semihost_hardfault.c project will be used on MCUXpresso project.
496  * Make sure __SEMIHOST_HARDFAULT_DISABLE Macro is defined in if want to use  HardFault_Handler function
497  * in exception_handling.c.
498  *
499  * @retval No return vaule.
500  */
501 
EXCEPTION_DataPrint(void)502 void EXCEPTION_DataPrint(void)
503 {
504     /* Here set g_exceptionStackStruct to 0x1 to avoid compiler optimization on some compiler */
505     g_exceptionStackStruct = (exception_stack_data_t *)0x1;
506     (void)EXCEPTION_CopyToStack();
507     (void)EXCEPTION_StackFramePrint();
508 }
509