diff --git a/include/logging/log_output.h b/include/logging/log_output.h index b15c8c90518..b4c0a62ee16 100644 --- a/include/logging/log_output.h +++ b/include/logging/log_output.h @@ -45,6 +45,10 @@ extern "C" { */ #define LOG_OUTPUT_FLAG_FORMAT_SYSLOG BIT(6) +/** @brief Flag forcing syslog format specified in mipi sys-t + */ +#define LOG_OUTPUT_FLAG_FORMAT_SYST BIT(7) + /** * @brief Prototype of the function processing output data. * diff --git a/modules/Kconfig.syst b/modules/Kconfig.syst new file mode 100644 index 00000000000..afeb9d0d873 --- /dev/null +++ b/modules/Kconfig.syst @@ -0,0 +1,8 @@ +# Copyright (c) 2019 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config MIPI_SYST_LIB + bool "MIPI SyS-T Library Support" + select NEWLIB_LIBC + help + This option enables the MIPI SyS-T Library diff --git a/subsys/logging/CMakeLists.txt b/subsys/logging/CMakeLists.txt index ad206048d09..40669d7291c 100644 --- a/subsys/logging/CMakeLists.txt +++ b/subsys/logging/CMakeLists.txt @@ -43,6 +43,11 @@ if(NOT CONFIG_LOG_MINIMAL) CONFIG_LOG_BACKEND_SWO log_backend_swo.c ) + + zephyr_sources_ifdef( + CONFIG_LOG_MIPI_SYST_ENABLE + log_output_syst.c + ) else() zephyr_sources(log_minimal.c) endif() diff --git a/subsys/logging/Kconfig b/subsys/logging/Kconfig index 8c74aae7509..2087a748242 100644 --- a/subsys/logging/Kconfig +++ b/subsys/logging/Kconfig @@ -81,6 +81,12 @@ config LOG_MAX_LEVEL - 3 INFO, maximal level set to LOG_LEVEL_INFO - 4 DEBUG, maximal level set to LOG_LEVEL_DBG +config LOG_MIPI_SYST_ENABLE + bool "Enable mipi syst format output" + select MIPI_SYST_LIB + help + Enable mipi syst format output for the logger system. + if !LOG_MINIMAL menu "Prepend log message with function name" diff --git a/subsys/logging/log_output.c b/subsys/logging/log_output.c index 31398b3419b..801ea06ba6c 100644 --- a/subsys/logging/log_output.c +++ b/subsys/logging/log_output.c @@ -49,6 +49,14 @@ typedef int (*out_func_t)(int c, void *ctx); extern int z_prf(int (*func)(), void *dest, char *format, va_list vargs); extern void z_vprintk(out_func_t out, void *log_output, const char *fmt, va_list ap); +extern void log_output_msg_syst_process(const struct log_output *log_output, + struct log_msg *msg, u32_t flag); +extern void log_output_string_syst_process(const struct log_output *log_output, + struct log_msg_ids src_level, + const char *fmt, va_list ap, u32_t flag); +extern void log_output_hexdump_syst_process(const struct log_output *log_output, + struct log_msg_ids src_level, + const u8_t *data, u32_t length, u32_t flag); /* The RFC 5424 allows very flexible mapping and suggest the value 0 being the * highest severity and 7 to be the lowest (debugging level) severity. @@ -514,6 +522,12 @@ void log_output_msg_process(const struct log_output *log_output, bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING); int prefix_offset; + if (IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) && + flags & LOG_OUTPUT_FLAG_FORMAT_SYST) { + log_output_msg_syst_process(log_output, msg, flags); + return; + } + prefix_offset = raw_string ? 0 : prefix_print(log_output, flags, std_msg, timestamp, level, domain_id, source_id); @@ -555,6 +569,13 @@ void log_output_string(const struct log_output *log_output, u16_t source_id = (u16_t)src_level.source_id; bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING); + if (IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) && + flags & LOG_OUTPUT_FLAG_FORMAT_SYST) { + log_output_string_syst_process(log_output, + src_level, fmt, ap, flags); + return; + } + if (!raw_string) { prefix_print(log_output, flags, true, timestamp, level, domain_id, source_id); @@ -591,6 +612,13 @@ void log_output_hexdump(const struct log_output *log_output, u8_t domain_id = (u8_t)src_level.domain_id; u16_t source_id = (u16_t)src_level.source_id; + if (IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) && + flags & LOG_OUTPUT_FLAG_FORMAT_SYST) { + log_output_hexdump_syst_process(log_output, + src_level, data, length, flags); + return; + } + prefix_offset = prefix_print(log_output, flags, true, timestamp, level, domain_id, source_id); diff --git a/subsys/logging/log_output_syst.c b/subsys/logging/log_output_syst.c new file mode 100644 index 00000000000..6364ae4a855 --- /dev/null +++ b/subsys/logging/log_output_syst.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2019 Intel corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +extern struct mipi_syst_handle log_syst_handle; +extern void update_systh_platform_data( + struct mipi_syst_handle *handle, + const struct log_output *log_output, u32_t flag); + +/* + * 0 MIPI_SYST_SEVERITY_MAX no assigned severity + * 1 MIPI_SYST_SEVERITY_FATAL critical error level + * 2 MIPI_SYST_SEVERITY_ERROR error message level + * 3 MIPI_SYST_SEVERITY_WARNING warning message level + * 4 MIPI_SYST_SEVERITY_INFO information message level + * 5 MIPI_SYST_SEVERITY_USER1 user defined level 5 + * 6 MIPI_SYST_SEVERITY_USER2 user defined level 6 + * 7 MIPI_SYST_SEVERITY_DEBUG debug information level + */ +static u32_t level_to_syst_severity(u32_t level) +{ + u32_t ret; + + switch (level) { + case LOG_LEVEL_NONE: + ret = 0U; + break; + case LOG_LEVEL_ERR: + ret = 2U; + break; + case LOG_LEVEL_WRN: + ret = 3U; + break; + case LOG_LEVEL_INF: + ret = 4U; + break; + case LOG_LEVEL_DBG: + ret = 7U; + break; + default: + ret = 7U; + break; + } + + return ret; +} + +static void std_print(struct log_msg *msg, + const struct log_output *log_output) +{ + const char *str = log_msg_str_get(msg); + u32_t nargs = log_msg_nargs_get(msg); + u32_t *args = alloca(sizeof(u32_t)*nargs); + u32_t severity = level_to_syst_severity(log_msg_level_get(msg)); + + for (int i = 0; i < nargs; i++) { + args[i] = log_msg_arg_get(msg, i); + } + + switch (log_msg_nargs_get(msg)) { + case 0: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str); + break; + case 1: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0]); + break; + case 2: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1]); + break; + case 3: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2]); + break; + case 4: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3]); + break; + case 5: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4]); + break; + case 6: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5]); + break; + case 7: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6]); + break; + case 8: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7]); + break; + case 9: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8]); + break; + case 10: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9]); + break; + case 11: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9], args[10]); + break; + case 12: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9], args[10], + args[11]); + break; + case 13: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9], args[10], + args[11], args[12]); + break; + case 14: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13]); + break; + case 15: + MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0], + args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13], args[14]); + break; + default: + /* Unsupported number of arguments. */ + __ASSERT_NO_MSG(true); + break; + } +} + +static void raw_string_print(struct log_msg *msg, + const struct log_output *log_output) +{ + char buf[CONFIG_LOG_STRDUP_MAX_STRING + 1]; + size_t length = CONFIG_LOG_STRDUP_MAX_STRING; + u32_t severity = level_to_syst_severity(log_msg_level_get(msg)); + + log_msg_hexdump_data_get(msg, buf, &length, 0); + + buf[length] = '\0'; + + MIPI_SYST_PRINTF(&log_syst_handle, severity, buf); +} + +static void hexdump_print(struct log_msg *msg, + const struct log_output *log_output) +{ + char buf[CONFIG_LOG_STRDUP_MAX_STRING + 1]; + size_t length = CONFIG_LOG_STRDUP_MAX_STRING; + u32_t severity = level_to_syst_severity(log_msg_level_get(msg)); + + log_msg_hexdump_data_get(msg, buf, &length, 0); + + MIPI_SYST_WRITE(&log_syst_handle, severity, 0x1A, buf, length); +} + +void log_output_msg_syst_process(const struct log_output *log_output, + struct log_msg *msg, u32_t flag) +{ + u8_t level = (u8_t)log_msg_level_get(msg); + bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING); + + update_systh_platform_data(&log_syst_handle, log_output, flag); + + if (log_msg_is_std(msg)) { + std_print(msg, log_output); + } else if (raw_string) { + raw_string_print(msg, log_output); + } else { + hexdump_print(msg, log_output); + } +} + +void log_output_string_syst_process(const struct log_output *log_output, + struct log_msg_ids src_level, + const char *fmt, va_list ap, u32_t flag) +{ + u8_t str[CONFIG_LOG_STRDUP_MAX_STRING]; + size_t length = CONFIG_LOG_STRDUP_MAX_STRING; + u32_t severity = level_to_syst_severity((u32_t)src_level.level); + + length = vsnprintk(str, length, fmt, ap); + str[length] = '\0'; + + update_systh_platform_data(&log_syst_handle, log_output, flag); + + MIPI_SYST_PRINTF(&log_syst_handle, severity, str); +} + +void log_output_hexdump_syst_process(const struct log_output *log_output, + struct log_msg_ids src_level, + const u8_t *data, u32_t length, u32_t flag) +{ + u32_t severity = level_to_syst_severity((u32_t)src_level.level); + + update_systh_platform_data(&log_syst_handle, log_output, flag); + + MIPI_SYST_WRITE(&log_syst_handle, severity, 0x1A, data, length); +} diff --git a/west.yml b/west.yml index 2b8376f3313..da86f0a8118 100644 --- a/west.yml +++ b/west.yml @@ -100,6 +100,9 @@ manifest: - name: littlefs path: modules/fs/littlefs revision: fe9572dd5a9fcf93a249daa4233012692bd2881d + - name: mipi-sys-t + path: modules/debug/mipi-sys-t + revision: baf51863f19f009b92e762115ba5572a5b996b92 self: path: zephyr