net: openthread: improved OT log interface

Added automatic strdup for RAM %s parameters. Postponed format
processing to idle time. Automatic parameters counting during
compilation. Very fast execution for up to three parameters.

Signed-off-by: Tomasz Konieczny <tomasz.konieczny@nordicsemi.no>
This commit is contained in:
Tomasz Konieczny 2020-03-27 12:15:50 +01:00 committed by Carles Cufí
commit 2cab72788e
2 changed files with 67 additions and 16 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
* Copyright (c) 2018 - 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,6 +9,7 @@
#include <stdio.h>
#include <openthread/platform/logging.h>
#include "openthread-core-zephyr-config.h"
#define LOG_MODULE_NAME net_openthread
#define LOG_LEVEL LOG_LEVEL_DBG
@ -17,41 +18,63 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "platform-zephyr.h"
#define LOG_PARSE_BUFFER_SIZE 128
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion,
const char *aFormat, ...)
{
/*
* The following speed optimization have been used:
* - arguments are counted at compile time
* - for none arguments aFormat is not checked for %s
* - for up to three arguments program uses fast path
* - time consuming string formatting is posponed to idle time
* TODO : add support for ll (problem for 32 bit processors)
*/
#ifdef OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION__COUNT_ARGS
/* The arguments number has been counted by macro at compile time,
* and the value has been passed in unused (now) aLogRegion.
* If LogRegion value from OT is needed, rewrite macro
* OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION__COUNT_ARGS and use higher bits.
* to pass args_num.
*/
uint32_t args_num = (uint32_t) aLogRegion;
#else
ARG_UNUSED(aLogRegion);
char logString[LOG_PARSE_BUFFER_SIZE + 1];
uint16_t length = 0U;
uint32_t args_num = log_count_args(aFormat);
#endif
/* Parse user string. */
va_list paramList;
va_start(paramList, aFormat);
length += vsnprintf(&logString[length],
(LOG_PARSE_BUFFER_SIZE - length),
aFormat, paramList);
va_end(paramList);
va_list param_list;
va_start(param_list, aFormat);
/* We assume, that OT has no access to strdup utility,
* and we are not obliged to check, if string has already
* been duplicated. So, to save time, in Z_LOG_VA macro calls
* we will use LOG_STRDUP_EXEC option.
*/
switch (aLogLevel) {
case OT_LOG_LEVEL_CRIT:
LOG_ERR("%s", log_strdup(logString));
Z_LOG_VA(LOG_LEVEL_ERR, aFormat, param_list, args_num,
LOG_STRDUP_EXEC);
break;
case OT_LOG_LEVEL_WARN:
LOG_WRN("%s", log_strdup(logString));
Z_LOG_VA(LOG_LEVEL_WRN, aFormat, param_list, args_num,
LOG_STRDUP_EXEC);
break;
case OT_LOG_LEVEL_NOTE:
case OT_LOG_LEVEL_INFO:
LOG_INF("%s", log_strdup(logString));
Z_LOG_VA(LOG_LEVEL_INF, aFormat, param_list, args_num,
LOG_STRDUP_EXEC);
break;
case OT_LOG_LEVEL_DEBG:
LOG_DBG("%s", log_strdup(logString));
Z_LOG_VA(LOG_LEVEL_DBG, aFormat, param_list, args_num,
LOG_STRDUP_EXEC);
break;
default:
break;
}
va_end(param_list);
}

View file

@ -151,4 +151,32 @@
*/
#define OPENTHREAD_CONFIG_NCP_BUFFER_SIZE 2048
/**
* @def OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION
*
* The platform logging function for openthread.
*
*/
#define _OT_CONF_PLAT_LOG_FUN_NARGS__IMPL( \
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10,\
_11, _12, _13, _14, N, ...) N
#define _OT_CONF_PLAT_LOG_FUN_NARGS__GET(...) \
_OT_CONF_PLAT_LOG_FUN_NARGS__IMPL(__VA_ARGS__,\
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ~)
#define OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION__COUNT_ARGS(aLogLevel, unused, \
aFormat, ...) \
otPlatLog(aLogLevel, \
(otLogRegion)_OT_CONF_PLAT_LOG_FUN_NARGS__GET(__VA_ARGS__),\
aFormat, ##__VA_ARGS__)
#ifdef OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION
#error OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION \
"OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION mustn't be defined before"
#endif
#define OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION \
OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION__COUNT_ARGS
#endif /* OPENTHREAD_CORE_NRF52840_CONFIG_H_ */