µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
exception-handlers.c
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2015-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#if defined(__clang__)
13#pragma clang diagnostic ignored "-Wempty-translation-unit"
14#endif
15
16// ----------------------------------------------------------------------------
17
18#if defined(__ARM_EABI__)
19
20// ----------------------------------------------------------------------------
21
22#if defined(OS_USE_OS_APP_CONFIG_H)
23#include <cmsis-plus/os-app-config.h>
24#endif
25
26#include <cmsis-plus/rtos/port/os-c-decls.h>
27
28#include <cmsis_device.h>
32
33#include <string.h>
34
35// ----------------------------------------------------------------------------
36
37#pragma GCC diagnostic push
38#pragma GCC diagnostic ignored "-Wredundant-decls"
39
40extern void __attribute__ ((noreturn, weak))
41_start (void);
42
43#pragma GCC diagnostic pop
44
45extern unsigned int _Heap_Limit;
46extern unsigned int __stack;
47
48typedef void (*handler_ptr_t) (void);
49
51
52// ----------------------------------------------------------------------------
53
54// Default exception handlers.
55// Weak definitions, override them with similar
56// handler routines defined in the application code.
57//
58// The ARCH_7M exception handlers are:
59// 0x00 stack
60// 0x04 Reset
61// 0x08 NMI
62// 0x0C HardFault
63// 0x10 MemManage
64// 0x14 BusFault
65// 0x18 UsageFault
66// 0x1C 0
67// 0x20 0
68// 0x24 0
69// 0x28 0
70// 0x2C SVC
71// 0x30 DebugMon
72// 0x34 0
73// 0x38 PendSV
74// 0x3C SysTick
75
76// ----------------------------------------------------------------------------
77
78// This function is not naked, and has a proper stack frame,
79// to allow setting breakpoints at Reset_Handler.
80void __attribute__ ((section (".after_vectors"), noreturn, weak))
82{
83 // For just in case, when started via QEMU.
84 __asm__ (" MSR msp, %0 " : : "r"(&__stack) :);
85
86 // SCB
87 // https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/system-control-block
88
89 // SCB->VTOR
90 // https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/system-control-block/vector-table-offset-register
91 // Mandatory when running from RAM. Not available on Cortex-M0.
92#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
93 *((uint32_t*)0xE000ED08)
94 = ((uint32_t)_interrupt_vectors & (uint32_t)(~0x3F));
95#endif
96
97#if defined(__ARM_FP)
98 // Enable CP10 and CP11 coprocessor.
99 // SCB->CPACR |= (0xF << 20);
100 *((uint32_t*)0xE000ED88) |= (uint32_t)(0xF << 20);
101
102 // Lazy save.
103 // FPU->FPCCR |= FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk;
104 *((uint32_t*)0xE000EF34) |= (uint32_t)(0x3 << 29);
105#endif // defined(__ARM_FP)
106
107 // Fill the main stack with a pattern, to detect usage and underflow.
108 for (unsigned int* p = &_Heap_Limit; p < &__stack;)
109 {
110 *p++ = OS_INTEGER_RTOS_STACK_FILL_MAGIC; // DEADBEEF
111 }
112
113 _start ();
114}
115
116void __attribute__ ((section (".after_vectors"), weak))
118{
119#if defined(DEBUG)
120#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
121 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
122 {
123 __BKPT (0);
124 }
125#else
126 __BKPT (0);
127#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
128#endif /* defined(DEBUG) */
129
130 while (true)
131 {
132 __NOP ();
133 }
134}
135
136// ----------------------------------------------------------------------------
137
138#if defined(TRACE)
139
140#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
141
142// The values of BFAR and MMFAR remain unchanged if the BFARVALID or
143// MMARVALID is set. However, if a new fault occurs during the
144// execution of this fault handler, the value of the BFAR and MMFAR
145// could potentially be erased. In order to ensure the fault addresses
146// accessed are valid, the following procedure should be used:
147// 1. Read BFAR/MMFAR.
148// 2. Read CFSR to get BFARVALID or MMARVALID. If the value is 0, the
149// value of BFAR or MMFAR accessed can be invalid and can be discarded.
150// 3. Optionally clear BFARVALID or MMARVALID.
151// (See Joseph Yiu's book).
152
153void
154dump_exception_stack (exception_stack_frame_t* frame, uint32_t cfsr,
155 uint32_t mmfar, uint32_t bfar, uint32_t lr)
156{
157 trace_printf ("Stack frame:\n");
158 trace_printf (" R0 = %08X\n", frame->r0);
159 trace_printf (" R1 = %08X\n", frame->r1);
160 trace_printf (" R2 = %08X\n", frame->r2);
161 trace_printf (" R3 = %08X\n", frame->r3);
162 trace_printf (" R12 = %08X\n", frame->r12);
163 trace_printf (" LR = %08X\n", frame->lr);
164 trace_printf (" PC = %08X\n", frame->pc);
165 trace_printf (" PSR = %08X\n", frame->psr);
166 trace_printf ("FSR/FAR:\n");
167 trace_printf (" CFSR = %08X\n", cfsr);
168 trace_printf (" HFSR = %08X\n", SCB->HFSR);
169 trace_printf (" DFSR = %08X\n", SCB->DFSR);
170 trace_printf (" AFSR = %08X\n", SCB->AFSR);
171
172 if (cfsr & (1UL << 7))
173 {
174 trace_printf (" MMFAR= %08X\n", mmfar);
175 }
176 if (cfsr & (1UL << 15))
177 {
178 trace_printf (" BFAR = %08X\n", bfar);
179 }
180 trace_printf ("Misc\n");
181 trace_printf (" LR/EXC_RETURN = %08X\n", lr);
182}
183
184#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
185
186#if defined(__ARM_ARCH_6M__)
187
188void
189dump_exception_stack (exception_stack_frame_t* frame, uint32_t lr)
190{
191 trace_printf ("Stack frame:\n");
192 trace_printf (" R0 = %08X\n", frame->r0);
193 trace_printf (" R1 = %08X\n", frame->r1);
194 trace_printf (" R2 = %08X\n", frame->r2);
195 trace_printf (" R3 = %08X\n", frame->r3);
196 trace_printf (" R12 = %08X\n", frame->r12);
197 trace_printf (" LR = %08X\n", frame->lr);
198 trace_printf (" PC = %08X\n", frame->pc);
199 trace_printf (" PSR = %08X\n", frame->psr);
200 trace_printf ("Misc\n");
201 trace_printf (" LR/EXC_RETURN = %08X\n", lr);
202}
203
204#endif /* defined(__ARM_ARCH_6M__) */
205
206#endif /* defined(TRACE) */
207
208// ----------------------------------------------------------------------------
209
210#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
211
212#if defined(OS_USE_SEMIHOSTING_SYSCALLS) \
213 || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) \
214 || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
215
216int
217is_semihosting (exception_stack_frame_t* frame, uint16_t opCode);
218
226int
227is_semihosting (exception_stack_frame_t* frame, uint16_t opCode)
228{
229 uint16_t* pw = (uint16_t*)frame->pc;
230 if (*pw == opCode)
231 {
232 uint32_t r0 = frame->r0;
233#if defined(OS_DEBUG_SEMIHOSTING_FAULTS) \
234 || defined(OS_USE_SEMIHOSTING_SYSCALLS) \
235 || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
236 uint32_t r1 = frame->r1;
237#endif
238#if defined(OS_USE_SEMIHOSTING_SYSCALLS) \
239 || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
240 uint32_t* blk = (uint32_t*)r1;
241#endif
242
243#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
244 // trace_printf ("sh r0=%d\n", r0);
245#endif
246
247 switch (r0)
248 {
249
250#if defined(OS_USE_SEMIHOSTING_SYSCALLS)
251
263 // The call is not successful or not supported.
264 frame->r0 = (uint32_t)-1;
265 break;
266
268 // The call is successful.
269 frame->r0 = 0;
270 break;
271
273 // Should be the value of the C library errno variable.
274 frame->r0 = 0;
275 break;
276
278 blk[0] = 0; // heap_base
279 blk[1] = 0; // heap_limit
280 blk[2] = 0; // stack_base
281 blk[3] = 0; // stack_limit
282 break;
283
285 // 0 if the status word is not an error indication.
286 frame->r0 = 0;
287 break;
288
290 // If R0 contains the same value as word 3, the call has
291 // failed and EOF is assumed.
292 frame->r0 = blk[2];
293 break;
294
296 // The byte read from the console.
297 frame->r0 = '\0';
298 break;
299
301 // The number of seconds since 00:00 January 1, 1970.
302 frame->r0 = 0;
303 break;
304
306
307 NVIC_SystemReset ();
308 // Should not reach here
309 return 0;
310
311#endif /* defined(OS_USE_SEMIHOSTING_SYSCALLS) */
312
313#if defined(OS_USE_SEMIHOSTING_SYSCALLS) \
314 || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
315
316#define HANDLER_STDIN (1)
317#define HANDLER_STDOUT (2)
318#define HANDLER_STDERR (3)
319
321 // Process only standard io/out/err and return 1/2/3
322 if (strcmp ((char*)blk[0], ":tt") == 0)
323 {
324 if ((blk[1] == 0))
325 {
326 frame->r0 = HANDLER_STDIN;
327 break;
328 }
329 else if (blk[1] == 4)
330 {
331 frame->r0 = HANDLER_STDOUT;
332 break;
333 }
334 else if (blk[1] == 8)
335 {
336 frame->r0 = HANDLER_STDERR;
337 break;
338 }
339 }
340 // The call is not successful or not supported.
341 frame->r0 = (uint32_t)-1;
342 break;
343
345 // Silently ignore writes to stdout/stderr, fail on all other
346 // handler.
347 if ((blk[0] == HANDLER_STDOUT) || (blk[0] == HANDLER_STDERR))
348 {
349#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
350 frame->r0
351 = (uint32_t)blk[2] - trace_write ((char*)blk[1], blk[2]);
352#else
353 frame->r0 = 0; // all sent, no more.
354#endif /* defined(OS_DEBUG_SEMIHOSTING_FAULTS) */
355 }
356 else
357 {
358 // If other handler, return the total number of bytes
359 // as the number of bytes that are not written.
360 frame->r0 = blk[2];
361 }
362 break;
363
364#endif /* defined(OS_USE_SEMIHOSTING_SYSCALLS) || \
365 defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) */
366
367#if defined(OS_USE_SEMIHOSTING_SYSCALLS) \
368 || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) \
369 || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
370
372#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
373 {
374 char ch = *((char*)r1);
375 trace_write (&ch, 1);
376 }
377#endif
378 // Register R0 is corrupted.
379 break;
380
382#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
383 {
384 char* p = ((char*)r1);
385 trace_write (p, strlen (p));
386 }
387#endif
388 // Register R0 is corrupted.
389 break;
390
391#endif /* semihosting */
392
393 default:
394 return 0;
395 }
396
397 // Alter the PC to make the exception returns to
398 // the instruction after the faulty BKPT.
399 frame->pc += 2;
400 return 1;
401 }
402 return 0;
403}
404
405#endif
406
407// Hard Fault handler wrapper in assembly.
408// Extract the location of the stack frame and pass it to the C
409// handler as a pointer. Also pass the LR value as second
410// parameter.
411// (Based on Joseph Yiu's, The Definitive Guide to ARM Cortex-M3 and
412// Cortex-M4 Processors, Third Edition, Chap. 12.8, page 402).
413
414void __attribute__ ((section (".after_vectors"), weak, naked))
416{
417 __asm__ volatile (" tst lr,#4 \n"
418 " ite eq \n"
419 " mrseq r0,msp \n"
420 " mrsne r0,psp \n"
421 " mov r1,lr \n"
422 " ldr r2,=HardFault_Handler_C \n"
423 " bx r2"
424
425 : /* Outputs */
426 : /* Inputs */
427 : /* Clobbers */
428 );
429}
430
431void __attribute__ ((section (".after_vectors"), weak, used))
432HardFault_Handler_C (exception_stack_frame_t* frame __attribute__ ((unused)),
433 uint32_t lr __attribute__ ((unused)))
434{
435#if defined(TRACE)
436 uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
437 uint32_t bfar = SCB->BFAR; // Bus Fault Address
438 uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
439#endif /* defined(TRACE) */
440
441#if defined(OS_USE_SEMIHOSTING_SYSCALLS) \
442 || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) \
443 || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
444
445 // If the BKPT instruction is executed with C_DEBUGEN == 0 and MON_EN == 0,
446 // it will cause the processor to enter a HardFault exception, with DEBUGEVT
447 // in the Hard Fault Status register (HFSR) set to 1, and BKPT in the
448 // Debug Fault Status register (DFSR) also set to 1.
449
450 if (((SCB->DFSR & SCB_DFSR_BKPT_Msk) != 0)
451 && ((SCB->HFSR & SCB_HFSR_DEBUGEVT_Msk) != 0))
452 {
453 if (is_semihosting (frame, 0xBE00 + (AngelSWI & 0xFF)))
454 {
455 // Clear the exception cause in exception status.
456 SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk;
457
458 // Continue after the BKPT
459 return;
460 }
461 }
462
463#endif /* semihosting */
464
465#if defined(TRACE)
466 trace_printf ("[HardFault]\n");
467 dump_exception_stack (frame, cfsr, mmfar, bfar, lr);
468#endif /* defined(TRACE) */
469
470#if defined(DEBUG)
471#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
472 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
473 {
474 __BKPT (0);
475 }
476#else
477 __BKPT (0);
478#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
479#endif /* defined(DEBUG) */
480
481 while (true)
482 {
483 __NOP ();
484 }
485}
486
487#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
488
489#if defined(__ARM_ARCH_6M__)
490
491// Hard Fault handler wrapper in assembly.
492// It extracts the location of stack frame and passes it to handler
493// in C as a pointer. We also pass the LR value as second
494// parameter.
495// (Based on Joseph Yiu's, The Definitive Guide to ARM Cortex-M0
496// First Edition, Chap. 12.8, page 402).
497
498void __attribute__ ((section (".after_vectors"), weak, naked))
500{
501 __asm__ volatile (" movs r0,#4 \n"
502 " mov r1,lr \n"
503 " tst r0,r1 \n"
504 " beq 1f \n"
505 " mrs r0,psp \n"
506 " b 2f \n"
507 "1: \n"
508 " mrs r0,msp \n"
509 "2:"
510 " mov r1,lr \n"
511 " ldr r2,=HardFault_Handler_C \n"
512 " bx r2"
513
514 : /* Outputs */
515 : /* Inputs */
516 : /* Clobbers */
517 );
518}
519
520void __attribute__ ((section (".after_vectors"), weak, used))
521HardFault_Handler_C (exception_stack_frame_t* frame __attribute__ ((unused)),
522 uint32_t lr __attribute__ ((unused)))
523{
524 // There is no semihosting support for Cortex-M0, since on ARMv6-M
525 // faults are fatal and it is not possible to return from the handler.
526
527#if defined(TRACE)
528 trace_printf ("[HardFault]\n");
529 dump_exception_stack (frame, lr);
530#endif /* defined(TRACE) */
531
532#if defined(DEBUG)
533#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
534 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
535 {
536 __BKPT (0);
537 }
538#else
539 __BKPT (0);
540#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
541#endif /* defined(DEBUG) */
542
543 while (true)
544 {
545 __NOP ();
546 }
547}
548
549#endif /* defined(__ARM_ARCH_6M__) */
550
551#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
552
553void __attribute__ ((section (".after_vectors"), weak))
554MemManage_Handler (void)
555{
556#if defined(DEBUG)
557#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
558 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
559 {
560 __BKPT (0);
561 }
562#else
563 __BKPT (0);
564#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
565#endif /* defined(DEBUG) */
566
567 while (true)
568 {
569 __NOP ();
570 }
571}
572
573void __attribute__ ((section (".after_vectors"), weak, naked))
574BusFault_Handler (void)
575{
576 __asm__ volatile (" tst lr,#4 \n"
577 " ite eq \n"
578 " mrseq r0,msp \n"
579 " mrsne r0,psp \n"
580 " mov r1,lr \n"
581 " ldr r2,=BusFault_Handler_C \n"
582 " bx r2"
583
584 : /* Outputs */
585 : /* Inputs */
586 : /* Clobbers */
587 );
588}
589
590void __attribute__ ((section (".after_vectors"), weak, used))
591BusFault_Handler_C (exception_stack_frame_t* frame __attribute__ ((unused)),
592 uint32_t lr __attribute__ ((unused)))
593{
594#if defined(TRACE)
595 uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
596 uint32_t bfar = SCB->BFAR; // Bus Fault Address
597 uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
598
599 trace_printf ("[BusFault]\n");
600 dump_exception_stack (frame, cfsr, mmfar, bfar, lr);
601#endif /* defined(TRACE) */
602
603#if defined(DEBUG)
604#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
605 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
606 {
607 __BKPT (0);
608 }
609#else
610 __BKPT (0);
611#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
612#endif /* defined(DEBUG) */
613
614 while (true)
615 {
616 __NOP ();
617 }
618}
619
620void __attribute__ ((section (".after_vectors"), weak, naked))
621UsageFault_Handler (void)
622{
623 __asm__ volatile (" tst lr,#4 \n"
624 " ite eq \n"
625 " mrseq r0,msp \n"
626 " mrsne r0,psp \n"
627 " mov r1,lr \n"
628 " ldr r2,=UsageFault_Handler_C \n"
629 " bx r2"
630
631 : /* Outputs */
632 : /* Inputs */
633 : /* Clobbers */
634 );
635}
636
637void __attribute__ ((section (".after_vectors"), weak, used))
638UsageFault_Handler_C (exception_stack_frame_t* frame __attribute__ ((unused)),
639 uint32_t lr __attribute__ ((unused)))
640{
641#if defined(TRACE)
642 uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
643 uint32_t bfar = SCB->BFAR; // Bus Fault Address
644 uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
645#endif /* defined(TRACE) */
646
647#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
648
649 if ((cfsr & (1UL << 16)) != 0) // UNDEFINSTR
650 {
651 // For testing purposes, instead of BKPT use 'setend be'.
652 if (is_semihosting (frame, AngelSWITestFaultOpCode))
653 {
654 return;
655 }
656 }
657
658#endif /* defined(OS_DEBUG_SEMIHOSTING_FAULTS) */
659
660#if defined(TRACE)
661 trace_printf ("[UsageFault]\n");
662 dump_exception_stack (frame, cfsr, mmfar, bfar, lr);
663#endif /* defined(TRACE) */
664
665#if defined(DEBUG)
666#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
667 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
668 {
669 __BKPT (0);
670 }
671#else
672 __BKPT (0);
673#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
674#endif /* defined(DEBUG) */
675
676 while (true)
677 {
678 __NOP ();
679 }
680}
681
682#endif
683
684void __attribute__ ((section (".after_vectors"), weak))
686{
687#if defined(DEBUG)
688#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
689 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
690 {
691 __BKPT (0);
692 }
693#else
694 __BKPT (0);
695#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
696#endif /* defined(DEBUG) */
697
698 while (true)
699 {
700 __NOP ();
701 }
702}
703
704#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
705
706void __attribute__ ((section (".after_vectors"), weak))
707DebugMon_Handler (void)
708{
709#if defined(DEBUG)
710 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
711 {
712 __BKPT (0);
713 }
714#endif /* defined(DEBUG) */
715
716 while (true)
717 {
718 __NOP ();
719 }
720}
721
722#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
723
724void __attribute__ ((section (".after_vectors"), weak))
726{
727#if defined(DEBUG)
728#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
729 if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
730 {
731 __BKPT (0);
732 }
733#else
734 __BKPT (0);
735#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
736#endif /* defined(DEBUG) */
737
738 while (true)
739 {
740 __NOP ();
741 }
742}
743
744void __attribute__ ((section (".after_vectors"), weak))
746{
747 // DO NOT loop, just return.
748 // Useful in case someone (like STM HAL) always enables SysTick.
749}
750
751// ----------------------------------------------------------------------------
752
753#endif /* defined(__ARM_EABI__) */
unsigned int __stack
void SVC_Handler(void)
unsigned int _Heap_Limit
void PendSV_Handler(void)
void NMI_Handler(void)
void SysTick_Handler(void)
handler_ptr_t _interrupt_vectors[]
void(* handler_ptr_t)(void)
void Reset_Handler(void)
void HardFault_Handler(void)
void HardFault_Handler_C(exception_stack_frame_t *frame, uint32_t lr)
void _start(void)
The standard C application entry point.
Definition startup.cpp:241
@ SEMIHOSTING_SYS_TICKFREQ
Definition semihosting.h:52
@ SEMIHOSTING_ReportException
Definition semihosting.h:35
@ SEMIHOSTING_SYS_ISERROR
Definition semihosting.h:43
@ SEMIHOSTING_SYS_WRITE
Definition semihosting.h:55
@ SEMIHOSTING_SYS_FLEN
Definition semihosting.h:40
@ SEMIHOSTING_SYS_GET_CMDLINE
Definition semihosting.h:41
@ SEMIHOSTING_SYS_REMOVE
Definition semihosting.h:48
@ SEMIHOSTING_SYS_SEEK
Definition semihosting.h:50
@ SEMIHOSTING_SYS_TMPNAM
Definition semihosting.h:54
@ SEMIHOSTING_SYS_TIME
Definition semihosting.h:53
@ SEMIHOSTING_SYS_CLOCK
Definition semihosting.h:37
@ SEMIHOSTING_SYS_WRITEC
Definition semihosting.h:56
@ SEMIHOSTING_SYS_ERRNO
Definition semihosting.h:39
@ SEMIHOSTING_SYS_ISTTY
Definition semihosting.h:44
@ SEMIHOSTING_SYS_HEAPINFO
Definition semihosting.h:42
@ SEMIHOSTING_SYS_WRITE0
Definition semihosting.h:57
@ SEMIHOSTING_SYS_ELAPSED
Definition semihosting.h:38
@ SEMIHOSTING_SYS_READ
Definition semihosting.h:46
@ SEMIHOSTING_SYS_SYSTEM
Definition semihosting.h:51
@ SEMIHOSTING_SYS_CLOSE
Definition semihosting.h:36
@ SEMIHOSTING_SYS_READC
Definition semihosting.h:47
@ SEMIHOSTING_SYS_OPEN
Definition semihosting.h:45
@ SEMIHOSTING_SYS_RENAME
Definition semihosting.h:49
#define AngelSWI
Definition semihosting.h:72
int trace_printf(const char *format,...)
ssize_t trace_write(const void *buf, size_t nbyte)