1 /* USER CODE BEGIN Header */
2 /**
3   ******************************************************************************
4   * @file    crash_handler.h
5   * @author  GPM WBL Application Team
6   * @brief   This header file defines the crash handler framework useful for
7   *          application issues debugging
8   ******************************************************************************
9   * @attention
10   *
11   * Copyright (c) 2024 STMicroelectronics.
12   * All rights reserved.
13   *
14   * This software is licensed under terms that can be found in the LICENSE file
15   * in the root directory of this software component.
16   * If no LICENSE file comes with this software, it is provided AS-IS.
17   *
18   ******************************************************************************
19   */
20 /* USER CODE END Header */
21 
22 /* Define to prevent recursive inclusion -------------------------------------*/
23 
24 #ifndef __CRASH_HANDLER_H_
25 #define __CRASH_HANDLER_H_
26 
27 #include <stdint.h>
28 #include <string.h>
29 #include "cmsis_compiler.h"
30 
31 /**
32  * @brief Number of word for the Exception RAM Locations
33  */
34 #define NMB_OF_EXCEP_RAM_WORD 10
35 
36 /**
37  * @brief Base address to store the Crash Information
38  */
39 #define CRASH_RAM_SIZE          40
40 
41 /**
42  * @brief Signature Information: CRASH_SIGNATURE_BASE
43  */
44 #define CRASH_SIGNATURE_BASE     0xBCEC0000
45 /**
46  * @brief Signature Information: ASSERT_SIGNATURE
47  */
48 #define ASSERT_SIGNATURE     (CRASH_SIGNATURE_BASE + 0)
49 /**
50  * @brief Signature Information: NMI_SIGNATURE
51  */
52 #define NMI_SIGNATURE        (CRASH_SIGNATURE_BASE + 1)
53 /**
54  * @brief Signature Information: HARD_FAULT_SIGNATURE
55  */
56 #define HARD_FAULT_SIGNATURE (CRASH_SIGNATURE_BASE + 2)
57 /**
58  * @brief Signature Information: WATCHDOG_SIGNATURE
59  */
60 #define WATCHDOG_SIGNATURE   (CRASH_SIGNATURE_BASE +3)
61 
62 /**
63  * @brief Typedef for the overall crash information (stack pointer, program counter, registers, ...)
64  */
65 typedef struct crash_infoS {
66   uint32_t signature;
67   uint32_t SP;
68   uint32_t R0;
69   uint32_t R1;
70   uint32_t R2;
71   uint32_t R3;
72   uint32_t R12;
73   uint32_t LR;
74   uint32_t PC;
75   uint32_t xPSR;
76 } crash_info_t;
77 
78 extern crash_info_t crash_info_ram;
79 
80 /**
81  * @brief Macro to store in RAM the register information where an assert is verified.
82  *
83  * All the information stored are words (32 bit):
84  * - Assert Signature
85  * - SP
86  * - R0
87  * - R1
88  * - R2
89  * - R3
90  * - R12
91  * - LR
92  * - PC
93  * - xPSR
94  */
95 #define ASSERT_HANDLER(expression) {                                              \
96   volatile uint32_t * crash_info = (volatile uint32_t *)&crash_info_ram;  \
97   register uint32_t reg_content;                                                  \
98   if (!(expression)) {                                                            \
99    /* Init to zero the crash_info RAM locations */                                \
100    for (reg_content=0; reg_content<NMB_OF_EXCEP_RAM_WORD; reg_content++) {        \
101      *crash_info = 0;                                                             \
102      crash_info++;                                                                \
103    }                                                                              \
104    crash_info = (volatile uint32_t *)&crash_info_ram;                     \
105    /* Store Crash Signature */                                                    \
106    *crash_info = ASSERT_SIGNATURE;                                                \
107    crash_info+=2;                                                                 \
108    /* Store R0 register */                                                        \
109    __ASM volatile ("MOV %0, R0" : "=r" (reg_content) );                           \
110    *crash_info = reg_content;                                                     \
111    crash_info--;                                                                  \
112    /* Store SP register */                                                        \
113    __ASM volatile ("MOV %0, SP" : "=r" (reg_content) );                           \
114    *crash_info = reg_content;                                                     \
115    crash_info+=2;                                                                 \
116    /* Store R1 register */                                                        \
117    __ASM volatile ("MOV %0, R1" : "=r" (reg_content) );                           \
118    *crash_info = reg_content;                                                     \
119    crash_info++;                                                                  \
120    /* Store R2 register */                                                        \
121    __ASM volatile ("MOV %0, R2" : "=r" (reg_content) );                           \
122    *crash_info = reg_content;                                                     \
123    crash_info++;                                                                  \
124    /* Store R3 register */                                                        \
125    __ASM volatile ("MOV %0, R3" : "=r" (reg_content) );                           \
126    *crash_info = reg_content;                                                     \
127    crash_info++;                                                                  \
128    /* Store R12 register */                                                       \
129    __ASM volatile ("MOV %0, R12" : "=r" (reg_content) );                          \
130    *crash_info = reg_content;                                                     \
131    crash_info++;                                                                  \
132    /* Store LR register */                                                        \
133    __ASM volatile ("MOV %0, LR" : "=r" (reg_content) );                           \
134    *crash_info = reg_content;                                                     \
135    crash_info++;                                                                  \
136    /* Store PC register */                                                        \
137    __ASM volatile ("MOV %0, PC" : "=r" (reg_content) );                           \
138    *crash_info = reg_content;                                                     \
139    crash_info++;                                                                  \
140    /* Store xPSR register */                                                      \
141    __ASM volatile ("MRS %0, PSR" : "=r" (reg_content) );                          \
142    *crash_info = reg_content;                                                     \
143    crash_info++;                                                                  \
144   }                                                                               \
145 }                                                                                 \
146 
147 #endif /* __CRASH_HANDLER_H_ */
148