1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * Bernard the first version 9 * 2013-06-26 Grissiom refactor 10 */ 11 12 #ifndef __LOG_TRACE_H__ 13 #define __LOG_TRACE_H__ 14 15 #include <rtthread.h> 16 17 #define LOG_TRACE_LEVEL_MASK 0x0f 18 #define LOG_TRACE_LEVEL_NOTRACE 0x00 19 #define LOG_TRACE_LEVEL_ERROR 0x01 20 #define LOG_TRACE_LEVEL_WARNING 0x03 21 #define LOG_TRACE_LEVEL_INFO 0x05 22 #define LOG_TRACE_LEVEL_VERBOSE 0x07 23 #define LOG_TRACE_LEVEL_DEBUG 0x09 24 #define LOG_TRACE_LEVEL_ALL 0x0f 25 26 #if defined(LOG_TRACE_USING_LEVEL_NOTRACE) 27 #define LOG_TRACE_LEVEL_DEFAULT LOG_TRACE_LEVEL_NOTRACE 28 #elif defined(LOG_TRACE_USING_LEVEL_ERROR) 29 #define LOG_TRACE_LEVEL_DEFAULT LOG_TRACE_LEVEL_ERROR 30 #elif defined(LOG_TRACE_USING_LEVEL_WARNING) 31 #define LOG_TRACE_LEVEL_DEFAULT LOG_TRACE_LEVEL_WARNING 32 #elif defined(LOG_TRACE_USING_LEVEL_INFO) 33 #define LOG_TRACE_LEVEL_DEFAULT LOG_TRACE_LEVEL_INFO 34 #elif defined(LOG_TRACE_USING_LEVEL_VERBOSE) 35 #define LOG_TRACE_LEVEL_DEFAULT LOG_TRACE_LEVEL_VERBOSE 36 #elif defined(LOG_TRACE_USING_LEVEL_DEBUG) 37 #define LOG_TRACE_LEVEL_DEFAULT LOG_TRACE_LEVEL_DEBUG 38 #else 39 #define LOG_TRACE_LEVEL_DEFAULT LOG_TRACE_LEVEL_INFO 40 #endif 41 42 #define LOG_TRACE_ERROR "<1>" 43 #define LOG_TRACE_WARNING "<3>" 44 #define LOG_TRACE_INFO "<5>" 45 #define LOG_TRACE_VERBOSE "<7>" 46 #define LOG_TRACE_DEBUG "<9>" 47 48 #define LOG_TRACE_OPT_NOTS 0x10 /* no timestamp */ 49 #define LOG_TRACE_OPT_LN 0x20 /* terminate the current line */ 50 51 #define LOG_TRACE_CTRL_FLUSH 0x10 52 #define LOG_TRACE_CTRL_RESET 0x11 53 #define LOG_TRACE_CTRL_DUMP 0x12 54 55 //#define LOG_TRACE_USE_LONGNAME 56 57 #ifndef LOG_TRACE_BUFSZ 58 #define LOG_TRACE_BUFSZ RT_CONSOLEBUF_SIZE 59 #endif 60 61 /** maximum number of sessions that can be registered to the log_trace system 62 */ 63 #ifndef LOG_TRACE_MAX_SESSION 64 #define LOG_TRACE_MAX_SESSION 16 65 #endif 66 67 #ifdef LOG_TRACE_USE_LONGNAME 68 typedef rt_uint64_t log_trace_idnum_t; 69 #else 70 typedef rt_uint32_t log_trace_idnum_t; 71 #endif 72 73 /* use a integer to represent a string to avoid strcmp. Even 4 chars 74 * should be enough for most of the cases. 75 * NOTE: take care when converting the name string to id number, you 76 * can trapped in endianness. 77 */ 78 union log_trace_id { 79 char name[sizeof(log_trace_idnum_t)]; 80 log_trace_idnum_t num; 81 }; 82 83 struct log_trace_session 84 { 85 union log_trace_id id; 86 rt_uint8_t lvl; 87 }; 88 89 /** initialize the log_trace system */ 90 int log_trace_init(void); 91 92 /** register a session. 93 * 94 * @return RT_EOK on success. -RT_EFULL if there is no space for registration. 95 */ 96 rt_err_t log_trace_register_session(const struct log_trace_session *session); 97 98 /** find a session with name 99 * 100 * The name is not enclosed by parenthesis([]). 101 * 102 * @return RT_NULL if there is no such a session. 103 */ 104 struct log_trace_session* log_trace_session_find(const char *name); 105 106 /** set the log level of the default session. */ 107 void log_trace_set_level(rt_uint8_t level); 108 109 /** set the log level of the session */ 110 void log_trace_session_set_level( 111 struct log_trace_session *session, rt_uint8_t level); 112 113 /** log according to the format 114 * 115 * the format of log_trace is: "<level>[name]log messages". It will output 116 * "[systick][name]log messages" When there is no session named name, the 117 * default session will be used. 118 * 119 * We have keep the level tag before the name tag because we don't print put 120 * the level tag to the output and it's easier to implement if we place the 121 * level tag in the very beginning. 122 */ 123 void log_trace(const char *fmt, ...); 124 125 /** log into session. 126 * 127 * the format of log_trace is: "<level>log messages". It will output 128 * "[systick][name]log messages". The name is the name of the session. It is 129 * faster than bare log_trace. 130 */ 131 void log_session(const struct log_trace_session *session, const char *fmt, ...); 132 133 extern void __logtrace_vfmtout(const struct log_trace_session *session, 134 const char *fmt, 135 va_list argptr); 136 137 rt_inline void __logtrace_fmtout(const struct log_trace_session *session, 138 const char *fmt, ...) 139 { 140 va_list args; 141 142 va_start(args, fmt); 143 __logtrace_vfmtout(session, fmt, args); 144 va_end(args); 145 } 146 147 /** 148 * log with numeric level 149 * 150 * The prototype of this function is: 151 * 152 * void log_session_lvl(struct log_trace_session *session, 153 * int lvl, 154 * const char *fmt, ...); 155 * 156 * If the @session is const and @level is greater than @session->lvl, the whole 157 * function will be optimized out. This is suitable for performance critical 158 * places where in most cases, the log is turned off by level. 159 */ 160 #define log_session_lvl(session, level, fmt, ...) \ 161 do { \ 162 if ((level) > (session)->lvl) \ 163 { \ 164 break; \ 165 } \ 166 __logtrace_fmtout(session, fmt, ##__VA_ARGS__); \ 167 } while (0) 168 169 /* here comes the global part. All sessions share the some output backend. */ 170 171 /** get the backend device */ 172 rt_device_t log_trace_get_device(void); 173 174 /** set the backend device */ 175 rt_err_t log_trace_set_device(const char *device_name); 176 177 void log_trace_flush(void); 178 179 #ifdef RT_USING_DFS 180 /** set the backend to file */ 181 void log_trace_set_file(const char *filename); 182 183 void log_trace_file_init(const char *filename); 184 #endif /* RT_USING_DFS */ 185 186 #endif 187 188