µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
trace.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) 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(TRACE)
13
14#if defined(OS_USE_OS_APP_CONFIG_H)
15#include <cmsis-plus/os-app-config.h>
16#endif
17
19
20#include <cstdarg>
21#include <cstdio>
22#include <cstring>
23
24#ifndef OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE
25#define OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE (200)
26#endif
27
28// ----------------------------------------------------------------------------
29
30namespace os
31{
32 namespace trace
33 {
34 // ------------------------------------------------------------------------
35
36 void __attribute__ ((weak))
38 {
39 }
40
45 ssize_t __attribute__ ((weak))
46 write (const void* buf __attribute__ ((unused)), std::size_t nbyte)
47 {
48 return static_cast<ssize_t> (nbyte);
49 }
50
51 void __attribute__ ((weak))
52 flush (void)
53 {
54 }
55
56 // ------------------------------------------------------------------------
57
58 int __attribute__ ((weak))
59 printf (const char* format, ...)
60 {
61 std::va_list args;
62 va_start (args, format);
63
64 int ret = vprintf (format, args);
65
66 va_end (args);
67 return ret;
68 }
69
70#if defined(__clang__)
71#elif defined(__GNUC__)
72#pragma GCC diagnostic ignored "-Wuseless-cast"
73#endif
74
75 int __attribute__ ((weak))
76 vprintf (const char* format, std::va_list args)
77 {
78 // Caution: allocated on the stack!
80
81 // TODO: possibly rewrite it to no longer use newlib,
82 // (although the nano version is no longer very heavy).
83
84 // Print to the local buffer
85#pragma GCC diagnostic push
86#if defined(__clang__)
87#pragma clang diagnostic ignored "-Wformat-nonliteral"
88#elif defined(__GNUC__)
89#pragma GCC diagnostic ignored "-Wformat-nonliteral"
90#endif
91 int ret = ::vsnprintf (buf, sizeof (buf), format, args);
92#pragma GCC diagnostic pop
93 if (ret > 0)
94 {
95 // Transfer the buffer to the device.
96 ret = static_cast<int> (write (buf, static_cast<size_t> (ret)));
97 }
98 return ret;
99 }
100
101 int __attribute__ ((weak))
102 puts (const char* s)
103 {
104 int ret = static_cast<int> (write (s, strlen (s)));
105 if (ret >= 0)
106 {
107 ret = static_cast<int> (write ("\n", 1)); // Add a line terminator
108 }
109 if (ret > 0)
110 {
111 return ret;
112 }
113 else
114 {
115 return EOF;
116 }
117 }
118
119 int __attribute__ ((weak))
120 putchar (int c)
121 {
122 int ret
123 = static_cast<int> (write (reinterpret_cast<const char*> (&c), 1));
124 if (ret > 0)
125 {
126 return c;
127 }
128 else
129 {
130 return EOF;
131 }
132 }
133
134#pragma GCC diagnostic push
135#if defined(__clang__)
136#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
137#endif
138 void __attribute__ ((weak))
139 dump_args (int argc, char* argv[])
140 {
141 printf ("main(argc=%d, argv=[", argc);
142 for (int i = 0; i < argc; ++i)
143 {
144 if (i != 0)
145 {
146 printf (", ");
147 }
148 printf ("\"%s\"", argv[i]);
149 }
150 printf ("]);\n");
151 }
152#pragma GCC diagnostic pop
153
154 } /* namespace trace */
155} /* namespace os */
156
157// ----------------------------------------------------------------------------
158
159using namespace os;
160
161// These cannot be aliased, since they might be defined
162// in a different translation units (and usually they are).
163
164void __attribute__ ((weak))
166{
168}
169
170ssize_t __attribute__ ((weak))
171trace_write (const void* buf, std::size_t nbyte)
172{
173 return trace::write (buf, nbyte);
174}
175
176void __attribute__ ((weak))
178{
179 return trace::flush ();
180}
181
182// ----------------------------------------------------------------------------
183
184#if defined(__ARM_EABI__)
185
186// For embedded platforms, optimise with aliases.
187//
188// Aliases can only refer symbols defined in the same translation unit
189// and C++ de-mangling must be done manually.
190
191int __attribute__ ((weak, alias ("_ZN2os5trace6printfEPKcz")))
192trace_printf (const char* format, ...);
193
194int __attribute__ ((weak, alias ("_ZN2os5trace7vprintfEPKcSt9__va_list")))
195trace_vprintf (const char* format, va_list args);
196
197int __attribute__ ((weak, alias ("_ZN2os5trace4putsEPKc")))
198trace_puts (const char* s);
199
200int __attribute__ ((weak, alias ("_ZN2os5trace7putcharEi")))
202
203void __attribute__ ((weak, alias ("_ZN2os5trace9dump_argsEiPPc")))
204trace_dump_args (int argc, char* argv[]);
205
206#else
207
208// For non-embedded platforms, to remain compatible with OS X which does
209// not support aliases, redefine the C functions to call the C++ versions.
210
211int
212trace_printf (const char* format, ...)
213{
214 std::va_list args;
215 va_start (args, format);
216
217 int ret = trace::vprintf (format, args);
218
219 va_end (args);
220 return ret;
221}
222
223int
224trace_vprintf (const char* format, va_list args)
225{
226 return trace::vprintf (format, args);
227}
228
229int
230trace_puts (const char* s)
231{
232 return trace::puts (s);
233}
234
235int
236trace_putchar (int c)
237{
238 return trace::putchar (c);
239}
240
241void
242trace_dump_args (int argc, char* argv[])
243{
244 trace::dump_args (argc, argv);
245}
246
247#endif
248
249// ----------------------------------------------------------------------------
250
251#endif // defined(TRACE)
int puts(const char *s)
Write the string and a line terminator to the trace device.
Definition trace.cpp:102
int vprintf(const char *format, std::va_list args)
Write a formatted variable arguments list to the trace device.
Definition trace.cpp:76
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
int putchar(int c)
Write the single character to the trace device.
Definition trace.cpp:120
void dump_args(int argc, char *argv[])
Write the argv[] array to the trace device.
Definition trace.cpp:139
void initialize(void)
Definition trace.cpp:37
ssize_t write(const void *buf, std::size_t nbyte)
Write the given number of bytes to the trace output channel.
Definition trace.cpp:46
void flush(void)
Flush the output.
Definition trace.cpp:52
System namespace.
Standard std namespace.
int trace_putchar(int c)
void trace_flush(void)
Definition trace.cpp:177
#define OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE
Definition trace.cpp:25
int trace_vprintf(const char *format, va_list args)
void trace_initialize(void)
Definition trace.cpp:165
void trace_dump_args(int argc, char *argv[])
ssize_t trace_write(const void *buf, std::size_t nbyte)
Definition trace.cpp:171
int trace_printf(const char *format,...)
int trace_puts(const char *s)