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