µ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 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(TRACE)
29
30#include <cmsis-plus/os-app-config.h>
32
33#include <cstdarg>
34#include <cstdio>
35#include <cstring>
36
37#ifndef OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE
38#define OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE (200)
39#endif
40
41// ----------------------------------------------------------------------------
42
43namespace os
44{
45 namespace trace
46 {
47 // ----------------------------------------------------------------------
48
49 void __attribute__((weak))
51 {
52 ;
53 }
54
59 ssize_t __attribute__((weak))
60 write (const void* buf __attribute__((unused)), std::size_t nbyte)
61 {
62 return static_cast<ssize_t> (nbyte);
63 }
64
65 void __attribute__((weak))
66 flush (void)
67 {
68 ;
69 }
70
71 // ----------------------------------------------------------------------
72
73 int __attribute__((weak))
74 printf (const char* format, ...)
75 {
76 std::va_list args;
77 va_start(args, format);
78
79 int ret = vprintf (format, args);
80
81 va_end(args);
82 return ret;
83 }
84
85 int __attribute__((weak))
86 vprintf (const char* format, std::va_list args)
87 {
88 // Caution: allocated on the stack!
90
91 // TODO: possibly rewrite it to no longer use newlib,
92 // (although the nano version is no longer very heavy).
93
94 // Print to the local buffer
95#pragma GCC diagnostic push
96#pragma GCC diagnostic ignored "-Wformat-nonliteral"
97 int ret = ::vsnprintf (buf, sizeof(buf), format, args);
98#pragma GCC diagnostic pop
99 if (ret > 0)
100 {
101 // Transfer the buffer to the device.
102 ret = static_cast<int> (write (buf, static_cast<size_t> (ret)));
103 }
104 return ret;
105 }
106
107 int __attribute__((weak))
108 puts (const char* s)
109 {
110 int ret = static_cast<int> (write (s, strlen (s)));
111 if (ret >= 0)
112 {
113 ret = static_cast<int> (write ("\n", 1)); // Add a line terminator
114 }
115 if (ret > 0)
116 {
117 return ret;
118 }
119 else
120 {
121 return EOF;
122 }
123 }
124
125 int __attribute__((weak))
126 putchar (int c)
127 {
128 int ret = static_cast<int> (write (reinterpret_cast<const char*> (&c), 1));
129 if (ret > 0)
130 {
131 return c;
132 }
133 else
134 {
135 return EOF;
136 }
137 }
138
139 void __attribute__((weak))
140 dump_args (int argc, char* argv[])
141 {
142 printf ("main(argc=%d, argv=[", argc);
143 for (int i = 0; i < argc; ++i)
144 {
145 if (i != 0)
146 {
147 printf (", ");
148 }
149 printf ("\"%s\"", argv[i]);
150 }
151 printf ("]);\n");
152 }
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:108
int vprintf(const char *format, std::va_list args)
Write a formatted variable arguments list to the trace device.
Definition trace.cpp:86
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
int putchar(int c)
Write the single character to the trace device.
Definition trace.cpp:126
void dump_args(int argc, char *argv[])
Write the argv[] array to the trace device.
Definition trace.cpp:140
void initialize(void)
Definition trace.cpp:50
ssize_t write(const void *buf, std::size_t nbyte)
Write the given number of bytes to the trace output channel.
Definition trace.cpp:60
void flush(void)
Flush the output.
Definition trace.cpp:66
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:38
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)