1 /*
2  * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *    1. Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *    2. 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
12  *       distribution.
13  *    3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
14  *       its contributors may be used to endorse or promote products derived
15  *       from this software without specific prior written permission.
16  *
17  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef __R_DEBUG_H__
31 #define __R_DEBUG_H__
32 
33 #include <errno.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdbool.h>
38 
39 #define R_DEBUG_ON
40 
41 
42 /*
43  * @brief Debug level
44  */
45 #define DBG_LEVEL_MASK (0x0F)
46 
47 
48 #define R_LEVEL_EMERG 0
49 
50 #define R_LEVEL_ALERT 1
51 
52 #define R_LEVEL_CRIT 2
53 
54 #define R_LEVEL_ERROR 3
55 
56 #define R_LEVEL_WARNING 4
57 
58 #define R_LEVEL_NOTICE 5
59 
60 #define R_LEVEL_INFO 6
61 
62 #define R_LEVEL_DEBUG 7
63 
64 #define R_LEVEL_ALL 0x0F
65 
66 
67 /*
68  * No expanded condition
69  */
70 #define NOEXPAND 1
71 
72 
73 /*
74  * module ON/OFF
75  */
76 #define DBG_ON (1 << 4)
77 
78 #define DBG_OFF (0)
79 
80 
81 /*
82  * Always show message
83  */
84 #define MOD_DBG_ALW_ON (DBG_ON | R_LEVEL_ALL)
85 
86 
87 /************************************************************
88  * R_DEBUG INTERFACE
89  ************************************************************/
90 #ifdef R_DEBUG_ON
91 
92 #define R_DEBUG_PRINT(msg, arg...) printf(msg, ##arg)
93 
94 #define R_DEBUG_ABORT() \
95     do { \
96         printf("system aborted!"); \
97         sys_abort(); \
98     } while (0)
99 
100 
101 /*
102  * @brief   The realization of showing debug messages.
103  * @param   module: Contained a module On/Off and a module debug level.
104  * @param   dlevel: Debug message showed level for seal like MDEBUG.
105  * @param   expand: Expanded condition if level param and module ON/OFF are not
106  *                  enough for developer.
107  * @param   msg: The debug message.
108  * @param   arg: Arguement shown in debug message which like printf arguement.
109  * @retval  None
110  */
111 #define _R_DEBUG(module, dlevel, expand, msg, arg...)   \
112         do { \
113             if ( \
114                 ((module) & DBG_ON) && \
115                 (((module) & DBG_LEVEL_MASK) >= dlevel) && \
116                 (expand)) { \
117                 R_DEBUG_PRINT(msg, ##arg); \
118             } \
119         } while(0)
120 
121 /*
122  * @brief   The realization of showing debug messages and it can't be turn off by
123  *          module ON/OFF.
124  * @param   module: Contained a module On/Off and a module debug level.
125  * @param   dlevel: Debug message showed level for seal.
126  * @param   expand: Expanded condition if level param is not enough for developer.
127  * @param   msg: The debug message.
128  * @param   arg: Arguement shown in debug message which like printf arguement.
129  * @retval  None
130  */
131 #define _R_INFO(module, dlevel, expand, msg, arg...)    \
132         do { \
133             if ( \
134                 (((int16_t)(module) & DBG_LEVEL_MASK) >= dlevel) && \
135                 (expand)) { \
136                 R_DEBUG_PRINT(msg, ##arg); \
137             } \
138         } while(0)
139 
140 /*
141  * @brief   The realization of assert debug messages shown the assert position,
142  *          for example: "[Assert] At module_debug.h line 112 fun _MASSERT: **"
143  * @param   module: Contained a module On/Off and a module debug level.
144  * @param   dlevel: Debug message showed level for seal.
145  * @param   msg: The debug message.
146  * @param   arg: Arguement shown in debug message which like printf arguement.
147  * @retval  None
148  */
149 #define _R_ASSERT(assert, module, dlevel, msg, arg...)  \
150         _R_DEBUG(module, dlevel, !(assert), \
151                 "[Assert] At %s line %d fun %s: " msg, \
152                 __FILE__, __LINE__, __func__, ##arg)
153 
154 /*
155  * @brief   The realization of assert debug messages shown the assert position,
156  *          and abort. for example: "[Assert] At module_debug.h line 112 fun
157  *          _MASSERT: ***"
158  * @param   module: Contained a module On/Off and a module debug level.
159  * @param   dlevel: Debug message showed level for seal.
160  * @param   msg: The debug message.
161  * @param   arg: Arguement shown in debug message which like printf arguement.
162  * @retval  None
163  */
164 #define _R_ASSERT_ABORT(assert, module, dlevel, msg, arg...)    \
165         do { \
166             if ((((int16_t)(module) & DBG_LEVEL_MASK) >= dlevel) && !(assert)) { \
167                 R_DEBUG_PRINT("[Assert] At %s line %d fun %s: " msg, \
168                              __FILE__, __LINE__, __func__, ##arg); \
169                 R_DEBUG_ABORT(); \
170             } \
171         } while(0)
172 
173 
174 /*
175  * @brief   A level debug message
176  * @param   module: Contained a module On/Off and a module debug level.
177  * @param   expand: Expanded condition if level param and module ON/OFF are not
178  *                  enough for developer.
179  * @param   msg: The debug message.
180  * @param   arg: Arguement shown in debug message which like printf arguement.
181  * @retval  None
182  */
183 #define R_ERROR(module, expand, msg, arg...) \
184         _R_DEBUG(module, R_LEVEL_ERROR, expand, msg, ##arg)
185 
186 #define R_ALERT(module, expand, msg, arg...) \
187         _R_DEBUG(module, R_LEVEL_ALERT, expand, msg, ##arg)
188 
189 #define R_CRIT(module, expand, msg, arg...) \
190         _R_DEBUG(module, R_LEVEL_CRIT, expand, msg, ##arg)
191 
192 #define R_EMERG(module, expand, msg, arg...) \
193         _R_DEBUG(module, R_LEVEL_EMERG, R_xpand, msg, ##arg)
194 
195 #define R_WARN(module, expand, msg, arg...) \
196         _R_DEBUG(module, R_LEVEL_WARNING, expand, msg, ##arg)
197 
198 #define R_NOTICE(module, expand, msg, arg...) \
199         _R_DEBUG(module, R_LEVEL_NOTICE, expand, msg, ##arg)
200 
201 #define R_INFO(module, expand, msg, arg...) \
202         _R_DEBUG(module, R_LEVEL_INFO, expand, msg, ##arg)
203 
204 #define R_DEBUG(module, expand, msg, arg...) \
205         _R_DEBUG(module, R_LEVEL_DEBUG, expand, msg, ##arg)
206 
207 
208 /*
209  * @brief   Assert a full debug message with position(file, line, etc.) without level.
210  *          for example: "[Assert] At module_debug.h line 112 fun _MASSERT: ***"
211  * @param   assert: Debug condition
212  * @param   module: Contained a module On/Off at least.
213  * @param   msg: The debug message.
214  * @param   arg: Arguement shown in debug message which like printf arguement.
215  * @retval  None
216  */
217 #define R_ASSERT(assert, module, msg, arg...) \
218         _R_ASSERT(assert, module, R_LEVEL_ALL, msg, ##arg)
219 
220 #define R_ASSERT_ABORT(assert, module, msg, arg...) \
221         _R_ASSERT_ABORT(assert, module, R_LEVEL_ALL, msg, ##arg)
222 
223 /*
224  * @brief   Assert a full debug message with position(file, line, etc.) and
225  *          error number without level. for example:
226  *          "[Assert] At module_debug.h line 112 fun _MASSERT: condition p != NULL is fault. errno is 115."
227  * @param   condition: It will assert a message if condition is fault.
228  * @retval  Nuon
229  */
230 #ifndef assert
231 #define assert(condition) R_ASSERT(condition, MOD_DBG_ALW_ON, "condition %s is fault. errno is %d.\n", #condition, r_thread_errno)
232 #endif
233 
234 /*
235 // THIS REALIZATION DO NOT SEAL
236 #define R_ASSERT(assert, module, msg, arg...) \
237         _R_ASSERT(assert, module, R_LEVEL_ALL, "[%s]" msg, #module, ##arg)
238 
239 #define R_ASSERT_ABORT(assert, module, msg, arg...) \
240         _R_ASSERT_ABORT(assert, module, R_LEVEL_ALL, "[%s]" msg, #module, ##arg)
241 */
242 
243 
244 /*
245  * @brief   notify the function entry and exit/return in the debug level
246  * @param   module: Contained a module On/Off at least.
247  * @param   mname: module name in string
248  * @param   ret: return value
249  * @retval  None
250  */
251 #define R_ENTRY(module, mname) \
252         R_DEBUG(module, NOEXPAND, mname "entry %s().\n", __func__)
253 
254 #define R_RET(module, mname, ret) \
255         R_DEBUG(module, NOEXPAND, mname "exit %s() with return %d.\n", __func__, ret)
256 
257 #define R_RET_NOVAL(module, mname) \
258         R_DEBUG(module, NOEXPAND, mname "exit %s().\n", __func__)
259 
260 
261 #else /* MDEBUG_ON */
262 
263 #define R_DEBUG_PRINT(msg, arg...)
264 
265 #define R_DEBUG_ABORT()
266 
267 
268 #define _R_DEBUG(module, dlevel, expand, msg, arg...)
269 
270 #define _R_INFO(module, dlevel, expand, msg, arg...)
271 
272 #define _R_ASSERT(assert, module, dlevel, msg, arg...)
273 
274 #define _R_ASSERT_ABORT(assert, module, dlevel, msg, arg...)
275 
276 
277 #define R_ERROR(module, expand, msg, arg...)
278 
279 #define R_ALERT(module, expand, msg, arg...)
280 
281 #define R_CRIT(module, expand, msg, arg...)
282 
283 #define R_EMERG(module, expand, msg, arg...)
284 
285 #define R_WARN(module, expand, msg, arg...)
286 
287 #define R_NOTICE(module, expand, msg, arg...)
288 
289 #define R_INFO(module, expand, msg, arg...)
290 
291 #define R_DEBUG(module, expand, msg, arg...)
292 
293 
294 #define R_ASSERT(assert, module, msg, arg...)
295 
296 #define R_ASSERT_ABORT(assert, module, msg, arg...)
297 
298 #ifndef assert
299 #define assert(condition)
300 #endif
301 
302 
303 #define R_ENTRY(module, mname)
304 
305 #define R_RET(module, mname, ret)
306 
307 #define R_RET_NOVAL(module, mname)
308 
309 #endif /* R_DEBUG_ON */
310 
311 #define ROM_DUMP_MASK   (1 << 0)
312 #define ROM_DBG_MASK    (1 << 1)
313 #define ROM_INF_MASK    (1 << 2)
314 #define ROM_WRN_MASK    (1 << 3)
315 #define ROM_ERR_MASK    (1 << 4)
316 #define ROM_ANY_MASK    (1 << 5)
317 #define ROM_ABORT_MASK  (1 << 6)
318 #define ROM_TOTAL_MASKS (ROM_DUMP_MASK | ROM_DBG_MASK | ROM_INF_MASK | \
319                          ROM_WRN_MASK | ROM_ERR_MASK | ROM_ANY_MASK | \
320                          ROM_ABORT_MASK)
321 
322 enum {
323     DUMP_PREFIX_NONE,
324     DUMP_PREFIX_ADDRESS,
325     DUMP_PREFIX_OFFSET
326 };
327 
328 extern int hex_to_bin(char ch);
329 
330 extern int hex2bin(unsigned char *dst, const char *src, size_t count);
331 
332 extern void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
333                                int groupsize, char *linebuf, size_t linebuflen,
334                                bool ascii);
335 
336 extern void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
337                                int groupsize, char *linebuf, size_t linebuflen,
338                                bool ascii);
339 
340 extern void print_hex_dump(const char *prefix_str, int prefix_type,
341                            int rowsize, int groupsize,
342                            const void *buf, size_t len, bool ascii);
343 
344 
345 extern void print_hex_dump_words(const void *addr, unsigned int len);
346 
347 /*
348 //$ Example of r_debug from mqtt $
349 
350 #define MQTT_MODULE (DBG_ON | R_LEVEL_DEBUG)
351 
352 #ifdef MOTT_ASSERT_ON
353 #define MQTT_ASSERT(assert, msg, arg...) R_ALERT(MOD_DBG_ALW_ON, (assert), "[MQTT assert] "msg, ##arg)
354 #else
355 #define MQTT_ASSERT(assert, msg, arg...)
356 #endif
357 
358 #ifdef MQTT_DBG_ON
359 
360 #define MQTT_INFO(msg, arg...) R_INFO(MQTT_MODULE, NOEXPAND, "[MQTT info] " msg, ##arg)
361 
362 #define MQTT_WARN(msg, arg...) R_WARN(MQTT_MODULE, NOEXPAND, "[MQTT warning] " msg, ##arg)
363 
364 #define MQTT_DEBUG(msg, arg...) R_DEBUG(MQTT_MODULE, NOEXPAND, "[MQTT debug] " msg, ##arg)
365 
366 
367 
368 #define MQTT_ENTRY() R_ENTRY(MQTT_MODULE, "[MQTT entry] ")
369 
370 #define MQTT_EXIT(ret) R_RET(MQTT_MODULE, "[MQTT return] ", ret)
371 
372 #else
373 
374 #define MQTT_INFO(msg, arg...)
375 
376 #define MQTT_WARN(msg, arg...)
377 
378 #define MQTT_DEBUG(msg, arg...)
379 
380 
381 #define MQTT_ENTRY()
382 
383 #define MQTT_EXIT(ret)
384 
385 #endif
386 
387 */
388 
389 extern void print_hex_dump_bytes(const void *addr, unsigned int len);
390 extern void print_hex_dump_words(const void *addr, unsigned int len);
391 
392 #endif /* __R_DEBUG_H__ */
393