COSA
An Object-Oriented Platform for Arduino Programming
Trace.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_TRACE_HH
22 #define COSA_TRACE_HH
23 
24 #include "Cosa/Types.h"
25 #include "Cosa/IOStream.hh"
26 
31 class Trace : public IOStream {
32 public:
38  Trace() : IOStream(), EXITCHARACTER(0x1d) {}
39 
46  bool begin(IOStream::Device* dev, str_P banner = NULL);
47 
52  bool end()
53  __attribute__((always_inline))
54  {
55  device(NULL);
56  return (true);
57  }
58 
63  void exitcharacter(char c)
64  {
65  EXITCHARACTER = c;
66  }
67 
76  void fatal(const char* file, int line, str_P expr)
77  __attribute__((noreturn));
78 
80  uint32_t measure;
81 
82 protected:
85 };
86 
90 #define LOG_EMERG 0 /* System is unusable */
91 #define LOG_ALERT 1 /* Action must be taken immediately */
92 #define LOG_CRIT 2 /* Critical conditions */
93 #define LOG_ERR 3 /* Error conditions */
94 #define LOG_WARNING 4 /* Warning conditions */
95 #define LOG_NOTICE 5 /* Normal but significant condition */
96 #define LOG_INFO 6 /* Informational */
97 #define LOG_DEBUG 7 /* Debug-level messages */
98 
105 #define LOG_MASK(prio) (1 << (prio))
106 #define LOG_UPTO(prio) (LOG_MASK((prio) + 1) - 1)
107 extern uint8_t trace_log_mask;
108 
115 #define FATAL(msg) \
116  trace.fatal(__FILE__, \
117  __LINE__, \
118  __PSTR(msg))
119 #ifndef NDEBUG
120 
127 # define ASSERT(expr) \
128  do { \
129  if (UNLIKELY(!(expr))) FATAL("assert:" #expr); \
130  } while (0)
131 
136 # define TRACE_P(str) trace.print(PSTR(str))
137 
143 # if defined(TRACE_NO_VERBOSE) || defined(BOARD_ATTINY)
144 # define TRACE(expr) \
145  do { \
146  trace.print(__PSTR(#expr " = ")); \
147  trace.print(expr); \
148  trace.println(); \
149  } while (0)
150 # else
151 # define TRACE(expr) \
152  do { \
153  trace.printf(__PSTR("%d:%s:trace:" #expr " = "), \
154  __LINE__, \
155  __PRETTY_FUNCTION__); \
156  trace.print(expr); \
157  trace.println(); \
158  } while (0)
159 # endif
160 
166 # define TRACE_LOG(msg, ...) \
167  trace.printf(__PSTR("%d:%s:" msg "\r\n"), \
168  __LINE__, \
169  __PRETTY_FUNCTION__, \
170  __VA_ARGS__)
171 # define IS_LOG_PRIO(prio) (trace_log_mask & LOG_MASK(prio))
172 # define EMERG(msg, ...) \
173  if (IS_LOG_PRIO(LOG_EMERG)) TRACE_LOG("emerg:" msg, __VA_ARGS__)
174 # define ALERT(msg, ...) \
175  if (IS_LOG_PRIO(LOG_ALERT)) TRACE_LOG("alert:" msg, __VA_ARGS__)
176 # define CRIT(msg, ...) \
177  if (IS_LOG_PRIO(LOG_CRIT)) TRACE_LOG("crit:" msg, __VA_ARGS__)
178 # define ERR(msg, ...) \
179  if (IS_LOG_PRIO(LOG_ERR)) TRACE_LOG("err:" msg, __VA_ARGS__)
180 # define WARNING(msg, ...) \
181  if (IS_LOG_PRIO(LOG_WARNING)) TRACE_LOG("warning:" msg, __VA_ARGS__)
182 # define NOTICE(msg, ...) \
183  if (IS_LOG_PRIO(LOG_NOTICE)) TRACE_LOG("notice:" msg, __VA_ARGS__)
184 # define INFO(msg, ...) \
185  if (IS_LOG_PRIO(LOG_INFO)) TRACE_LOG("info:" msg, __VA_ARGS__)
186 # define DEBUG(msg, ...) \
187  if (IS_LOG_PRIO(LOG_DEBUG)) TRACE_LOG("debug:" msg, __VA_ARGS__)
188 #else
189 # define ASSERT(expr)
190 # define TRACE_P(str)
191 # define TRACE(expr)
192 # define TRACE_LOG(msg, ...)
193 # define EMERG(msg, ...)
194 # define ALERT(msg, ...)
195 # define CRIT(msg, ...)
196 # define ERR(msg, ...)
197 # define WARNING(msg, ...)
198 # define NOTICE(msg, ...)
199 # define INFO(msg, ...)
200 # define DEBUG(msg, ...)
201 #endif
202 
217 # if defined(TRACE_NO_VERBOSE) || defined(BOARD_ATTINY)
218 # define MEASURE(msg,cnt) \
219  trace.flush(); \
220  for (uint32_t __stop, __start = RTT::micros(), __i = 1; \
221  __i != 0; \
222  __i--, \
223  __stop = RTT::micros(), \
224  trace.measure = (__stop - __start) / cnt, \
225  trace << PSTR(msg) << trace.measure, \
226  trace << PSTR(" us") << endl, \
227  trace.flush()) \
228  for (uint16_t __j = cnt; __j != 0; __j--)
229 # define measure(msg,cnt) \
230  trace.flush(); \
231  for (uint32_t __stop, __start = RTT::millis(), __i = 1; \
232  __i != 0; \
233  __i--, \
234  __stop = RTT::millis(), \
235  trace.measure = (__stop - __start) / cnt, \
236  trace << PSTR(msg) << trace.measure, \
237  trace << PSTR(" ms") << endl, \
238  trace.flush()) \
239  for (uint16_t __j = cnt; __j != 0; __j--)
240 #else
241 # define MEASURE(msg,cnt) \
242  trace.flush(); \
243  for (uint32_t __stop, __start = RTT::micros(), __i = 1; \
244  __i != 0; \
245  __i--, \
246  __stop = RTT::micros(), \
247  trace.measure = (__stop - __start) / cnt, \
248  trace << __LINE__ << ':' << __PRETTY_FUNCTION__, \
249  trace << PSTR(":measure:") << PSTR(msg) << trace.measure, \
250  trace << PSTR(" us") << endl, \
251  trace.flush()) \
252  for (uint16_t __j = cnt; __j != 0; __j--)
253 # define measure(msg,cnt) \
254  trace.flush(); \
255  for (uint32_t __stop, __start = RTT::millis(), __i = 1; \
256  __i != 0; \
257  __i--, \
258  __stop = RTT::millis(), \
259  trace.measure = (__stop - __start) / cnt, \
260  trace << __LINE__ << ':' << __PRETTY_FUNCTION__, \
261  trace << PSTR(":measure:") << PSTR(msg) << trace.measure, \
262  trace << PSTR(" ms") << endl, \
263  trace.flush()) \
264  for (uint16_t __j = cnt; __j != 0; __j--)
265 #endif
266 
270 extern Trace trace;
271 
272 #endif
uint8_t trace_log_mask
Definition: Trace.cpp:25
void fatal(const char *file, int line, str_P expr)
Definition: Trace.cpp:39
Trace()
Definition: Trace.hh:38
Trace trace
Definition: Trace.cpp:23
#define NULL
Definition: Types.h:101
bool end()
Definition: Trace.hh:52
uint32_t measure
Definition: Trace.hh:80
const class prog_str * str_P
Definition: Types.h:187
Definition: Trace.hh:31
char EXITCHARACTER
Definition: Trace.hh:84
Device * device() const
Definition: IOStream.hh:265
bool begin(IOStream::Device *dev, str_P banner=NULL)
Definition: Trace.cpp:28
void exitcharacter(char c)
Definition: Trace.hh:63