|
@@ -246,20 +246,16 @@ static char *get_log_buf(void)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *tag, rt_bool_t newline,
|
|
|
|
- const char *format, va_list args)
|
|
|
|
|
|
+RT_WEAK rt_size_t ulog_head_formater(char *log_buf, rt_uint32_t level, const char *tag)
|
|
{
|
|
{
|
|
/* the caller has locker, so it can use static variable for reduce stack usage */
|
|
/* the caller has locker, so it can use static variable for reduce stack usage */
|
|
- static rt_size_t log_len, newline_len;
|
|
|
|
- static int fmt_result;
|
|
|
|
|
|
+ static rt_size_t log_len;
|
|
|
|
|
|
RT_ASSERT(log_buf);
|
|
RT_ASSERT(log_buf);
|
|
RT_ASSERT(level <= LOG_LVL_DBG);
|
|
RT_ASSERT(level <= LOG_LVL_DBG);
|
|
RT_ASSERT(tag);
|
|
RT_ASSERT(tag);
|
|
- RT_ASSERT(format);
|
|
|
|
|
|
|
|
log_len = 0;
|
|
log_len = 0;
|
|
- newline_len = rt_strlen(ULOG_NEWLINE_SIGN);
|
|
|
|
|
|
|
|
#ifdef ULOG_USING_COLOR
|
|
#ifdef ULOG_USING_COLOR
|
|
/* add CSI start sign and color info */
|
|
/* add CSI start sign and color info */
|
|
@@ -370,19 +366,18 @@ RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *ta
|
|
#endif /* ULOG_OUTPUT_THREAD_NAME */
|
|
#endif /* ULOG_OUTPUT_THREAD_NAME */
|
|
|
|
|
|
log_len += ulog_strcpy(log_len, log_buf + log_len, ": ");
|
|
log_len += ulog_strcpy(log_len, log_buf + log_len, ": ");
|
|
- fmt_result = rt_vsnprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, format, args);
|
|
|
|
|
|
|
|
- /* calculate log length */
|
|
|
|
- if ((log_len + fmt_result <= ULOG_LINE_BUF_SIZE) && (fmt_result > -1))
|
|
|
|
- {
|
|
|
|
- log_len += fmt_result;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- /* using max length */
|
|
|
|
- log_len = ULOG_LINE_BUF_SIZE;
|
|
|
|
- }
|
|
|
|
|
|
+ return log_len;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
|
|
+RT_WEAK rt_size_t ulog_tail_formater(char *log_buf, rt_size_t log_len, rt_bool_t newline, rt_uint32_t level)
|
|
|
|
+{
|
|
|
|
+ /* the caller has locker, so it can use static variable for reduce stack usage */
|
|
|
|
+ static rt_size_t newline_len;
|
|
|
|
+
|
|
|
|
+ RT_ASSERT(log_buf);
|
|
|
|
+ newline_len = rt_strlen(ULOG_NEWLINE_SIGN);
|
|
/* overflow check and reserve some space for CSI end sign, newline sign and string end sign */
|
|
/* overflow check and reserve some space for CSI end sign, newline sign and string end sign */
|
|
#ifdef ULOG_USING_COLOR
|
|
#ifdef ULOG_USING_COLOR
|
|
if (log_len + (sizeof(CSI_END) - 1) + newline_len + sizeof((char)'\0') > ULOG_LINE_BUF_SIZE)
|
|
if (log_len + (sizeof(CSI_END) - 1) + newline_len + sizeof((char)'\0') > ULOG_LINE_BUF_SIZE)
|
|
@@ -423,6 +418,86 @@ RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *ta
|
|
return log_len;
|
|
return log_len;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *tag, rt_bool_t newline,
|
|
|
|
+ const char *format, va_list args)
|
|
|
|
+{
|
|
|
|
+ /* the caller has locker, so it can use static variable for reduce stack usage */
|
|
|
|
+ static rt_size_t log_len;
|
|
|
|
+ static int fmt_result;
|
|
|
|
+
|
|
|
|
+ RT_ASSERT(log_buf);
|
|
|
|
+ RT_ASSERT(format);
|
|
|
|
+
|
|
|
|
+ /* log head */
|
|
|
|
+ log_len = ulog_head_formater(log_buf, level, tag);
|
|
|
|
+ /* log content */
|
|
|
|
+ fmt_result = rt_vsnprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, format, args);
|
|
|
|
+ /* calculate log length */
|
|
|
|
+ if ((log_len + fmt_result <= ULOG_LINE_BUF_SIZE) && (fmt_result > -1))
|
|
|
|
+ {
|
|
|
|
+ log_len += fmt_result;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ /* using max length */
|
|
|
|
+ log_len = ULOG_LINE_BUF_SIZE;
|
|
|
|
+ }
|
|
|
|
+ /* log tail */
|
|
|
|
+ return ulog_tail_formater(log_buf, log_len, newline, level);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+RT_WEAK rt_size_t ulog_hex_formater(char *log_buf, const char *tag, const rt_uint8_t *buf, rt_size_t size, rt_size_t width, rt_base_t addr)
|
|
|
|
+{
|
|
|
|
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
|
|
|
|
+ /* the caller has locker, so it can use static variable for reduce stack usage */
|
|
|
|
+ static rt_size_t log_len, j;
|
|
|
|
+ static int fmt_result;
|
|
|
|
+ char dump_string[8];
|
|
|
|
+
|
|
|
|
+ RT_ASSERT(log_buf);
|
|
|
|
+ RT_ASSERT(buf);
|
|
|
|
+
|
|
|
|
+ /* log head */
|
|
|
|
+ log_len = ulog_head_formater(log_buf, LOG_LVL_DBG, tag);
|
|
|
|
+ /* log content */
|
|
|
|
+ fmt_result = rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE, "%04X-%04X: ", addr, addr + size);
|
|
|
|
+ /* calculate log length */
|
|
|
|
+ if ((fmt_result > -1) && (fmt_result <= ULOG_LINE_BUF_SIZE))
|
|
|
|
+ {
|
|
|
|
+ log_len += fmt_result;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ log_len = ULOG_LINE_BUF_SIZE;
|
|
|
|
+ }
|
|
|
|
+ /* dump hex */
|
|
|
|
+ for (j = 0; j < width; j++)
|
|
|
|
+ {
|
|
|
|
+ if (j < size)
|
|
|
|
+ {
|
|
|
|
+ rt_snprintf(dump_string, sizeof(dump_string), "%02X ", buf[j]);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ rt_strncpy(dump_string, " ", sizeof(dump_string));
|
|
|
|
+ }
|
|
|
|
+ log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
|
|
|
|
+ if ((j + 1) % 8 == 0)
|
|
|
|
+ {
|
|
|
|
+ log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
|
|
|
|
+ /* dump char for hex */
|
|
|
|
+ for (j = 0; j < size; j++)
|
|
|
|
+ {
|
|
|
|
+ rt_snprintf(dump_string, sizeof(dump_string), "%c", __is_print(buf[j]) ? buf[j] : '.');
|
|
|
|
+ log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
|
|
|
|
+ }
|
|
|
|
+ /* log tail */
|
|
|
|
+ return ulog_tail_formater(log_buf, log_len, RT_TRUE, LOG_LVL_DBG);
|
|
|
|
+}
|
|
|
|
+
|
|
static void ulog_output_to_all_backend(rt_uint32_t level, const char *tag, rt_bool_t is_raw, const char *log, rt_size_t len)
|
|
static void ulog_output_to_all_backend(rt_uint32_t level, const char *tag, rt_bool_t is_raw, const char *log, rt_size_t len)
|
|
{
|
|
{
|
|
rt_slist_t *node;
|
|
rt_slist_t *node;
|
|
@@ -552,24 +627,28 @@ static void do_output(rt_uint32_t level, const char *tag, rt_bool_t is_raw, cons
|
|
* @param level level
|
|
* @param level level
|
|
* @param tag tag
|
|
* @param tag tag
|
|
* @param newline has_newline
|
|
* @param newline has_newline
|
|
|
|
+ * @param hex_buf != RT_NULL: enable hex log mode, data buffer
|
|
|
|
+ * @param hex_size hex data buffer size
|
|
|
|
+ * @param hex_width hex log width
|
|
|
|
+ * @param hex_addr hex data address
|
|
* @param format output format
|
|
* @param format output format
|
|
* @param args variable argument list
|
|
* @param args variable argument list
|
|
*/
|
|
*/
|
|
-void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const char *format, va_list args)
|
|
|
|
|
|
+void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const rt_uint8_t *hex_buf, rt_size_t hex_size,
|
|
|
|
+ rt_size_t hex_width, rt_base_t hex_addr, const char *format, va_list args)
|
|
{
|
|
{
|
|
static rt_bool_t ulog_voutput_recursion = RT_FALSE;
|
|
static rt_bool_t ulog_voutput_recursion = RT_FALSE;
|
|
char *log_buf = RT_NULL;
|
|
char *log_buf = RT_NULL;
|
|
- rt_size_t log_len = 0;
|
|
|
|
|
|
+ static rt_size_t log_len = 0;
|
|
|
|
|
|
RT_ASSERT(tag);
|
|
RT_ASSERT(tag);
|
|
- RT_ASSERT(format);
|
|
|
|
|
|
+ RT_ASSERT((format && !hex_buf) || (!format && hex_buf));
|
|
#ifndef ULOG_USING_SYSLOG
|
|
#ifndef ULOG_USING_SYSLOG
|
|
RT_ASSERT(level <= LOG_LVL_DBG);
|
|
RT_ASSERT(level <= LOG_LVL_DBG);
|
|
#else
|
|
#else
|
|
RT_ASSERT(LOG_PRI(level) <= LOG_DEBUG);
|
|
RT_ASSERT(LOG_PRI(level) <= LOG_DEBUG);
|
|
#endif /* ULOG_USING_SYSLOG */
|
|
#endif /* ULOG_USING_SYSLOG */
|
|
|
|
|
|
-
|
|
|
|
if (!ulog.init_ok)
|
|
if (!ulog.init_ok)
|
|
{
|
|
{
|
|
return;
|
|
return;
|
|
@@ -603,10 +682,10 @@ void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const c
|
|
output_lock();
|
|
output_lock();
|
|
|
|
|
|
/* If there is a recursion, we use a simple way */
|
|
/* If there is a recursion, we use a simple way */
|
|
- if (ulog_voutput_recursion == RT_TRUE)
|
|
|
|
|
|
+ if ((ulog_voutput_recursion == RT_TRUE) && (hex_buf == RT_NULL))
|
|
{
|
|
{
|
|
rt_kprintf(format, args);
|
|
rt_kprintf(format, args);
|
|
- if(newline == RT_TRUE)
|
|
|
|
|
|
+ if (newline == RT_TRUE)
|
|
{
|
|
{
|
|
rt_kprintf(ULOG_NEWLINE_SIGN);
|
|
rt_kprintf(ULOG_NEWLINE_SIGN);
|
|
}
|
|
}
|
|
@@ -616,12 +695,20 @@ void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const c
|
|
|
|
|
|
ulog_voutput_recursion = RT_TRUE;
|
|
ulog_voutput_recursion = RT_TRUE;
|
|
|
|
|
|
|
|
+ if (hex_buf == RT_NULL)
|
|
|
|
+ {
|
|
#ifndef ULOG_USING_SYSLOG
|
|
#ifndef ULOG_USING_SYSLOG
|
|
- log_len = ulog_formater(log_buf, level, tag, newline, format, args);
|
|
|
|
|
|
+ log_len = ulog_formater(log_buf, level, tag, newline, format, args);
|
|
#else
|
|
#else
|
|
- extern rt_size_t syslog_formater(char *log_buf, rt_uint8_t level, const char *tag, rt_bool_t newline, const char *format, va_list args);
|
|
|
|
- log_len = syslog_formater(log_buf, level, tag, newline, format, args);
|
|
|
|
|
|
+ extern rt_size_t syslog_formater(char *log_buf, rt_uint8_t level, const char *tag, rt_bool_t newline, const char *format, va_list args);
|
|
|
|
+ log_len = syslog_formater(log_buf, level, tag, newline, format, args);
|
|
#endif /* ULOG_USING_SYSLOG */
|
|
#endif /* ULOG_USING_SYSLOG */
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ /* hex mode */
|
|
|
|
+ log_len = ulog_hex_formater(log_buf, tag, hex_buf, hex_size, hex_width, hex_addr);
|
|
|
|
+ }
|
|
|
|
|
|
#ifdef ULOG_USING_FILTER
|
|
#ifdef ULOG_USING_FILTER
|
|
/* keyword filter */
|
|
/* keyword filter */
|
|
@@ -664,7 +751,7 @@ void ulog_output(rt_uint32_t level, const char *tag, rt_bool_t newline, const ch
|
|
/* args point to the first variable parameter */
|
|
/* args point to the first variable parameter */
|
|
va_start(args, format);
|
|
va_start(args, format);
|
|
|
|
|
|
- ulog_voutput(level, tag, newline, format, args);
|
|
|
|
|
|
+ ulog_voutput(level, tag, newline, RT_NULL, 0, 0, 0, format, args);
|
|
|
|
|
|
va_end(args);
|
|
va_end(args);
|
|
}
|
|
}
|
|
@@ -727,150 +814,23 @@ void ulog_raw(const char *format, ...)
|
|
* @param buf hex buffer
|
|
* @param buf hex buffer
|
|
* @param size buffer size
|
|
* @param size buffer size
|
|
*/
|
|
*/
|
|
-void ulog_hexdump(const char *tag, rt_size_t width, rt_uint8_t *buf, rt_size_t size)
|
|
|
|
|
|
+void ulog_hexdump(const char *tag, rt_size_t width, const rt_uint8_t *buf, rt_size_t size, ...)
|
|
{
|
|
{
|
|
-#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
|
|
|
|
-
|
|
|
|
- rt_size_t i, j;
|
|
|
|
- rt_size_t log_len = 0, name_len = rt_strlen(tag);
|
|
|
|
-#ifdef ULOG_OUTPUT_TIME
|
|
|
|
- rt_size_t time_head_len = 0;
|
|
|
|
-#endif
|
|
|
|
- char *log_buf = RT_NULL, dump_string[8];
|
|
|
|
- int fmt_result;
|
|
|
|
-
|
|
|
|
- RT_ASSERT(ulog.init_ok);
|
|
|
|
-
|
|
|
|
-#ifdef ULOG_USING_FILTER
|
|
|
|
- /* level filter */
|
|
|
|
-#ifndef ULOG_USING_SYSLOG
|
|
|
|
- if (LOG_LVL_DBG > ulog.filter.level || LOG_LVL_DBG > ulog_tag_lvl_filter_get(tag))
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-#else
|
|
|
|
- if ((LOG_MASK(LOG_DEBUG) & ulog.filter.level) == 0)
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-#endif /* ULOG_USING_SYSLOG */
|
|
|
|
- else if (!rt_strstr(tag, ulog.filter.tag))
|
|
|
|
- {
|
|
|
|
- /* tag filter */
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-#endif /* ULOG_USING_FILTER */
|
|
|
|
-
|
|
|
|
-#ifdef ULOG_USING_ASYNC_OUTPUT
|
|
|
|
- if (ulog.async_rb == RT_NULL)
|
|
|
|
- {
|
|
|
|
- ulog.async_rb = rt_ringbuffer_create(ULOG_ASYNC_OUTPUT_BUF_SIZE);
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- /* get log buffer */
|
|
|
|
- log_buf = get_log_buf();
|
|
|
|
|
|
+ rt_size_t i, len;
|
|
|
|
+ va_list args;
|
|
|
|
|
|
- /* lock output */
|
|
|
|
- output_lock();
|
|
|
|
|
|
+ va_start(args, size);
|
|
|
|
|
|
- for (i = 0, log_len = 0; i < size; i += width)
|
|
|
|
|
|
+ for (i = 0; i < size; i += width, buf += width)
|
|
{
|
|
{
|
|
- /* package header */
|
|
|
|
- if (i == 0)
|
|
|
|
- {
|
|
|
|
-#ifdef ULOG_OUTPUT_TIME
|
|
|
|
- /* add time info */
|
|
|
|
-#ifdef ULOG_TIME_USING_TIMESTAMP
|
|
|
|
- static time_t now;
|
|
|
|
- static struct tm *tm, tm_tmp;
|
|
|
|
-
|
|
|
|
- now = time(RT_NULL);
|
|
|
|
- tm = gmtime_r(&now, &tm_tmp);
|
|
|
|
-
|
|
|
|
-#ifdef RT_USING_SOFT_RTC
|
|
|
|
- rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, "%02d-%02d %02d:%02d:%02d.%03d ", tm->tm_mon + 1,
|
|
|
|
- tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, rt_tick_get() % 1000);
|
|
|
|
-#else
|
|
|
|
- rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, "%02d-%02d %02d:%02d:%02d ", tm->tm_mon + 1,
|
|
|
|
- tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
|
|
-#endif /* RT_USING_SOFT_RTC */
|
|
|
|
-
|
|
|
|
-#else
|
|
|
|
- static rt_size_t tick_len = 0;
|
|
|
|
-
|
|
|
|
- log_buf[log_len] = '[';
|
|
|
|
- tick_len = ulog_ultoa(log_buf + log_len + 1, rt_tick_get());
|
|
|
|
- log_buf[log_len + 1 + tick_len] = ']';
|
|
|
|
- log_buf[log_len + 2 + tick_len] = ' ';
|
|
|
|
- log_buf[log_len + 3 + tick_len] = '\0';
|
|
|
|
-#endif /* ULOG_TIME_USING_TIMESTAMP */
|
|
|
|
- time_head_len = rt_strlen(log_buf + log_len);
|
|
|
|
- log_len += time_head_len;
|
|
|
|
-#endif /* ULOG_OUTPUT_TIME */
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, "D/HEX ");
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, tag);
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, ": ");
|
|
|
|
- }
|
|
|
|
|
|
+ if (i + size < width)
|
|
|
|
+ len = size - i;
|
|
else
|
|
else
|
|
- {
|
|
|
|
- log_len = 6 + name_len + 2;
|
|
|
|
-#ifdef ULOG_OUTPUT_TIME
|
|
|
|
- log_len += time_head_len;
|
|
|
|
-#endif
|
|
|
|
- rt_memset(log_buf, ' ', log_len);
|
|
|
|
- }
|
|
|
|
- fmt_result = rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE, "%04X-%04X: ", i, i + width - 1);
|
|
|
|
- /* calculate log length */
|
|
|
|
- if ((fmt_result > -1) && (fmt_result <= ULOG_LINE_BUF_SIZE))
|
|
|
|
- {
|
|
|
|
- log_len += fmt_result;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- log_len = ULOG_LINE_BUF_SIZE;
|
|
|
|
- }
|
|
|
|
- /* dump hex */
|
|
|
|
- for (j = 0; j < width; j++)
|
|
|
|
- {
|
|
|
|
- if (i + j < size)
|
|
|
|
- {
|
|
|
|
- rt_snprintf(dump_string, sizeof(dump_string), "%02X ", buf[i + j]);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- rt_strncpy(dump_string, " ", sizeof(dump_string));
|
|
|
|
- }
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
|
|
|
|
- if ((j + 1) % 8 == 0)
|
|
|
|
- {
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
|
|
|
|
- /* dump char for hex */
|
|
|
|
- for (j = 0; j < width; j++)
|
|
|
|
- {
|
|
|
|
- if (i + j < size)
|
|
|
|
- {
|
|
|
|
- rt_snprintf(dump_string, sizeof(dump_string), "%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- /* overflow check and reserve some space for newline sign */
|
|
|
|
- if (log_len + rt_strlen(ULOG_NEWLINE_SIGN) > ULOG_LINE_BUF_SIZE)
|
|
|
|
- {
|
|
|
|
- log_len = ULOG_LINE_BUF_SIZE - rt_strlen(ULOG_NEWLINE_SIGN);
|
|
|
|
- }
|
|
|
|
- /* package newline sign */
|
|
|
|
- log_len += ulog_strcpy(log_len, log_buf + log_len, ULOG_NEWLINE_SIGN);
|
|
|
|
- /*add string end sign*/
|
|
|
|
- log_buf[log_len] = '\0';
|
|
|
|
- /* do log output */
|
|
|
|
- do_output(LOG_LVL_DBG, RT_NULL, RT_TRUE, log_buf, log_len);
|
|
|
|
|
|
+ len = width;
|
|
|
|
+ ulog_voutput(LOG_LVL_DBG, tag, RT_TRUE, buf, len, width, i, RT_NULL, args);
|
|
}
|
|
}
|
|
- /* unlock output */
|
|
|
|
- output_unlock();
|
|
|
|
|
|
+
|
|
|
|
+ va_end(args);
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef ULOG_USING_FILTER
|
|
#ifdef ULOG_USING_FILTER
|