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