µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os-main.cpp
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) 2016-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(OS_USE_OS_APP_CONFIG_H)
14#include <cmsis-plus/os-app-config.h>
15#endif
16
17#include <cmsis-plus/rtos/os.h>
19
20// ----------------------------------------------------------------------------
21
22#if defined(__clang__)
23#pragma clang diagnostic ignored "-Wc++98-compat"
24#endif
25
26// ----------------------------------------------------------------------------
27
28using namespace os;
29
30// ----------------------------------------------------------------------------
31
36extern "C" void
37os_goodbye (void);
38
39namespace
40{
41 // --------------------------------------------------------------------------
42
43 // Since the native threads have a single argument, and it is better to
44 // avoid C++11 tuples and function objects, there is no other simple
45 // way than to pack the args in a structure and use it by the
46 // trampoline to invoke the os_main().
47
48#pragma GCC diagnostic push
49#if defined(__clang__)
50#pragma clang diagnostic ignored "-Wpadded"
51#elif defined(__GNUC__)
52#pragma GCC diagnostic ignored "-Wpadded"
53#endif
54
55 using main_args_t = struct
56 {
57 int argc;
58 char** argv;
59 };
60
61#pragma GCC diagnostic pop
62
63 static main_args_t main_args;
64
65 // --------------------------------------------------------------------------
66
67 [[noreturn]] static void
68 _main_trampoline (void)
69 {
70 trace::puts ("");
71 trace::dump_args (main_args.argc, main_args.argv);
72
73 int code = os_main (main_args.argc, main_args.argv);
74 trace::printf ("%s() exit = %d\n", __func__, code);
75
76 // Exit will run the atexit() and destructors, then
77 // terminate gracefully.
78 std::exit (code);
79 }
80
81// --------------------------------------------------------------------------
82
83} /* namespace */
84
89// ----------------------------------------------------------------------------
91
92// Intentionally a raw pointer, to prevent destruction.
94
95#if defined(OS_EXCLUDE_DYNAMIC_MEMORY_ALLOCATIONS)
96
97// Necessarily static, on Cortex-M the reset stack will be used
98// as MSP for the interrupts, so the current stack must be freed
99// and os_main() shall run on its own stack.
101static std::aligned_storage<sizeof(main_thread), alignof(main_thread)>::type os_main_thread_;
102
103#endif /* defined(OS_EXCLUDE_DYNAMIC_MEMORY_ALLOCATIONS) */
104
108int
109#if !defined(__APPLE__)
110__attribute__((weak))
111#endif
112main (int argc, char* argv[])
113{
114 using namespace os::rtos;
115
116 trace::printf ("\nµOS++ IIIe version " OS_STRING_RTOS_IMPL_VERSION "\n");
117 trace::printf ("Copyright (c) 2007-" OS_STRING_RTOS_IMPL_YEAR " Liviu Ionescu\n");
118
119 port::scheduler::greeting ();
120
121 trace::printf ("Scheduler frequency: %u ticks/sec\n",
123 trace::printf ("Default stack size: %u bytes\n",
124 thread::stack::default_size ());
125#if defined(OS_HAS_INTERRUPTS_STACK)
126 trace::printf ("Interrupts stack size: %u bytes\n",
127 interrupts::stack ()->size ());
128#endif /* defined(OS_HAS_INTERRUPTS_STACK) */
129
130#if defined(__clang__)
131 trace::printf ("Built with clang " __VERSION__);
132#else
133 trace::printf ("Built with GCC " __VERSION__);
134#endif
135
136#if defined(__EXCEPTIONS)
137 trace::printf (", with exceptions");
138#else
139 trace::printf (", no exceptions");
140#endif
141 trace::puts ("\n");
142
143 scheduler::initialize ();
144
145 // Store the parameters in the static structure, to be used by os_main().
146 main_args.argc = argc;
147 main_args.argv = argv;
148
149#if defined(OS_EXCLUDE_DYNAMIC_MEMORY_ALLOCATIONS)
150
151 // Running the constructor manually has the additional advantage of
152 // not registering any destructor, and for main this is important,
153 // since the destructors are executed on its context, and it cannot
154 // destruct itself.
155 new (&os_main_thread_) main_thread
156 {"main", reinterpret_cast<thread::func_t> (_main_trampoline), nullptr};
157
158 os_main_thread = reinterpret_cast<rtos::thread*>(&os_main_thread_);
159
160#else
161
162 thread::attributes attr = thread::initializer;
164 os_main_thread = new thread (
165 "main", reinterpret_cast<thread::func_t> (_main_trampoline), nullptr,
166 attr);
167
168#endif /* defined(OS_EXCLUDE_DYNAMIC_MEMORY_ALLOCATIONS) */
169
170#if !defined(OS_USE_RTOS_PORT_SCHEDULER)
172#endif /* !defined(OS_USE_RTOS_PORT_SCHEDULER) */
173
174 // Execution will proceed to first registered thread, possibly
175 // "idle", which will immediately lower its priority,
176 // and at a certain moment will reach os_main().
177 scheduler::start ();
178
179 /* NOTREACHED */
180}
181
182void
183#if !defined(__APPLE__)
184__attribute__((weak))
185#endif
187{
188#if defined(TRACE)
189
190 trace::printf ("\n");
191
192#if !defined(OS_EXCLUDE_DYNAMIC_MEMORY_ALLOCATIONS)
193
194 // Application memory.
196
197#if defined(OS_INTEGER_RTOS_DYNAMIC_MEMORY_SIZE_BYTES)
199#endif /* defined(OS_INTEGER_RTOS_DYNAMIC_MEMORY_SIZE_BYTES) */
200
201#endif /* !defined(OS_EXCLUDE_DYNAMIC_MEMORY_ALLOCATIONS) */
202
204
205 trace::printf ("Main thread stack: %u/%u bytes used\n",
206 st.size () - st.available (), st.size ());
207
208#if defined(OS_HAS_INTERRUPTS_STACK)
210 "Interrupts stack: %u/%u bytes used\n",
214#endif /* defined(OS_HAS_INTERRUPTS_STACK) */
215
216 trace::printf ("\nHasta la Vista!\n");
217
218#endif /* defined(TRACE) */
219}
220
221// ----------------------------------------------------------------------------
static constexpr uint32_t frequency_hz
SysTick frequency in Hz.
Definition os-clocks.h:472
void trace_print_statistics(void)
Print a long message with usage statistics.
Definition os-memory.h:1443
Thread attributes.
Definition os-thread.h:798
std::size_t th_stack_size_bytes
Size of the user defined storage for the thread stack, in bytes.
Definition os-thread.h:858
std::size_t size(void)
Get the stack size.
Definition os-thread.h:2169
std::size_t available(void)
Compute how much available stack remains.
Template of a POSIX compliant thread with local stack.
Definition os-thread.h:1824
POSIX compliant thread, using the default RTOS allocator.
Definition os-thread.h:250
void *(*)(func_args_t args) func_t
Type of thread function.
Definition os-thread.h:420
thread::stack & stack(void)
Get the thread context stack.
Definition os-thread.h:2445
Standard thread.
void os_goodbye(void)
#define OS_INTEGER_RTOS_MAIN_STACK_SIZE_BYTES
Define the main thread stack size, in bytes.
void os_startup_create_thread_idle(void)
Create the idle thread.
void os_terminate_goodbye(void)
Display statistics and say goodbye before terminating.
Definition os-main.cpp:186
int puts(const char *s)
Write the string and a line terminator to the trace device.
Definition trace.cpp:103
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
void dump_args(int argc, char *argv[])
Write the argv[] array to the trace device.
Definition trace.cpp:135
int os_main(int argc, char *argv[])
Application entry point, running on the main thread context.
class thread::stack * stack(void)
Get the interrupts stack.
Definition os-core.cpp:571
memory_resource * get_default_resource(void) noexcept
Get the default RTOS system memory manager.
Definition os-memory.h:1133
memory_resource * get_default_resource(void) noexcept
Get the default application memory manager.
RTOS namespace.
Definition os-flags.h:38
System namespace.
int main(int argc, char *argv[])
Default implementation of main().
Definition os-main.cpp:112
rtos::thread * os_main_thread
Definition os-main.cpp:93
#define OS_STRING_RTOS_IMPL_YEAR
Definition os-versions.h:43
#define OS_STRING_RTOS_IMPL_VERSION
Definition os-versions.h:45
Single file µOS++ RTOS definitions.