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