2 Revize

Autor SHA1 Zpráva Datum
  huangyulong 81a5ca0f74 [add] 浮点寄存器处理 před 1 měsícem
  huangyulong 1b53ae7e2d [add] PRINT_COREDUMP_ELF 0 // 直接打印elf格式 před 2 měsíci

+ 0
- 579
Middlewares/MCoreDump/addr2line.c Zobrazit soubor

@@ -1,579 +0,0 @@
1
-#include "addr2line.h"
2
-
3
-// 错误类型打印
4
-#define DUMP_CPU_ARM_CORTEX_M0          0
5
-#define DUMP_CPU_ARM_CORTEX_M3          1
6
-#define DUMP_CPU_ARM_CORTEX_M4          2
7
-#define DUMP_CPU_ARM_CORTEX_M7          3
8
-
9
-#define DUMP_CPU_PLATFORM_TYPE      DUMP_CPU_ARM_CORTEX_M4
10
-
11
-/* system handler control and state register */
12
-#ifndef DUMP_SYSHND_CTRL
13
-    #define DUMP_SYSHND_CTRL                (*(volatile unsigned int*)  (0xE000ED24u))
14
-#endif
15
-
16
-/* memory management fault status register */
17
-#ifndef DUMP_NVIC_MFSR
18
-    #define DUMP_NVIC_MFSR                  (*(volatile unsigned char*) (0xE000ED28u))
19
-#endif
20
-
21
-/* bus fault status register */
22
-#ifndef DUMP_NVIC_BFSR
23
-    #define DUMP_NVIC_BFSR                  (*(volatile unsigned char*) (0xE000ED29u))
24
-#endif
25
-
26
-/* usage fault status register */
27
-#ifndef DUMP_NVIC_UFSR
28
-    #define DUMP_NVIC_UFSR                  (*(volatile unsigned short*)(0xE000ED2Au))
29
-#endif
30
-
31
-/* hard fault status register */
32
-#ifndef DUMP_NVIC_HFSR
33
-    #define DUMP_NVIC_HFSR                  (*(volatile unsigned int*)  (0xE000ED2Cu))
34
-#endif
35
-
36
-/* debug fault status register */
37
-#ifndef DUMP_NVIC_DFSR
38
-    #define DUMP_NVIC_DFSR                  (*(volatile unsigned short*)(0xE000ED30u))
39
-#endif
40
-
41
-/* memory management fault address register */
42
-#ifndef DUMP_NVIC_MMAR
43
-    #define DUMP_NVIC_MMAR                  (*(volatile unsigned int*)  (0xE000ED34u))
44
-#endif
45
-
46
-/* bus fault manage address register */
47
-#ifndef DUMP_NVIC_BFAR
48
-    #define DUMP_NVIC_BFAR                  (*(volatile unsigned int*)  (0xE000ED38u))
49
-#endif
50
-
51
-/* auxiliary fault status register */
52
-#ifndef DUMP_NVIC_AFSR
53
-    #define DUMP_NVIC_AFSR                  (*(volatile unsigned short*)(0xE000ED3Cu))
54
-#endif
55
-
56
-/**
57
- * Cortex-M fault registers
58
- */
59
-struct dump_hard_fault_regs
60
-{
61
-    struct
62
-    {
63
-        unsigned int r0;                 // Register R0
64
-        unsigned int r1;                 // Register R1
65
-        unsigned int r2;                 // Register R2
66
-        unsigned int r3;                 // Register R3
67
-        unsigned int r12;                // Register R12
68
-        unsigned int lr;                 // Link register
69
-        unsigned int pc;                 // Program counter
70
-        union
71
-        {
72
-            unsigned int value;
73
-            struct
74
-            {
75
-                unsigned int IPSR : 8;   // Interrupt Program Status register (IPSR)
76
-                unsigned int EPSR : 19;  // Execution Program Status register (EPSR)
77
-                unsigned int APSR : 5;   // Application Program Status register (APSR)
78
-            } bits;
79
-        } psr;                           // Program status register.
80
-    } saved;
81
-
82
-    union
83
-    {
84
-        unsigned int value;
85
-        struct
86
-        {
87
-            unsigned int MEMFAULTACT    : 1; // Read as 1 if memory management fault is active
88
-            unsigned int BUSFAULTACT    : 1; // Read as 1 if bus fault exception is active
89
-            unsigned int UnusedBits1    : 1;
90
-            unsigned int USGFAULTACT    : 1; // Read as 1 if usage fault exception is active
91
-            unsigned int UnusedBits2    : 3;
92
-            unsigned int SVCALLACT      : 1; // Read as 1 if SVC exception is active
93
-            unsigned int MONITORACT     : 1; // Read as 1 if debug monitor exception is active
94
-            unsigned int UnusedBits3    : 1;
95
-            unsigned int PENDSVACT      : 1; // Read as 1 if PendSV exception is active
96
-            unsigned int SYSTICKACT     : 1; // Read as 1 if SYSTICK exception is active
97
-            unsigned int USGFAULTPENDED : 1; // Usage fault pended; usage fault started but was replaced by a higher-priority exception
98
-            unsigned int MEMFAULTPENDED : 1; // Memory management fault pended; memory management fault started but was replaced by a higher-priority exception
99
-            unsigned int BUSFAULTPENDED : 1; // Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception
100
-            unsigned int SVCALLPENDED   : 1; // SVC pended; SVC was started but was replaced by a higher-priority exception
101
-            unsigned int MEMFAULTENA    : 1; // Memory management fault handler enable
102
-            unsigned int BUSFAULTENA    : 1; // Bus fault handler enable
103
-            unsigned int USGFAULTENA    : 1; // Usage fault handler enable
104
-        } bits;
105
-    } syshndctrl;                        // System Handler Control and State Register (0xE000ED24)
106
-
107
-    union
108
-    {
109
-        unsigned char value;
110
-        struct
111
-        {
112
-            unsigned char IACCVIOL    : 1; // Instruction access violation
113
-            unsigned char DACCVIOL    : 1; // Data access violation
114
-            unsigned char UnusedBits  : 1;
115
-            unsigned char MUNSTKERR   : 1; // Unstacking error
116
-            unsigned char MSTKERR     : 1; // Stacking error
117
-            unsigned char MLSPERR     : 1; // Floating-point lazy state preservation (M4/M7)
118
-            unsigned char UnusedBits2 : 1;
119
-            unsigned char MMARVALID   : 1; // Indicates the MMAR is valid
120
-        } bits;
121
-    } mfsr;                              // Memory Management Fault Status Register (0xE000ED28)
122
-    unsigned int mmar;                   // Memory Management Fault Address Register (0xE000ED34)
123
-
124
-    union
125
-    {
126
-        unsigned char value;
127
-        struct
128
-        {
129
-            unsigned char IBUSERR    : 1; // Instruction access violation
130
-            unsigned char PRECISERR  : 1; // Precise data access violation
131
-            unsigned char IMPREISERR : 1; // Imprecise data access violation
132
-            unsigned char UNSTKERR   : 1; // Unstacking error
133
-            unsigned char STKERR     : 1; // Stacking error
134
-            unsigned char LSPERR     : 1; // Floating-point lazy state preservation (M4/M7)
135
-            unsigned char UnusedBits : 1;
136
-            unsigned char BFARVALID  : 1; // Indicates BFAR is valid
137
-        } bits;
138
-    } bfsr;                              // Bus Fault Status Register (0xE000ED29)
139
-    unsigned int bfar;                   // Bus Fault Manage Address Register (0xE000ED38)
140
-
141
-    union
142
-    {
143
-        unsigned short value;
144
-        struct
145
-        {
146
-            unsigned short UNDEFINSTR : 1; // Attempts to execute an undefined instruction
147
-            unsigned short INVSTATE   : 1; // Attempts to switch to an invalid state (e.g., ARM)
148
-            unsigned short INVPC      : 1; // Attempts to do an exception with a bad value in the EXC_RETURN number
149
-            unsigned short NOCP       : 1; // Attempts to execute a coprocessor instruction
150
-            unsigned short UnusedBits : 4;
151
-            unsigned short UNALIGNED  : 1; // Indicates that an unaligned access fault has taken place
152
-            unsigned short DIVBYZERO0 : 1; // Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)
153
-        } bits;
154
-    } ufsr;                              // Usage Fault Status Register (0xE000ED2A)
155
-
156
-    union
157
-    {
158
-        unsigned int value;
159
-        struct
160
-        {
161
-            unsigned int UnusedBits  : 1;
162
-            unsigned int VECTBL      : 1; // Indicates hard fault is caused by failed vector fetch
163
-            unsigned int UnusedBits2 : 28;
164
-            unsigned int FORCED      : 1; // Indicates hard fault is taken because of bus fault/memory management fault/usage fault
165
-            unsigned int DEBUGEVT    : 1; // Indicates hard fault is triggered by debug event
166
-        } bits;
167
-    } hfsr;                              // Hard Fault Status Register (0xE000ED2C)
168
-
169
-    union
170
-    {
171
-        unsigned int value;
172
-        struct
173
-        {
174
-            unsigned int HALTED   : 1;   // Halt requested in NVIC
175
-            unsigned int BKPT     : 1;   // BKPT instruction executed
176
-            unsigned int DWTTRAP  : 1;   // DWT match occurred
177
-            unsigned int VCATCH   : 1;   // Vector fetch occurred
178
-            unsigned int EXTERNAL : 1;   // EDBGRQ signal asserted
179
-        } bits;
180
-    } dfsr;                              // Debug Fault Status Register (0xE000ED30)
181
-
182
-    unsigned int afsr;                   // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
183
-};
184
-
185
-enum
186
-{
187
-    PRINT_MAIN_STACK_CFG_ERROR,
188
-    PRINT_FIRMWARE_INFO,
189
-    PRINT_ASSERT_ON_THREAD,
190
-    PRINT_ASSERT_ON_HANDLER,
191
-    PRINT_THREAD_STACK_INFO,
192
-    PRINT_MAIN_STACK_INFO,
193
-    PRINT_THREAD_STACK_OVERFLOW,
194
-    PRINT_MAIN_STACK_OVERFLOW,
195
-    PRINT_CALL_STACK_INFO,
196
-    PRINT_CALL_STACK_ERR,
197
-    PRINT_FAULT_ON_THREAD,
198
-    PRINT_FAULT_ON_HANDLER,
199
-    PRINT_REGS_TITLE,
200
-    PRINT_HFSR_VECTBL,
201
-    PRINT_MFSR_IACCVIOL,
202
-    PRINT_MFSR_DACCVIOL,
203
-    PRINT_MFSR_MUNSTKERR,
204
-    PRINT_MFSR_MSTKERR,
205
-    PRINT_MFSR_MLSPERR,
206
-    PRINT_BFSR_IBUSERR,
207
-    PRINT_BFSR_PRECISERR,
208
-    PRINT_BFSR_IMPREISERR,
209
-    PRINT_BFSR_UNSTKERR,
210
-    PRINT_BFSR_STKERR,
211
-    PRINT_BFSR_LSPERR,
212
-    PRINT_UFSR_UNDEFINSTR,
213
-    PRINT_UFSR_INVSTATE,
214
-    PRINT_UFSR_INVPC,
215
-    PRINT_UFSR_NOCP,
216
-    PRINT_UFSR_UNALIGNED,
217
-    PRINT_UFSR_DIVBYZERO0,
218
-    PRINT_DFSR_HALTED,
219
-    PRINT_DFSR_BKPT,
220
-    PRINT_DFSR_DWTTRAP,
221
-    PRINT_DFSR_VCATCH,
222
-    PRINT_DFSR_EXTERNAL,
223
-    PRINT_MMAR,
224
-    PRINT_BFAR,
225
-};
226
-
227
-static const char *const print_info[] = {
228
-    [PRINT_MAIN_STACK_CFG_ERROR]  = "ERROR: Unable to get the main stack information, please check the configuration of the main stack\n",
229
-    [PRINT_FIRMWARE_INFO]         = "Firmware name: %s, hardware version: %s, software version: %s\n",
230
-    [PRINT_ASSERT_ON_THREAD]      = "Assert on thread %s\n",
231
-    [PRINT_ASSERT_ON_HANDLER]     = "Assert on interrupt or bare metal(no OS) environment\n",
232
-    [PRINT_THREAD_STACK_INFO]     = "===== Thread stack information =====\n",
233
-    [PRINT_MAIN_STACK_INFO]       = "====== Main stack information ======\n",
234
-    [PRINT_THREAD_STACK_OVERFLOW] = "Error: Thread stack(%08x) was overflow\n",
235
-    [PRINT_MAIN_STACK_OVERFLOW]   = "Error: Main stack(%08x) was overflow\n",
236
-    [PRINT_CALL_STACK_INFO]       = "Show more call stack info by run: addr2line -e %s%s -a -f %.*s\n",
237
-    [PRINT_CALL_STACK_ERR]        = "Dump call stack has an error\n",
238
-    [PRINT_FAULT_ON_THREAD]       = "Fault on thread %s\n",
239
-    [PRINT_FAULT_ON_HANDLER]      = "Fault on interrupt or bare metal(no OS) environment\n",
240
-    [PRINT_REGS_TITLE]            = "=================== Registers information ====================\n",
241
-    [PRINT_HFSR_VECTBL]           = "Hard fault is caused by failed vector fetch\n",
242
-    [PRINT_MFSR_IACCVIOL]         = "Memory management fault is caused by instruction access violation\n",
243
-    [PRINT_MFSR_DACCVIOL]         = "Memory management fault is caused by data access violation\n",
244
-    [PRINT_MFSR_MUNSTKERR]        = "Memory management fault is caused by unstacking error\n",
245
-    [PRINT_MFSR_MSTKERR]          = "Memory management fault is caused by stacking error\n",
246
-    [PRINT_MFSR_MLSPERR]          = "Memory management fault is caused by floating-point lazy state preservation\n",
247
-    [PRINT_BFSR_IBUSERR]          = "Bus fault is caused by instruction access violation\n",
248
-    [PRINT_BFSR_PRECISERR]        = "Bus fault is caused by precise data access violation\n",
249
-    [PRINT_BFSR_IMPREISERR]       = "Bus fault is caused by imprecise data access violation\n",
250
-    [PRINT_BFSR_UNSTKERR]         = "Bus fault is caused by unstacking error\n",
251
-    [PRINT_BFSR_STKERR]           = "Bus fault is caused by stacking error\n",
252
-    [PRINT_BFSR_LSPERR]           = "Bus fault is caused by floating-point lazy state preservation\n",
253
-    [PRINT_UFSR_UNDEFINSTR]       = "Usage fault is caused by attempts to execute an undefined instruction\n",
254
-    [PRINT_UFSR_INVSTATE]         = "Usage fault is caused by attempts to switch to an invalid state (e.g., ARM)\n",
255
-    [PRINT_UFSR_INVPC]            = "Usage fault is caused by attempts to do an exception with a bad value in the EXC_RETURN number\n",
256
-    [PRINT_UFSR_NOCP]             = "Usage fault is caused by attempts to execute a coprocessor instruction\n",
257
-    [PRINT_UFSR_UNALIGNED]        = "Usage fault is caused by indicates that an unaligned access fault has taken place\n",
258
-    [PRINT_UFSR_DIVBYZERO0]       = "Usage fault is caused by Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)\n",
259
-    [PRINT_DFSR_HALTED]           = "Debug fault is caused by halt requested in NVIC\n",
260
-    [PRINT_DFSR_BKPT]             = "Debug fault is caused by BKPT instruction executed\n",
261
-    [PRINT_DFSR_DWTTRAP]          = "Debug fault is caused by DWT match occurred\n",
262
-    [PRINT_DFSR_VCATCH]           = "Debug fault is caused by Vector fetch occurred\n",
263
-    [PRINT_DFSR_EXTERNAL]         = "Debug fault is caused by EDBGRQ signal asserted\n",
264
-    [PRINT_MMAR]                  = "The memory management fault occurred address is %08x\n",
265
-    [PRINT_BFAR]                  = "The bus fault occurred address is %08x\n",
266
-};
267
-
268
-static struct dump_hard_fault_regs regs;
269
-
270
-#if (DUMP_CPU_PLATFORM_TYPE != DUMP_CPU_ARM_CORTEX_M0)
271
-/**
272
- * fault diagnosis then print cause of fault
273
- */
274
-static void fault_diagnosis(void)
275
-{
276
-    if (regs.hfsr.bits.VECTBL)
277
-    {
278
-        addr2line_print(print_info[PRINT_HFSR_VECTBL]);
279
-    }
280
-    if (regs.hfsr.bits.FORCED)
281
-    {
282
-        /* Memory Management Fault */
283
-        if (regs.mfsr.value)
284
-        {
285
-            if (regs.mfsr.bits.IACCVIOL)
286
-            {
287
-                addr2line_print(print_info[PRINT_MFSR_IACCVIOL]);
288
-            }
289
-            if (regs.mfsr.bits.DACCVIOL)
290
-            {
291
-                addr2line_print(print_info[PRINT_MFSR_DACCVIOL]);
292
-            }
293
-            if (regs.mfsr.bits.MUNSTKERR)
294
-            {
295
-                addr2line_print(print_info[PRINT_MFSR_MUNSTKERR]);
296
-            }
297
-            if (regs.mfsr.bits.MSTKERR)
298
-            {
299
-                addr2line_print(print_info[PRINT_MFSR_MSTKERR]);
300
-            }
301
-
302
-#if (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M4) || (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M7)
303
-            if (regs.mfsr.bits.MLSPERR)
304
-            {
305
-                addr2line_print(print_info[PRINT_MFSR_MLSPERR]);
306
-            }
307
-#endif
308
-
309
-            if (regs.mfsr.bits.MMARVALID)
310
-            {
311
-                if (regs.mfsr.bits.IACCVIOL || regs.mfsr.bits.DACCVIOL)
312
-                {
313
-                    addr2line_print(print_info[PRINT_MMAR], regs.mmar);
314
-                }
315
-            }
316
-        }
317
-        /* Bus Fault */
318
-        if (regs.bfsr.value)
319
-        {
320
-            if (regs.bfsr.bits.IBUSERR)
321
-            {
322
-                addr2line_print(print_info[PRINT_BFSR_IBUSERR]);
323
-            }
324
-            if (regs.bfsr.bits.PRECISERR)
325
-            {
326
-                addr2line_print(print_info[PRINT_BFSR_PRECISERR]);
327
-            }
328
-            if (regs.bfsr.bits.IMPREISERR)
329
-            {
330
-                addr2line_print(print_info[PRINT_BFSR_IMPREISERR]);
331
-            }
332
-            if (regs.bfsr.bits.UNSTKERR)
333
-            {
334
-                addr2line_print(print_info[PRINT_BFSR_UNSTKERR]);
335
-            }
336
-            if (regs.bfsr.bits.STKERR)
337
-            {
338
-                addr2line_print(print_info[PRINT_BFSR_STKERR]);
339
-            }
340
-
341
-#if (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M4) || (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M7)
342
-            if (regs.bfsr.bits.LSPERR)
343
-            {
344
-                addr2line_print(print_info[PRINT_BFSR_LSPERR]);
345
-            }
346
-#endif
347
-
348
-            if (regs.bfsr.bits.BFARVALID)
349
-            {
350
-                if (regs.bfsr.bits.PRECISERR)
351
-                {
352
-                    addr2line_print(print_info[PRINT_BFAR], regs.bfar);
353
-                }
354
-            }
355
-
356
-        }
357
-        /* Usage Fault */
358
-        if (regs.ufsr.value)
359
-        {
360
-            if (regs.ufsr.bits.UNDEFINSTR)
361
-            {
362
-                addr2line_print(print_info[PRINT_UFSR_UNDEFINSTR]);
363
-            }
364
-            if (regs.ufsr.bits.INVSTATE)
365
-            {
366
-                addr2line_print(print_info[PRINT_UFSR_INVSTATE]);
367
-            }
368
-            if (regs.ufsr.bits.INVPC)
369
-            {
370
-                addr2line_print(print_info[PRINT_UFSR_INVPC]);
371
-            }
372
-            if (regs.ufsr.bits.NOCP)
373
-            {
374
-                addr2line_print(print_info[PRINT_UFSR_NOCP]);
375
-            }
376
-            if (regs.ufsr.bits.UNALIGNED)
377
-            {
378
-                addr2line_print(print_info[PRINT_UFSR_UNALIGNED]);
379
-            }
380
-            if (regs.ufsr.bits.DIVBYZERO0)
381
-            {
382
-                addr2line_print(print_info[PRINT_UFSR_DIVBYZERO0]);
383
-            }
384
-        }
385
-    }
386
-    /* Debug Fault */
387
-    if (regs.hfsr.bits.DEBUGEVT)
388
-    {
389
-        if (regs.dfsr.value)
390
-        {
391
-            if (regs.dfsr.bits.HALTED)
392
-            {
393
-                addr2line_print(print_info[PRINT_DFSR_HALTED]);
394
-            }
395
-            if (regs.dfsr.bits.BKPT)
396
-            {
397
-                addr2line_print(print_info[PRINT_DFSR_BKPT]);
398
-            }
399
-            if (regs.dfsr.bits.DWTTRAP)
400
-            {
401
-                addr2line_print(print_info[PRINT_DFSR_DWTTRAP]);
402
-            }
403
-            if (regs.dfsr.bits.VCATCH)
404
-            {
405
-                addr2line_print(print_info[PRINT_DFSR_VCATCH]);
406
-            }
407
-            if (regs.dfsr.bits.EXTERNAL)
408
-            {
409
-                addr2line_print(print_info[PRINT_DFSR_EXTERNAL]);
410
-            }
411
-        }
412
-    }
413
-}
414
-#endif
415
-
416
-int coredump_fault_diagnosis(void)
417
-{
418
-    /* the Cortex-M0 is not support fault diagnosis */
419
-#if (DUMP_CPU_PLATFORM_TYPE != DUMP_CPU_ARM_CORTEX_M0)
420
-    regs.syshndctrl.value = DUMP_SYSHND_CTRL;  // System Handler Control and State Register
421
-    regs.mfsr.value       = DUMP_NVIC_MFSR;    // Memory Fault Status Register
422
-    regs.mmar             = DUMP_NVIC_MMAR;    // Memory Management Fault Address Register
423
-    regs.bfsr.value       = DUMP_NVIC_BFSR;    // Bus Fault Status Register
424
-    regs.bfar             = DUMP_NVIC_BFAR;    // Bus Fault Manage Address Register
425
-    regs.ufsr.value       = DUMP_NVIC_UFSR;    // Usage Fault Status Register
426
-    regs.hfsr.value       = DUMP_NVIC_HFSR;    // Hard Fault Status Register
427
-    regs.dfsr.value       = DUMP_NVIC_DFSR;    // Debug Fault Status Register
428
-    regs.afsr             = DUMP_NVIC_AFSR;    // Auxiliary Fault Status Register
429
-
430
-    fault_diagnosis();
431
-    return 0;
432
-#endif
433
-
434
-    return -1;
435
-}
436
-
437
-int addr2line_print_stack_before(uint32_t lr)
438
-{
439
-    int on_thread_before_fault = lr & (1UL << 2);
440
-    /* check which stack was used before (MSP or PSP) */
441
-    if (on_thread_before_fault)
442
-        addr2line_print(print_info[PRINT_FAULT_ON_THREAD], rt_thread_self()->name != NULL ? rt_thread_self()->name : "NO_NAME");
443
-    else
444
-        addr2line_print(print_info[PRINT_FAULT_ON_HANDLER]);
445
-
446
-    coredump_fault_diagnosis();
447
-    return 0;
448
-}
449
-
450
-void addr2line_trigger_exception(void)
451
-{
452
-    volatile int *SCB_CCR = (volatile int *)0xE000ED14; // SCB->CCR
453
-    int x, y, z;
454
-
455
-    *SCB_CCR |= (1 << 4);     /* bit4: DIV_0_TRP. */
456
-    x = 10;
457
-    y = strlen("");
458
-    z = x / y;
459
-    addr2line_print("z:%d\n", z);
460
-}
461
-
462
-
463
-// addr to line
464
-#include <stdbool.h>
465
-
466
-#pragma section = ".text"
467
-
468
-static bool is_in_text(uint32_t addr)
469
-{
470
-#if 0
471
-    uint32_t code_start_addr = (uint32_t)&CODE_SECTION_START(CMB_CODE_SECTION_NAME);
472
-    uint32_t code_size = (uint32_t)&CODE_SECTION_END(CMB_CODE_SECTION_NAME) - code_start_addr;
473
-#else
474
-    uint32_t code_start_addr = (uint32_t)__section_begin(".text");
475
-    uint32_t code_size = (uint32_t)__section_end(".text") - code_start_addr;
476
-#endif
477
-
478
-    if (code_start_addr < addr && addr <= code_start_addr + code_size)
479
-    {
480
-        return true;
481
-    }
482
-
483
-    return false;
484
-}
485
-
486
-static bool disassembly_ins_is_bl_blx(uint32_t addr)
487
-{
488
-#define BL_INS_MASK         0xF800
489
-#define BL_INS_HIGH         0xF800
490
-#define BL_INS_LOW          0xF000
491
-#define BLX_INX_MASK        0xFF00
492
-#define BLX_INX             0x4700
493
-
494
-    uint16_t ins1 = *((uint16_t *)addr);
495
-    uint16_t ins2 = *((uint16_t *)(addr + 2));
496
-
497
-    if ((ins2 & BL_INS_MASK) == BL_INS_HIGH && (ins1 & BL_INS_MASK) == BL_INS_LOW)
498
-    {
499
-        return true;
500
-    }
501
-    else if ((ins2 & BLX_INX_MASK) == BLX_INX)
502
-    {
503
-        return true;
504
-    }
505
-    else
506
-    {
507
-        return false;
508
-    }
509
-}
510
-
511
-void addr2line_print(uint32_t *addr, int size)
512
-{
513
-    addr2line_print("\naddr2line -e " PROJECT_NAME " -a -f ");
514
-    size /= sizeof(uint32_t);
515
-
516
-    for (int i = 1; i < size; i++)
517
-    {
518
-        const uint32_t lr = addr[i];
519
-
520
-        if (false == is_in_text(lr))
521
-            continue;
522
-
523
-        uint32_t pc = lr - sizeof(size_t); // 假设当前是lr寄存器的值,向下增长4就是pc寄存器的值
524
-
525
-        if (pc % 2 == 0) // thumb 指令pc寄存器值一定是偶数
526
-            continue;
527
-
528
-        pc = lr - 1; // lr寄存器值保存的是pc+1
529
-
530
-        if (true == disassembly_ins_is_bl_blx(pc - sizeof(size_t))) // pc 的上一条指令是跳转指令
531
-            addr2line_print("%08x ", pc);
532
-    }
533
-
534
-    addr2line_print("\n");
535
-}
536
-
537
-#if 0
538
-static void test_addr2line(void)
539
-{
540
-    uint32_t sg_test_stack[] =
541
-    {
542
-        0x00000001, 0x000514d5, 0x000000f0, 0x00000001,
543
-        0x000c3fcc, 0x00000000, 0x000538b4, 0x00549822,
544
-        0xdeadbeef, 0x00000000, 0x00000000, 0x00000000,
545
-        0x00000000, 0x00000000, 0x00000000, 0x00000000,
546
-        0x00000000, 0x00000000, 0x00000000, 0x00000000,
547
-        0x00000000, 0x00000000, 0x00000000, 0x00000000,
548
-        0x00000000, 0x0000000a, 0x00000210, 0x00000000,
549
-        0x00000000, 0x00000006, 0x000514eb, 0x000516f8,
550
-        0x49000000, 0x00000004, 0x0000007d, 0x00000000,
551
-        0x00000000, 0x00000000, 0x00000000, 0x00000000,
552
-        0x00000000, 0x00000000, 0x00000000, 0x00000000,
553
-        0x00000000, 0x00000000, 0x00000000, 0x00000000,
554
-        0x00000000, 0x00000010, 0x00000000, 0x00000200,
555
-        0x00000000, 0x000008f4, 0x000537bb, 0x000000f0,
556
-        0x00000000, 0x00000001, 0x00000002, 0x20033378,
557
-        0x000468e3, 0x00000000, 0x20036c3c, 0x20036c78,
558
-        0x000b8789, 0x00000000, 0x20016dd8, 0x20008198,
559
-        0x000b819f, 0x00000000, 0x2003727c, 0x20016dd8,
560
-        0x0006047f, 0x00000050, 0x00000000, 0x20016dd8,
561
-        0x00000001, 0x00000001, 0x000604dd, 0x00000000,
562
-        0x2003092c, 0x20030b1c, 0x200334f4, 0x200334b4,
563
-        0x00060215, 0x2003764c, 0x20036e98, 0x00000008,
564
-        0x200081f4, 0x200334b4, 0x00000000, 0x0068007a,
565
-        0x00000000, 0x20030b1c, 0x00063dd3, 0x007a0068,
566
-        0x00000000, 0x00000000, 0x00000000, 0x00000000,
567
-        0xffffffff, 0x20033520, 0x2003060c, 0x2002cc84,
568
-        0x2002cbf4, 0x20033378, 0x0005ce35, 0x20030e20,
569
-        0x000d17c8, 0x20030214, 0x00000014, 0xdeadbeef,
570
-        0xdeadbeef, 0xdeadbeef, 0x00057c99, 0x00000000,
571
-        0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
572
-        0x000302e7
573
-    };
574
-
575
-    uint32_t *addr = sg_test_stack;
576
-    int size = sizeof(sg_test_stack);
577
-    _addr2line_print(addr, size);
578
-}
579
-#endif

+ 0
- 11
Middlewares/MCoreDump/addr2line.h Zobrazit soubor

@@ -1,11 +0,0 @@
1
-#ifndef ADDR2LINE_H
2
-#define ADDR2LINE_H
3
-
4
-// 触发一个异常
5
-void addr2line_trigger_exception(void);
6
-// 打印地址供CMD命令行运行
7
-void addr2line_print(uint32_t *addr, int size);
8
-// 打印异常错误类型
9
-int addr2line_print_stack_before(uint32_t exc_return);
10
-
11
-#endif

+ 4
- 2
Middlewares/MCoreDump/arch/armv7m/armv7m.c Zobrazit soubor

@@ -285,8 +285,9 @@ void print_registers_armv7m(core_regset_type *reg, fp_regset_type *fp_reg, char
285 285
  * @param fp_regset Pointer to structure for storing FPU registers
286 286
  */
287 287
 // 通过sp指针得到寄存器信息
288
-void collect_registers_armv7m(uint32_t *stack_top, core_regset_type *core_regset, fp_regset_type *fp_regset)
288
+uint32_t collect_registers_armv7m(uint32_t *stack_top, core_regset_type *core_regset, fp_regset_type *fp_regset)
289 289
 {
290
+    uint32_t fpu_flag = 0;
290 291
     /*
291 292
      * This function uses the same stack frame parsing approach as collect_registers_armv7ms
292 293
      * for consistency. Both PendSV_Handler and HardFault_Handler now use identical
@@ -303,7 +304,7 @@ void collect_registers_armv7m(uint32_t *stack_top, core_regset_type *core_regset
303 304
 
304 305
 #if MCD_FPU_SUPPORT
305 306
     /* Read FPU flag first - indicates if FPU context was saved */
306
-    uint32_t fpu_flag = *current_ptr++;
307
+    fpu_flag = *current_ptr++;
307 308
 #endif
308 309
 
309 310
     /* Extract core registers r4-r11 (software saved by RT-Thread) */
@@ -358,6 +359,7 @@ void collect_registers_armv7m(uint32_t *stack_top, core_regset_type *core_regset
358 359
 
359 360
     /* SP should point to the current stack pointer position after all saved data */
360 361
     core_regset->sp = (uintptr_t)current_ptr;
362
+    return fpu_flag;
361 363
 }
362 364
 
363 365
 /**

+ 1
- 1
Middlewares/MCoreDump/arch/mcd_arch_interface.h Zobrazit soubor

@@ -33,7 +33,7 @@ int armv7m_hard_fault_exception_hook(void *context);
33 33
  * @param core_regset Pointer to store ARM core registers
34 34
  * @param fp_regset Pointer to store FPU registers
35 35
  */
36
-void collect_registers_armv7m(uint32_t *stack_top, core_regset_type *core_regset, fp_regset_type *fp_regset);
36
+uint32_t collect_registers_armv7m(uint32_t *stack_top, core_regset_type *core_regset, fp_regset_type *fp_regset);
37 37
 
38 38
 // 打印寄存器
39 39
 void print_registers_armv7m(core_regset_type *reg, fp_regset_type *fp_reg, char *thread);

+ 11
- 0
Middlewares/MCoreDump/coredump.c Zobrazit soubor

@@ -199,6 +199,9 @@ void mcd_init(mcd_writeout_func_t func)
199 199
 
200 200
 static void fill_one_threads_regset(core_regset_type *core_regset, fp_regset_type *fp_regset)
201 201
 {
202
+    if (NULL == m_ctx.writeout_func)
203
+        return;
204
+
202 205
     fill_note_prstatus(&m_ctx.tmp.prstatus, core_regset);
203 206
     m_ctx.writeout_func((uint8_t *)&m_ctx.tmp.prstatus, sizeof(elf_note_prstatus_t));
204 207
 
@@ -218,6 +221,10 @@ static void addr_align(uint32_t *addr, uint32_t *memlen)
218 221
 // 生成.elf格式
219 222
 void mcd_gen_coredump(struct thread_info_ops *ops)
220 223
 {
224
+    if (NULL == ops || NULL == ops->get_memarea_count || NULL == ops->get_memarea
225
+        || NULL == ops->get_thread_regset || NULL == m_ctx.writeout_func)
226
+        return;
227
+
221 228
     int note_size;
222 229
     uint32_t addr, memlen;
223 230
 
@@ -265,6 +272,9 @@ void mcd_gen_coredump(struct thread_info_ops *ops)
265 272
 
266 273
 int32_t mcd_corefile_size(struct thread_info_ops *ops)
267 274
 {
275
+    if (NULL == ops || NULL == ops->get_memarea_count || NULL == ops->get_memarea)
276
+        return 0;
277
+
268 278
     int elf_size = 0;
269 279
     int segment_count;
270 280
     uint32_t addr, memlen;
@@ -337,6 +347,7 @@ static int32_t minidump_memarea(struct thread_info_ops *ops, int32_t idx,
337 347
 
338 348
 void mcd_mini_dump_ops(struct thread_info_ops *ops)
339 349
 {
350
+    memset(ops, 0, sizeof(struct thread_info_ops));
340 351
     ops->get_threads_count = minidump_thr_cnts;
341 352
     ops->get_current_thread_idx = minidump_cur_idx;
342 353
     ops->get_thread_regset = minidump_thr_rset;

+ 1
- 1
Middlewares/MCoreDump/mcd_cfg.h Zobrazit soubor

@@ -40,7 +40,7 @@
40 40
 /* RT-Thread print functions */
41 41
 #ifndef RT_USING_ULOG
42 42
 /* Use rt_kprintf directly */
43
-#define mcd_println(...)               rt_kprintf(__VA_ARGS__);rt_kprintf("\r\n")
43
+#define mcd_println(...)               do{rt_kprintf(__VA_ARGS__);rt_kprintf("\r\n");}while(0)
44 44
 #define mcd_print(...)                 rt_kprintf(__VA_ARGS__)
45 45
 #else /* RT_USING_ULOG */
46 46
 /* Use ulog for unified logging */

+ 41
- 20
Middlewares/MCoreDump/rtthread_port.c Zobrazit soubor

@@ -13,10 +13,18 @@
13 13
 #include "arch/mcd_arch_interface.h"
14 14
 #include "addr2line/addr2line.h"
15 15
 
16
-#define PRINT_COREDUMP_INFO_STRING 1 // 打印字符串格式的coredump信息
16
+#define PRINT_COREDUMP_ELF 1 // 直接打印elf格式
17
+#define PRINT_COREDUMP_INFO_STRING 0 // 打印字符串格式的coredump信息
17 18
 #define STACK_CORE_REG_SIZE (17 * 4) // 16个自动+手动压栈寄存器 + exe_return
18
-#define STACK_FPU_REG_SIZE (17 * 4) // 17个自动压栈的浮点寄存器
19
+#define STACK_FPU_REG_SIZE (16 * 4) // 16个自动压栈的浮点寄存器
19 20
 
21
+static rt_int32_t is_thread_object(rt_thread_t thread)
22
+{
23
+    /* Check if the object is a thread (both static and dynamic) */
24
+    return ((thread->type & ~RT_Object_Class_Static) == RT_Object_Class_Thread);
25
+}
26
+
27
+#if PRINT_COREDUMP_ELF
20 28
 /*
21 29
  * RT-Thread OS abstraction layer implementation for MCoreDump
22 30
  */
@@ -26,12 +34,6 @@ typedef struct
26 34
     rt_int32_t cur_idx;
27 35
 } rtthread_ti_priv_t;
28 36
 
29
-static rt_int32_t is_thread_object(rt_thread_t thread)
30
-{
31
-    /* Check if the object is a thread (both static and dynamic) */
32
-    return ((thread->type & ~RT_Object_Class_Static) == RT_Object_Class_Thread);
33
-}
34
-
35 37
 static int32_t rtthread_thread_cnts(struct thread_info_ops *ops)
36 38
 {
37 39
     rtthread_ti_priv_t *priv = (rtthread_ti_priv_t *)ops->priv;
@@ -167,7 +169,7 @@ static int32_t rtthread_get_memarea(struct thread_info_ops *ops, int32_t idx,
167 169
                     *memlen += STACK_CORE_REG_SIZE * 2; // 前后括大两倍:实际可能更多局部变量在死机前还没来得及向下增长sp
168 170
 #if MCD_FPU_SUPPORT
169 171
                     /* Read FPU flag first - indicates if FPU context was saved */
170
-                    uint32_t fpu_flag = *(uint32_t *)thread->sp;
172
+                    uint32_t fpu_flag = 0 != get_cur_fp_regset_address()->fpscr; // 异常标志位肯定被置位
171 173
                     *addr -= 1;
172 174
                     *memlen += 1;
173 175
 
@@ -196,11 +198,12 @@ static int32_t rtthread_get_memarea(struct thread_info_ops *ops, int32_t idx,
196 198
     }
197 199
     return 0;
198 200
 }
201
+#endif
199 202
 
200 203
 #if PRINT_COREDUMP_INFO_STRING
201 204
 static int mcd_print_coredump_info_string(struct thread_info_ops *ops)
202 205
 {
203
-    rt_int32_t current_idx = rtthread_cur_index(ops);
206
+    rt_thread_t current_thread = rt_thread_self();
204 207
     rt_int32_t idx_l = 0;
205 208
     struct rt_object_information *information;
206 209
     struct rt_object *object;
@@ -220,7 +223,7 @@ static int mcd_print_coredump_info_string(struct thread_info_ops *ops)
220 223
         if (is_thread_object(thread))
221 224
         {
222 225
             /* If this is the current thread, use current stack pointer */
223
-            if (idx_l == current_idx)
226
+            if (thread == current_thread)
224 227
             {
225 228
                 uint32_t fpu_flag = 0;
226 229
                 addr = (rt_uint32_t)get_cur_core_regset_address()->sp;      // 异常中填充
@@ -229,7 +232,7 @@ static int mcd_print_coredump_info_string(struct thread_info_ops *ops)
229 232
                 memlen += STACK_CORE_REG_SIZE * 2; // 前后括大两倍:实际可能更多局部变量在死机前还没来得及向下增长sp
230 233
 #if MCD_FPU_SUPPORT
231 234
                 /* Read FPU flag first - indicates if FPU context was saved */
232
-                fpu_flag = *(uint32_t *)thread->sp;
235
+                fpu_flag = 0 != get_cur_fp_regset_address()->fpscr; // 异常标志位肯定被置位
233 236
                 addr -= 1;
234 237
                 memlen += 1;
235 238
 
@@ -251,12 +254,12 @@ static int mcd_print_coredump_info_string(struct thread_info_ops *ops)
251 254
             }
252 255
             else
253 256
             {
254
-                mcd_print("Thread index:%d\n", idx_l + 1);
255 257
                 addr = (rt_uint32_t)thread->sp;
256
-                memlen = (rt_uint32_t)thread->stack_addr + thread->stack_size - (rt_uint32_t)thread->sp;
257
-                core_regset_type core_regset;
258
-                fp_regset_type fp_regset;
259
-                collect_registers((uint32_t *)thread->sp, &core_regset, &fp_regset); // rtos栈寄存器格式转换成core_regset类型的
258
+                memlen = (rt_uint32_t)thread->stack_addr + thread->stack_size - addr;
259
+                core_regset_type core_regset = {0};
260
+                fp_regset_type fp_regset = {0};
261
+                uint32_t use_fpu = collect_registers((uint32_t *)addr, &core_regset, &fp_regset); // rtos栈寄存器格式转换成core_regset类型的
262
+                mcd_print("Thread index:%d (fpu:%d)\n", idx_l + 1, use_fpu);
260 263
                 print_registers(&core_regset, &fp_regset, thread->name);
261 264
                 addr2line_cmd_with_pc_print((rt_uint32_t *)core_regset.pc, (uint32_t *)addr, memlen);
262 265
             }
@@ -273,24 +276,29 @@ static int mcd_print_coredump_info_string(struct thread_info_ops *ops)
273 276
 
274 277
 void mcd_rtos_thread_ops(struct thread_info_ops *ops)
275 278
 {
279
+    memset(ops, 0, sizeof(struct thread_info_ops));
280
+#if PRINT_COREDUMP_ELF
276 281
     static rtthread_ti_priv_t priv;
277 282
     ops->get_threads_count = rtthread_thread_cnts;
278 283
     ops->get_current_thread_idx = rtthread_cur_index;
279 284
     ops->get_thread_regset = rtthread_thread_register;
280 285
     ops->get_memarea_count = rtthread_get_mem_cnts;
281 286
     ops->get_memarea = rtthread_get_memarea;
282
-#if PRINT_COREDUMP_INFO_STRING
283
-    ops->print_info_string = mcd_print_coredump_info_string;
284
-#endif
285 287
     ops->priv = &priv;
286 288
     priv.cur_idx = -1;
287 289
     priv.thr_cnts = -1;
290
+#endif
291
+#if PRINT_COREDUMP_INFO_STRING
292
+    ops->print_info_string = mcd_print_coredump_info_string;
293
+#endif
294
+
288 295
 }
289 296
 
290 297
 MCD_WEAK rt_err_t rtt_hard_fault_exception_hook(void *context)
291 298
 {
292 299
     arch_hard_fault_exception_hook(context);
293 300
     addr2line_print_stack_before((uint32_t)context);
301
+    //error_user_info_print();
294 302
     return -RT_ERROR;
295 303
 }
296 304
 
@@ -304,11 +312,24 @@ MCD_WEAK void rtt_assert_hook(const char *ex, const char *func, rt_size_t line)
304 312
 
305 313
     mcd_faultdump(MCD_OUTPUT_SERIAL);
306 314
 
315
+    error_user_info_print();
307 316
     rt_interrupt_leave();
308 317
 
309 318
     while (_continue == 1);
310 319
 }
311 320
 
321
+void coredump_trigger_exception(void)
322
+{
323
+    volatile int *SCB_CCR = (volatile int *)0xE000ED14; // SCB->CCR
324
+    int x, y, z;
325
+
326
+    *SCB_CCR |= (1 << 4);     /* bit4: DIV_0_TRP. */
327
+    x = 10;
328
+    y = strlen("");
329
+    z = x / y;
330
+    rt_kprintf("z:%d\n", z);
331
+}
332
+
312 333
 static int mcd_coredump_init(void)
313 334
 {
314 335
     //mcd_print_memoryinfo();

+ 48
- 0
Middlewares/rtthread/libcpu/arm/cortex-m3/context_iar.S Zobrazit soubor

@@ -202,4 +202,52 @@ _update_done
202 202
     
203 203
 #endif
204 204
 
205
+#if 0 // 带浮点寄存器的
206
+    IMPORT rt_hw_hard_fault_exception
207
+    EXPORT HardFault_Handler
208
+HardFault_Handler:
209
+
210
+    ; get current context
211
+    MRS     r0, msp                 ; get fault context from handler.
212
+    TST     lr, #0x04               ; if(!EXC_RETURN[2])
213
+    BEQ     _get_sp_done1
214
+    MRS     r0, psp                 ; get fault context from thread.
215
+_get_sp_done1
216
+
217
+#if defined ( __ARMVFP__ )
218
+    TST     lr, #0x10               ; if(!EXC_RETURN[4])
219
+    BNE     skip_push_fpu1
220
+    VSTMDB  r0!, {d8 - d15}         ; push FPU register s16~s31
221
+skip_push_fpu1
222
+#endif
223
+
224
+    STMFD   r0!, {r4 - r11}         ; push r4 - r11 register
225
+
226
+#if defined ( __ARMVFP__ )
227
+    MOV     r4, #0x00               ; flag = 0
228
+    TST     lr, #0x10               ; if(!EXC_RETURN[4])
229
+    BNE     push_flag1
230
+    MOV     r4, #0x01               ; flag = 1
231
+push_flag1
232
+    STMFD   r0!, {r4}              ; push flag
233
+#endif
234
+
235
+    STMFD   r0!, {lr}              ; push flag
236
+
237
+    TST     lr, #0x04               ; if(!EXC_RETURN[2])
238
+    BEQ     _update_msp1
239
+    MSR     psp, r0                 ; update stack pointer to PSP.
240
+    B       _update_done1
241
+_update_msp1
242
+    MSR     msp, r0                 ; update stack pointer to MSP.
243
+_update_done1
244
+
245
+    PUSH    {lr}
246
+    BL      rt_hw_hard_fault_exception
247
+    POP     {lr}
248
+
249
+    ORR     lr, lr, #0x04
250
+    BX      lr
251
+#endif
252
+
205 253
     END

Načítá se…
Zrušit
Uložit