1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | /*============================================================================= |
29 | VideoCore OS Abstraction Layer - logging support |
30 | =============================================================================*/ |
31 | |
32 | #ifndef VCOS_LOGGING_H |
33 | #define VCOS_LOGGING_H |
34 | |
35 | #ifdef __cplusplus |
36 | extern "C" { |
37 | #endif |
38 | |
39 | #include <stdarg.h> |
40 | |
41 | #include "interface/vcos/vcos_types.h" |
42 | #include "vcos.h" |
43 | #include "vcos_logging_control.h" |
44 | |
45 | /** |
46 | * \file |
47 | * |
48 | * Logging support |
49 | * |
50 | * This provides categorised logging. Clients register |
51 | * a category, and then get a number of logging levels for |
52 | * that category. |
53 | * |
54 | * The logging level flag is tested using a flag *before* the |
55 | * function call, which makes logging very fast when disabled - there |
56 | * is no function call overhead just to find out that this log |
57 | * message is disabled. |
58 | * |
59 | * \section VCOS_LOG_CATEGORY |
60 | * |
61 | * As a convenience, clients define VCOS_LOG_CATEGORY to point to |
62 | * their category; the various vcos_log_xxx() macros then expand to |
63 | * use this. |
64 | * |
65 | * e.g. |
66 | * |
67 | * #define VCOS_LOG_CATEGORY (&my_category) |
68 | * |
69 | * #include <interface/vcos/vcos.h> |
70 | * |
71 | * VCOS_LOG_CAT_T my_category; |
72 | * |
73 | * .... |
74 | * |
75 | * vcos_log_trace("Stuff happened: %d", n_stuff); |
76 | * |
77 | */ |
78 | |
79 | /** Logging levels */ |
80 | typedef enum VCOS_LOG_LEVEL_T |
81 | { |
82 | VCOS_LOG_UNINITIALIZED = 0, |
83 | VCOS_LOG_NEVER, |
84 | VCOS_LOG_ERROR, |
85 | VCOS_LOG_WARN, |
86 | VCOS_LOG_INFO, |
87 | VCOS_LOG_TRACE, |
88 | } VCOS_LOG_LEVEL_T; |
89 | |
90 | |
91 | /** Initialize a logging category without going through vcos_log_register(). |
92 | * |
93 | * This is useful for the case where there is no obvious point to do the |
94 | * registration (no initialization function for the module). However, it |
95 | * means that your logging category is not registered, so cannot be easily |
96 | * changed at run-time. |
97 | */ |
98 | #define VCOS_LOG_INIT(n,l) { l, n, 0, {0}, 0, 0 } |
99 | |
100 | /** A registered logging category. |
101 | */ |
102 | typedef struct VCOS_LOG_CAT_T |
103 | { |
104 | VCOS_LOG_LEVEL_T level; /**< Which levels are enabled for this category */ |
105 | const char *name; /**< Name for this category. */ |
106 | struct VCOS_LOG_CAT_T *next; |
107 | struct { |
108 | unsigned int want_prefix:1; |
109 | } flags; |
110 | unsigned int refcount; |
111 | void *platform_data; /**< platform specific data */ |
112 | } VCOS_LOG_CAT_T; |
113 | |
114 | typedef void (*VCOS_VLOG_IMPL_FUNC_T)(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args); |
115 | |
116 | /** Convert a VCOS_LOG_LEVEL_T into a printable string. |
117 | * The platform needs to implement this function. |
118 | */ |
119 | VCOSPRE_ const char * VCOSPOST_ vcos_log_level_to_string( VCOS_LOG_LEVEL_T level ); |
120 | |
121 | /** Convert a string into a VCOS_LOG_LEVEL_T |
122 | * The platform needs to implement this function. |
123 | */ |
124 | VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_string_to_log_level( const char *str, VCOS_LOG_LEVEL_T *level ); |
125 | |
126 | /** Log a message. Basic API. Normal code should not use this. |
127 | * The platform needs to implement this function. |
128 | */ |
129 | VCOSPRE_ void VCOSPOST_ vcos_log_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, ...) VCOS_FORMAT_ATTR_(printf, 3, 4); |
130 | |
131 | /** Log a message using a varargs parameter list. Normal code should |
132 | * not use this. |
133 | */ |
134 | VCOSPRE_ void VCOSPOST_ vcos_vlog_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0); |
135 | |
136 | /** Set the function which does the actual logging output. |
137 | * Passing in NULL causes the default logging function to be |
138 | * used. |
139 | */ |
140 | VCOSPRE_ void VCOSPOST_ vcos_set_vlog_impl( VCOS_VLOG_IMPL_FUNC_T vlog_impl_func ); |
141 | |
142 | /** The default logging function, which is provided by each |
143 | * platform. |
144 | */ |
145 | |
146 | VCOSPRE_ void VCOSPOST_ vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0); |
147 | |
148 | /* |
149 | * Initialise the logging subsystem. This is called from |
150 | * vcos_init() so you don't normally need to call it. |
151 | */ |
152 | VCOSPRE_ void VCOSPOST_ vcos_logging_init(void); |
153 | |
154 | /** Register a logging category. |
155 | * |
156 | * @param name the name of this category. |
157 | * @param category the category to register. |
158 | */ |
159 | VCOSPRE_ void VCOSPOST_ vcos_log_register(const char *name, VCOS_LOG_CAT_T *category); |
160 | |
161 | /** Unregister a logging category. |
162 | */ |
163 | VCOSPRE_ void VCOSPOST_ vcos_log_unregister(VCOS_LOG_CAT_T *category); |
164 | |
165 | /** Return a default logging category, for people too lazy to create their own. |
166 | * |
167 | * Using the default category will be slow (there's an extra function |
168 | * call overhead). Don't do this in normal code. |
169 | */ |
170 | VCOSPRE_ const VCOS_LOG_CAT_T * VCOSPOST_ vcos_log_get_default_category(void); |
171 | |
172 | VCOSPRE_ void VCOSPOST_ vcos_set_log_options(const char *opt); |
173 | |
174 | /** Set the logging level for a category at run time. Without this, the level |
175 | * will be that set by vcos_log_register from a platform-specific source. |
176 | * |
177 | * @param category the category to modify. |
178 | * @param level the new logging level for this category. |
179 | */ |
180 | VCOS_STATIC_INLINE void vcos_log_set_level(VCOS_LOG_CAT_T *category, VCOS_LOG_LEVEL_T level) |
181 | { |
182 | category->level = level; |
183 | } |
184 | |
185 | |
186 | /** Set the logging levels for many categories at once. |
187 | * |
188 | * Set lots of categorys from a string cat:lev,cat:lev This can |
189 | * be used at startup time to set a bunch of category levels from |
190 | * a single string. Used with C(vcos_logging_level) |
191 | */ |
192 | VCOSPRE_ void VCOSPOST_ vcos_log_set_level_all(char *levels); |
193 | |
194 | #define vcos_log_dump_mem(cat,label,addr,voidMem,numBytes) do { if (vcos_is_log_enabled(cat,VCOS_LOG_TRACE)) vcos_log_dump_mem_impl(cat,label,addr,voidMem,numBytes); } while (0) |
195 | |
196 | void vcos_log_dump_mem_impl( const VCOS_LOG_CAT_T *cat, |
197 | const char *label, |
198 | uint32_t addr, |
199 | const void *voidMem, |
200 | size_t numBytes ); |
201 | |
202 | /* |
203 | * Platform specific hooks (optional). |
204 | */ |
205 | #ifndef vcos_log_platform_init |
206 | #define vcos_log_platform_init() (void)0 |
207 | #endif |
208 | |
209 | #ifndef vcos_log_platform_register |
210 | #define vcos_log_platform_register(category) (void)0 |
211 | #endif |
212 | |
213 | #ifndef vcos_log_platform_unregister |
214 | #define vcos_log_platform_unregister(category) (void)0 |
215 | #endif |
216 | |
217 | /* VCOS_TRACE() - deprecated macro which just outputs in a debug build and |
218 | * is a no-op in a release build. |
219 | * |
220 | * _VCOS_LOG_X() - internal macro which outputs if the current level for the |
221 | * particular category is higher than the supplied message level. |
222 | */ |
223 | |
224 | #define VCOS_LOG_DFLT_CATEGORY vcos_log_get_default_category() |
225 | |
226 | #define _VCOS_LEVEL(x) (x) |
227 | |
228 | #define vcos_is_log_enabled(cat,_level) (_VCOS_LEVEL((cat)->level) >= _VCOS_LEVEL(_level)) |
229 | |
230 | #if defined(_VCOS_METAWARE) || defined(__GNUC__) |
231 | |
232 | # if !defined(AMPUTATE_ALL_VCOS_LOGGING) && (!defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING)) |
233 | # define VCOS_LOGGING_ENABLED |
234 | # define _VCOS_LOG_X(cat, _level, fmt...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat,_level,fmt); } while (0) |
235 | # define _VCOS_VLOG_X(cat, _level, fmt, ap) do { if (vcos_is_log_enabled(cat,_level)) vcos_vlog_impl(cat,_level,fmt,ap); } while (0) |
236 | # else |
237 | # define _VCOS_LOG_X(cat, _level, fmt...) (void)0 |
238 | # define _VCOS_VLOG_X(cat, _level, fmt, ap) (void)0 |
239 | # endif |
240 | |
241 | |
242 | |
243 | # define vcos_log_error(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__) |
244 | # define vcos_log_warn(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, __VA_ARGS__) |
245 | # define vcos_log_info(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__) |
246 | # define vcos_log_trace(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, __VA_ARGS__) |
247 | |
248 | # define vcos_vlog_error(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, ap) |
249 | # define vcos_vlog_warn(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, ap) |
250 | # define vcos_vlog_info(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, ap) |
251 | # define vcos_vlog_trace(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, ap) |
252 | |
253 | # define vcos_logc_error(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_ERROR, __VA_ARGS__) |
254 | # define vcos_logc_warn(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_WARN, __VA_ARGS__) |
255 | # define vcos_logc_info(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_INFO, __VA_ARGS__) |
256 | # define vcos_logc_trace(cat,...) _VCOS_LOG_X(cat, VCOS_LOG_TRACE, __VA_ARGS__) |
257 | |
258 | # define vcos_vlogc_error(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_ERROR, fmt, ap) |
259 | # define vcos_vlogc_warn(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_WARN, fmt, ap) |
260 | # define vcos_vlogc_info(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_INFO, fmt, ap) |
261 | # define vcos_vlogc_trace(cat,fmt,ap) _VCOS_VLOG_X(cat, VCOS_LOG_TRACE, fmt, ap) |
262 | |
263 | # define vcos_log(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__) |
264 | # define vcos_vlog(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, ap) |
265 | # define VCOS_ALERT(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__) |
266 | # define VCOS_TRACE(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__) |
267 | |
268 | /* |
269 | * MS Visual Studio - pre 2005 does not grok variadic macros |
270 | */ |
271 | #elif defined(_MSC_VER) |
272 | |
273 | # if _MSC_VER >= 1400 |
274 | |
275 | # if !defined(AMPUTATE_ALL_VCOS_LOGGING) && (!defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING)) |
276 | # define VCOS_LOGGING_ENABLED |
277 | # define _VCOS_LOG_X(cat, _level, fmt,...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat, _level, fmt, __VA_ARGS__); } while (0) |
278 | # else |
279 | # define _VCOS_LOG_X(cat, _level, fmt,...) (void)0 |
280 | # endif |
281 | |
282 | # define vcos_log_error(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, __VA_ARGS__) |
283 | # define vcos_log_warn(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, __VA_ARGS__) |
284 | # define vcos_log_info(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__) |
285 | # define vcos_log_trace(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, __VA_ARGS__) |
286 | |
287 | # define vcos_logc_error(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_ERROR, fmt, __VA_ARGS__) |
288 | # define vcos_logc_warn(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_WARN, fmt, __VA_ARGS__) |
289 | # define vcos_logc_info(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_INFO, fmt, __VA_ARGS__) |
290 | # define vcos_logc_trace(cat,fmt,...) _VCOS_LOG_X(cat, VCOS_LOG_TRACE, fmt, __VA_ARGS__) |
291 | |
292 | # define vcos_log(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__) |
293 | # define VCOS_ALERT(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, fmt, __VA_ARGS__) |
294 | # define VCOS_TRACE(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__) |
295 | |
296 | # else /* _MSC_VER >= 1400 */ |
297 | |
298 | /* do not define these */ |
299 | |
300 | # endif /* _MSC_VER >= 1400 */ |
301 | |
302 | #endif |
303 | |
304 | #if VCOS_HAVE_CMD |
305 | |
306 | #include "interface/vcos/vcos_cmd.h" |
307 | |
308 | /* |
309 | * These are the log sub-commands. They're exported here for user-mode apps which |
310 | * may want to call these, since the "log" command isn't registered for user-mode |
311 | * apps (vcdbg for example, has its own log command). |
312 | */ |
313 | VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_assert_cmd( VCOS_CMD_PARAM_T *param ); |
314 | VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_set_cmd( VCOS_CMD_PARAM_T *param ); |
315 | VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_status_cmd( VCOS_CMD_PARAM_T *param ); |
316 | VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_test_cmd( VCOS_CMD_PARAM_T *param ); |
317 | #endif |
318 | |
319 | #ifdef __cplusplus |
320 | } |
321 | #endif |
322 | #endif /* VCOS_LOGGING_H */ |
323 | |
324 | |
325 | |