µOS++ IIIe / CMSIS++ / POSIX++ Reference  v6.3.11
“Perfekt ist nicht gut genug”
The third edition of µOS++ and CMSIS++, a proposal for the next generation CMSIS, written in C++.
exit.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 Liviu Ionescu.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom
12  * the Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #if defined(__ARM_EABI__)
29 
30 // ----------------------------------------------------------------------------
31 
33 #include <cmsis-plus/diag/trace.h>
34 #include <cmsis_device.h>
35 
36 #include <stdlib.h>
37 #include <stdbool.h>
38 #include "atexit.h"
39 
40 // ----------------------------------------------------------------------------
41 
42 void
43 __attribute__ ((noreturn))
44 os_exit (int code);
45 
46 extern void
47 os_goodbye (void);
48 
49 // ----------------------------------------------------------------------------
50 
51 void __attribute__((weak,noreturn))
52 abort (void)
53 {
54  trace_puts ("abort(), exiting...");
55 
56  _Exit (1);
57  /* NOTREACHED */
58 }
59 
60 // ----------------------------------------------------------------------------
61 
76 void
77 __attribute__ ((noreturn))
78 exit (int code)
79 {
80  trace_printf ("%s(%d)\n", __func__, code);
81 
82  // Call the cleanup functions enrolled with atexit().
83  __call_exitprocs (code, NULL);
84 
85  // Run the C++ static destructors.
87 
88  // This should normally be the end of it.
89  _Exit (code);
90 
91  // Reset again, in case _Exit() did not kill it.
92  // This normally should not happen, but since it can be
93  // overloaded by the application, better safe than sorry.
94  os_terminate (code);
95 
96  // If it does not want o die, loop.
97  while (true)
98  {
99  __NOP ();
100  }
101  /* NOTREACHED */
102 }
103 
104 // ----------------------------------------------------------------------------
105 
106 #pragma GCC diagnostic push
107 #pragma GCC diagnostic ignored "-Wunused-parameter"
108 
109 // On Release, call the hardware reset procedure.
110 // On Debug, use a breakpoint to notify the debugger.
111 //
112 // It can be redefined by the application, if more functionality
113 // is required. For example, when semihosting is used, this
114 // function sends the return code to the host.
115 
116 void __attribute__((weak, noreturn))
117 _Exit (int code)
118 {
119  trace_printf ("%s()\n", __func__);
120 
121  // Print some statistics about memory use.
123 
124  // Gracefully terminate the trace session.
125  trace_flush ();
126 
127 #if defined(DEBUG)
128 
129 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
130  if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
131  {
132  // Break only if the debugger is connected.
133  __BKPT(0);
134  }
135 #endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
136 
137 #endif /* defined(DEBUG) */
138 
139  // Reset hardware or terminate the semihosting session.
140  os_terminate (code);
141 
142  while (true)
143  {
144  __NOP ();
145  }
146  /* NOTREACHED */
147 }
148 
149 #pragma GCC diagnostic pop
150 
151 void __attribute__((weak, alias ("_Exit")))
152 _exit (int status);
153 
154 // ----------------------------------------------------------------------------
155 
156 // Semihosting defines this function to terminate the semihosting session.
157 #if !defined(OS_USE_SEMIHOSTING_SYSCALLS)
158 
164 void
165 __attribute__ ((noreturn,weak))
166 os_terminate(int code __attribute__((unused)))
167  {
168  NVIC_SystemReset ();
169  while(1)
170  ;
171  /* NOTREACHED */
172  }
173 
174 #endif
175 
176 // ----------------------------------------------------------------------------
177 
178 #endif /* defined(__ARM_EABI__) */
void exit(int code)
Definition: exit.c:78
void trace_flush(void)
Definition: trace.cpp:177
void os_exit(int code)
void os_run_fini_array(void)
Definition: startup.cpp:205
void os_goodbye(void)
void _exit(int status)
void _Exit(int code)
Definition: exit.c:117
void os_terminate_goodbye(void)
Display statistics and say goodbye before terminating.
Definition: os-main.cpp:187
void os_terminate(int code)
Terminate the application. There is no more life after this.
Definition: exit.c:166
int trace_printf(const char *format,...)
int trace_puts(const char *s)
void __call_exitprocs(int code, void *d)
Definition: atexit.cpp:140
void NVIC_SystemReset(void)
void abort(void)
Definition: exit.c:52