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