logging: Add remote link and backend
Added implementation of link and backend that are intended to complement each other. Both requires transport function hooks to be provided. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
050378ab39
commit
6c785b5677
9 changed files with 840 additions and 0 deletions
237
include/zephyr/logging/log_multidomain_helper.h
Normal file
237
include/zephyr/logging/log_multidomain_helper.h
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_MULTIDOMAIN_HELPER_H_
|
||||
#define ZEPHYR_INCLUDE_LOGGING_LOG_MULTIDOMAIN_HELPER_H_
|
||||
|
||||
/* This module aims to provide baseline for links and backends and simplify
|
||||
* the implementation. It is not core part of logging in similar way as
|
||||
* log_output module is just a helper for log message formatting. Links and
|
||||
* backends can be implemented without this helper.
|
||||
*/
|
||||
|
||||
/**@defgroup LOG_MULTIDOMAIN_HALPER_MESSAGE_IDS IDs of message.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Logging message ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_MSG 0
|
||||
|
||||
/** @brief Domain count request ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_CNT 1
|
||||
|
||||
/** @brief Source count request ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_CNT 2
|
||||
|
||||
/** @brief Domain name request ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME 3
|
||||
|
||||
/** @brief Source name request ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME 4
|
||||
|
||||
/** @brief Compile time and run-time levels request ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_GET_LEVELS 5
|
||||
|
||||
/** @brief Setting run-time level ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_SET_RUNTIME_LEVEL 6
|
||||
|
||||
/** @brief Get number of dropped message ID. */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_DROPPED 7
|
||||
|
||||
/** @brief Link-backend readiness indication ID/ */
|
||||
#define Z_LOG_MULTIDOMAIN_ID_READY 8
|
||||
|
||||
/**@} */
|
||||
|
||||
/**@defgroup LOG_MULTIDOMAIN_STATUS.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief OK. */
|
||||
#define Z_LOG_MULTIDOMAIN_STATUS_OK 0
|
||||
/** @brief Error. */
|
||||
#define Z_LOG_MULTIDOMAIN_STATUS_ERR 1
|
||||
|
||||
/**@} */
|
||||
|
||||
/** @brief Content of the logging message. */
|
||||
struct log_multidomain_log_msg {
|
||||
uint8_t data[0];
|
||||
} __packed;
|
||||
|
||||
/** @brief Content of the domain count message. */
|
||||
struct log_multidomain_domain_cnt {
|
||||
uint16_t count;
|
||||
} __packed;
|
||||
|
||||
/** @brief Content of the source count message. */
|
||||
struct log_multidomain_source_cnt {
|
||||
uint8_t domain_id;
|
||||
uint16_t count;
|
||||
} __packed;
|
||||
|
||||
/** @brief Content of the domain name message. */
|
||||
struct log_multidomain_domain_name {
|
||||
uint8_t domain_id;
|
||||
char name[0];
|
||||
} __packed;
|
||||
|
||||
/** @brief Content of the source name message. */
|
||||
struct log_multidomain_source_name {
|
||||
uint8_t domain_id;
|
||||
uint16_t source_id;
|
||||
char name[0];
|
||||
} __packed;
|
||||
|
||||
/** @brief Content of the message for getting logging levels. */
|
||||
struct log_multidomain_levels {
|
||||
uint8_t domain_id;
|
||||
uint16_t source_id;
|
||||
uint8_t level;
|
||||
uint8_t runtime_level;
|
||||
} __packed;
|
||||
|
||||
/** @brief Content of the message for setting logging level. */
|
||||
struct log_multidomain_set_runtime_level {
|
||||
uint8_t domain_id;
|
||||
uint16_t source_id;
|
||||
uint8_t runtime_level;
|
||||
} __packed;
|
||||
|
||||
/** @brief Content of the message for getting amount of dropped messages. */
|
||||
struct log_multidomain_dropped {
|
||||
uint32_t dropped;
|
||||
} __packed;
|
||||
|
||||
/** @brief Union with all message types. */
|
||||
union log_multidomain_msg_data {
|
||||
struct log_multidomain_log_msg log_msg;
|
||||
struct log_multidomain_domain_cnt domain_cnt;
|
||||
struct log_multidomain_source_cnt source_cnt;
|
||||
struct log_multidomain_domain_name domain_name;
|
||||
struct log_multidomain_source_name source_name;
|
||||
struct log_multidomain_levels levels;
|
||||
struct log_multidomain_set_runtime_level set_rt_level;
|
||||
struct log_multidomain_dropped dropped;
|
||||
};
|
||||
|
||||
/** @brief Message. */
|
||||
struct log_multidomain_msg {
|
||||
uint8_t id;
|
||||
uint8_t status;
|
||||
union log_multidomain_msg_data data;
|
||||
} __packed;
|
||||
|
||||
/** @brief Forward declaration. */
|
||||
struct log_multidomain_link;
|
||||
|
||||
/** @brief Structure with link transport API. */
|
||||
struct log_multidomain_link_transport_api {
|
||||
int (*init)(struct log_multidomain_link *link);
|
||||
int (*send)(struct log_multidomain_link *link, void *data, size_t len);
|
||||
};
|
||||
|
||||
/** @brief Union for holding data returned by associated remote backend. */
|
||||
union log_multidomain_link_dst {
|
||||
uint16_t count;
|
||||
|
||||
struct {
|
||||
char *dst;
|
||||
size_t *len;
|
||||
} name;
|
||||
|
||||
struct {
|
||||
uint8_t level;
|
||||
uint8_t runtime_level;
|
||||
} levels;
|
||||
|
||||
struct {
|
||||
uint8_t level;
|
||||
} set_runtime_level;
|
||||
};
|
||||
|
||||
/** @brief Remote link API. */
|
||||
extern struct log_link_api log_multidomain_link_api;
|
||||
|
||||
/** @brief Remote link structure. */
|
||||
struct log_multidomain_link {
|
||||
const struct log_multidomain_link_transport_api *transport_api;
|
||||
struct k_sem rdy_sem;
|
||||
const struct log_link *link;
|
||||
union log_multidomain_link_dst dst;
|
||||
int status;
|
||||
bool ready;
|
||||
};
|
||||
|
||||
/** @brief Forward declaration. */
|
||||
struct log_multidomain_backend;
|
||||
|
||||
/** @brief Backend transport API. */
|
||||
struct log_multidomain_backend_transport_api {
|
||||
int (*init)(struct log_multidomain_backend *backend);
|
||||
int (*send)(struct log_multidomain_backend *backend, void *data, size_t len);
|
||||
};
|
||||
|
||||
/** @brief Remote backend API. */
|
||||
extern const struct log_backend_api log_multidomain_backend_api;
|
||||
|
||||
/** @brief Remote backend structure. */
|
||||
struct log_multidomain_backend {
|
||||
const struct log_multidomain_backend_transport_api *transport_api;
|
||||
const struct log_backend *log_backend;
|
||||
struct k_sem rdy_sem;
|
||||
bool panic;
|
||||
int status;
|
||||
bool ready;
|
||||
};
|
||||
|
||||
/** @brief Function to be called when data is received from remote.
|
||||
*
|
||||
* @param link Link instance.
|
||||
* @param data Data.
|
||||
* @param len Data length.
|
||||
*/
|
||||
void log_multidomain_link_on_recv_cb(struct log_multidomain_link *link,
|
||||
const void *data, size_t len);
|
||||
|
||||
/** @brief Function called on error reported by transport layer.
|
||||
*
|
||||
* @param link Link instance.
|
||||
* @param err Error code.
|
||||
*/
|
||||
void log_multidomain_link_on_error(struct log_multidomain_link *link, int err);
|
||||
|
||||
/** @brief Function called when connection with remote is established.
|
||||
*
|
||||
* @param link Link instance.
|
||||
* @param err Error code.
|
||||
*/
|
||||
void log_multidomain_link_on_started(struct log_multidomain_link *link, int err);
|
||||
|
||||
/** @brief Function to be called when data is received from remote.
|
||||
*
|
||||
* @param backend Backend instance.
|
||||
* @param data Data.
|
||||
* @param len Data length.
|
||||
*/
|
||||
void log_multidomain_backend_on_recv_cb(struct log_multidomain_backend *backend,
|
||||
const void *data, size_t len);
|
||||
|
||||
/** @brief Function called on error reported by transport layer.
|
||||
*
|
||||
* @param backend Backend instance.
|
||||
* @param err Error code.
|
||||
*/
|
||||
void log_multidomain_backend_on_error(struct log_multidomain_backend *backend, int err);
|
||||
|
||||
/** @brief Function called when connection with remote is established.
|
||||
*
|
||||
* @param backend Backend instance.
|
||||
* @param err Error code.
|
||||
*/
|
||||
void log_multidomain_backend_on_started(struct log_multidomain_backend *backend, int err);
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_MULTIDOMAIN_HELPER_H_ */
|
|
@ -65,6 +65,13 @@ if(NOT CONFIG_LOG_MODE_MINIMAL)
|
|||
zephyr_sources(log_output_custom.c)
|
||||
endif()
|
||||
|
||||
zephyr_sources_ifdef(
|
||||
CONFIG_LOG_MULTIDOMAIN_LINK
|
||||
log_multidomain_link.c
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
else()
|
||||
zephyr_sources(log_minimal.c)
|
||||
endif()
|
||||
|
|
|
@ -36,6 +36,12 @@ rsource "Kconfig.frontends"
|
|||
|
||||
endif #LOG_FRONTEND
|
||||
|
||||
if LOG_MULTIDOMAIN
|
||||
|
||||
rsource "Kconfig.links"
|
||||
|
||||
endif
|
||||
|
||||
rsource "Kconfig.misc"
|
||||
|
||||
endif # LOG
|
||||
|
|
6
subsys/logging/Kconfig.links
Normal file
6
subsys/logging/Kconfig.links
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config LOG_MULTIDOMAIN_LINK
|
||||
bool
|
||||
select LOG_TIMESTAMP_64BIT
|
|
@ -64,3 +64,8 @@ zephyr_sources_ifdef(
|
|||
CONFIG_LOG_BACKEND_XTENSA_SIM
|
||||
log_backend_xtensa_sim.c
|
||||
)
|
||||
|
||||
zephyr_sources_ifdef(
|
||||
CONFIG_LOG_MULTIDOMAIN_BACKEND
|
||||
log_multidomain_backend.c
|
||||
)
|
||||
|
|
|
@ -15,5 +15,6 @@ rsource "Kconfig.spinel"
|
|||
rsource "Kconfig.swo"
|
||||
rsource "Kconfig.uart"
|
||||
rsource "Kconfig.xtensa_sim"
|
||||
rsource "Kconfig.multidomain"
|
||||
|
||||
endmenu
|
||||
|
|
7
subsys/logging/backends/Kconfig.multidomain
Normal file
7
subsys/logging/backends/Kconfig.multidomain
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config LOG_MULTIDOMAIN_BACKEND
|
||||
bool
|
||||
select LOG_TIMESTAMP_64BIT
|
||||
select LOG_MSG_APPEND_RO_STRING_LOC
|
246
subsys/logging/backends/log_multidomain_backend.c
Normal file
246
subsys/logging/backends/log_multidomain_backend.c
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/ipc/ipc_service.h>
|
||||
#include <zephyr/logging/log_multidomain_helper.h>
|
||||
#include <zephyr/logging/log_core.h>
|
||||
#include <zephyr/logging/log_backend.h>
|
||||
#include <zephyr/logging/log_ctrl.h>
|
||||
|
||||
static void process(const struct log_backend *const backend,
|
||||
union log_msg_generic *msg)
|
||||
{
|
||||
int err;
|
||||
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
||||
uint32_t dlen = msg->log.hdr.desc.data_len;
|
||||
int fsc_plen;
|
||||
|
||||
if (backend_remote->panic) {
|
||||
return;
|
||||
}
|
||||
|
||||
fsc_plen = cbprintf_fsc_package(msg->log.data,
|
||||
msg->log.hdr.desc.package_len,
|
||||
NULL,
|
||||
0);
|
||||
if (fsc_plen < 0) {
|
||||
__ASSERT_NO_MSG(false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to ensure that package is aligned to a pointer size. */
|
||||
uint32_t msg_len = Z_LOG_MSG2_LEN(fsc_plen, dlen);
|
||||
uint8_t buf[msg_len + sizeof(void *)] __aligned(sizeof(void *));
|
||||
size_t msg_offset = offsetof(struct log_multidomain_msg, data);
|
||||
struct log_multidomain_msg *out_msg =
|
||||
(struct log_multidomain_msg *)&buf[sizeof(void *) - msg_offset];
|
||||
struct log_msg *out_log_msg = (struct log_msg *)out_msg->data.log_msg.data;
|
||||
|
||||
/* Set ipc message id. */
|
||||
out_msg->id = Z_LOG_MULTIDOMAIN_ID_MSG;
|
||||
out_msg->status = Z_LOG_MULTIDOMAIN_STATUS_OK;
|
||||
/* Copy log message header. */
|
||||
memcpy(&out_log_msg->hdr, &msg->log.hdr, sizeof(struct log_msg_hdr));
|
||||
/* Update package len field in the message descriptor. */
|
||||
out_log_msg->hdr.desc.package_len = fsc_plen;
|
||||
|
||||
out_log_msg->hdr.source = out_log_msg->hdr.source ?
|
||||
(const void *)(IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ?
|
||||
log_dynamic_source_id((void *)out_log_msg->hdr.source) :
|
||||
log_const_source_id((void *)out_log_msg->hdr.source)) :
|
||||
(const void *)-1;
|
||||
|
||||
/* Fill new package. */
|
||||
fsc_plen = cbprintf_fsc_package(msg->log.data, msg->log.hdr.desc.package_len,
|
||||
out_log_msg->data, fsc_plen);
|
||||
if (fsc_plen < 0) {
|
||||
__ASSERT_NO_MSG(false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
if (dlen) {
|
||||
memcpy(&out_log_msg->data[fsc_plen],
|
||||
&msg->log.data[msg->log.hdr.desc.package_len],
|
||||
dlen);
|
||||
}
|
||||
|
||||
err = backend_remote->transport_api->send(backend_remote, out_msg, msg_len + msg_offset);
|
||||
if (err < 0) {
|
||||
__ASSERT(false, "Unexpected error: %d\n", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void log_multidomain_backend_on_started(struct log_multidomain_backend *backend_remote, int err)
|
||||
{
|
||||
backend_remote->status = err;
|
||||
|
||||
k_sem_give(&backend_remote->rdy_sem);
|
||||
}
|
||||
|
||||
void log_multidomain_backend_on_error(struct log_multidomain_backend *backend_remote, int err)
|
||||
{
|
||||
backend_remote->status = err;
|
||||
}
|
||||
|
||||
static void get_name_response(struct log_multidomain_backend *backend_remote,
|
||||
uint8_t domain_id, uint16_t source_id,
|
||||
bool domain_name)
|
||||
{
|
||||
const char *name = domain_name ?
|
||||
log_domain_name_get(domain_id) :
|
||||
log_source_name_get(domain_id, source_id);
|
||||
size_t slen = strlen(name);
|
||||
size_t msg_offset = offsetof(struct log_multidomain_msg, data);
|
||||
size_t msg_size = slen + 1 + msg_offset +
|
||||
(domain_name ? sizeof(struct log_multidomain_domain_name) :
|
||||
sizeof(struct log_multidomain_source_name));
|
||||
uint8_t msg_buf[msg_size];
|
||||
struct log_multidomain_msg *outmsg = (struct log_multidomain_msg *)msg_buf;
|
||||
char *dst = domain_name ?
|
||||
outmsg->data.domain_name.name :
|
||||
outmsg->data.source_name.name;
|
||||
int err;
|
||||
|
||||
outmsg->id = domain_name ? Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME :
|
||||
Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME;
|
||||
outmsg->status = Z_LOG_MULTIDOMAIN_STATUS_OK;
|
||||
memcpy(dst, name, slen);
|
||||
dst[slen] = '\0';
|
||||
|
||||
if (domain_name) {
|
||||
outmsg->data.domain_name.domain_id = domain_id;
|
||||
} else {
|
||||
outmsg->data.source_name.domain_id = domain_id;
|
||||
outmsg->data.source_name.source_id = source_id;
|
||||
}
|
||||
|
||||
err = backend_remote->transport_api->send(backend_remote, outmsg, msg_size);
|
||||
__ASSERT_NO_MSG(err >= 0);
|
||||
}
|
||||
|
||||
void log_multidomain_backend_on_recv_cb(struct log_multidomain_backend *backend_remote,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
struct log_multidomain_msg *msg = (struct log_multidomain_msg *)data;
|
||||
struct log_multidomain_msg outmsg = {
|
||||
.id = msg->id,
|
||||
.status = Z_LOG_MULTIDOMAIN_STATUS_OK
|
||||
};
|
||||
int err;
|
||||
|
||||
memcpy(&outmsg, msg, sizeof(struct log_multidomain_msg));
|
||||
|
||||
switch (msg->id) {
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_CNT:
|
||||
outmsg.data.domain_cnt.count = log_domains_count();
|
||||
break;
|
||||
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_CNT:
|
||||
outmsg.data.source_cnt.count =
|
||||
log_src_cnt_get(msg->data.source_cnt.domain_id);
|
||||
break;
|
||||
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME:
|
||||
get_name_response(backend_remote,
|
||||
msg->data.domain_name.domain_id,
|
||||
0, true);
|
||||
return;
|
||||
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME:
|
||||
get_name_response(backend_remote,
|
||||
msg->data.source_name.domain_id,
|
||||
msg->data.source_name.source_id,
|
||||
false);
|
||||
return;
|
||||
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_LEVELS:
|
||||
outmsg.data.levels.level =
|
||||
log_filter_get(backend_remote->log_backend,
|
||||
outmsg.data.levels.domain_id,
|
||||
outmsg.data.levels.source_id,
|
||||
false);
|
||||
outmsg.data.levels.runtime_level =
|
||||
log_filter_get(backend_remote->log_backend,
|
||||
outmsg.data.levels.domain_id,
|
||||
outmsg.data.levels.source_id,
|
||||
true);
|
||||
break;
|
||||
case Z_LOG_MULTIDOMAIN_ID_SET_RUNTIME_LEVEL:
|
||||
outmsg.data.set_rt_level.runtime_level =
|
||||
log_filter_set(backend_remote->log_backend,
|
||||
outmsg.data.set_rt_level.domain_id,
|
||||
outmsg.data.set_rt_level.source_id,
|
||||
outmsg.data.set_rt_level.runtime_level);
|
||||
break;
|
||||
case Z_LOG_MULTIDOMAIN_ID_READY:
|
||||
backend_remote->ready = true;
|
||||
break;
|
||||
default:
|
||||
__ASSERT(0, "Unexpected message");
|
||||
break;
|
||||
}
|
||||
|
||||
err = backend_remote->transport_api->send(backend_remote, &outmsg, sizeof(outmsg));
|
||||
__ASSERT_NO_MSG(err >= 0);
|
||||
}
|
||||
|
||||
static void init(struct log_backend const *const backend)
|
||||
{
|
||||
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
||||
int err;
|
||||
|
||||
backend_remote->log_backend = backend;
|
||||
k_sem_init(&backend_remote->rdy_sem, 0, 1);
|
||||
|
||||
err = backend_remote->transport_api->init(backend_remote);
|
||||
__ASSERT_NO_MSG(err >= 0);
|
||||
|
||||
err = k_sem_take(&backend_remote->rdy_sem, K_MSEC(4000));
|
||||
__ASSERT_NO_MSG(err >= 0);
|
||||
}
|
||||
|
||||
static int is_ready(struct log_backend const *const backend)
|
||||
{
|
||||
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
||||
|
||||
return backend_remote->ready ? 0 : -EINPROGRESS;
|
||||
}
|
||||
|
||||
static void panic(struct log_backend const *const backend)
|
||||
{
|
||||
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
||||
|
||||
backend_remote->panic = true;
|
||||
}
|
||||
|
||||
static void dropped(const struct log_backend *const backend, uint32_t cnt)
|
||||
{
|
||||
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
||||
int err;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_DROPPED,
|
||||
.status = Z_LOG_MULTIDOMAIN_STATUS_OK,
|
||||
.data = {
|
||||
.dropped = {
|
||||
.dropped = cnt
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
err = backend_remote->transport_api->send(backend_remote, &msg, sizeof(msg));
|
||||
__ASSERT_NO_MSG(err >= 0);
|
||||
}
|
||||
|
||||
const struct log_backend_api log_multidomain_backend_api = {
|
||||
.process = process,
|
||||
.panic = panic,
|
||||
.dropped = dropped,
|
||||
.init = init,
|
||||
.is_ready = is_ready
|
||||
};
|
325
subsys/logging/log_multidomain_link.c
Normal file
325
subsys/logging/log_multidomain_link.c
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/ipc/ipc_service.h>
|
||||
#include <zephyr/logging/log_link.h>
|
||||
#include <zephyr/logging/log_multidomain_helper.h>
|
||||
#include <zephyr/logging/log_core.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_DECLARE(link_ipc);
|
||||
|
||||
void log_multidomain_link_on_error(struct log_multidomain_link *link_remote, int err)
|
||||
{
|
||||
link_remote->status = err;
|
||||
}
|
||||
|
||||
void log_multidomain_link_on_started(struct log_multidomain_link *link_remote, int err)
|
||||
{
|
||||
link_remote->status = err;
|
||||
|
||||
if (err == 0) {
|
||||
link_remote->ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
void log_multidomain_link_on_recv_cb(struct log_multidomain_link *link_remote,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
struct log_multidomain_msg *msg = (struct log_multidomain_msg *)data;
|
||||
|
||||
if (msg->status != Z_LOG_MULTIDOMAIN_STATUS_OK) {
|
||||
link_remote->status = -EIO;
|
||||
goto exit;
|
||||
} else {
|
||||
link_remote->status = 0;
|
||||
}
|
||||
|
||||
switch (msg->id) {
|
||||
case Z_LOG_MULTIDOMAIN_ID_MSG:
|
||||
z_log_msg_enqueue(link_remote->link,
|
||||
msg->data.log_msg.data,
|
||||
len - offsetof(struct log_multidomain_msg, data));
|
||||
return;
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_CNT:
|
||||
link_remote->dst.count = msg->data.domain_cnt.count;
|
||||
break;
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_CNT:
|
||||
link_remote->dst.count = msg->data.source_cnt.count;
|
||||
break;
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME:
|
||||
{
|
||||
size_t slen = MIN(len - 1, *link_remote->dst.name.len - 1);
|
||||
|
||||
*link_remote->dst.name.len = len - 1;
|
||||
memcpy(link_remote->dst.name.dst, msg->data.domain_name.name, slen);
|
||||
link_remote->dst.name.dst[slen] = '\0';
|
||||
break;
|
||||
}
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME:
|
||||
{
|
||||
size_t slen = MIN(len - 1, *link_remote->dst.name.len - 1);
|
||||
|
||||
*link_remote->dst.name.len = len - 1;
|
||||
memcpy(link_remote->dst.name.dst, msg->data.source_name.name, slen);
|
||||
link_remote->dst.name.dst[slen] = '\0';
|
||||
break;
|
||||
}
|
||||
case Z_LOG_MULTIDOMAIN_ID_GET_LEVELS:
|
||||
link_remote->dst.levels.level = msg->data.levels.level;
|
||||
link_remote->dst.levels.runtime_level = msg->data.levels.runtime_level;
|
||||
break;
|
||||
case Z_LOG_MULTIDOMAIN_ID_SET_RUNTIME_LEVEL:
|
||||
link_remote->dst.set_runtime_level.level = msg->data.set_rt_level.runtime_level;
|
||||
break;
|
||||
case Z_LOG_MULTIDOMAIN_ID_READY:
|
||||
break;
|
||||
default:
|
||||
__ASSERT(0, "Unexpected message");
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
k_sem_give(&link_remote->rdy_sem);
|
||||
}
|
||||
|
||||
static int getter_msg_process(struct log_multidomain_link *link_remote,
|
||||
struct log_multidomain_msg *msg, size_t msg_size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = link_remote->transport_api->send(link_remote, msg, msg_size);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = k_sem_take(&link_remote->rdy_sem, K_MSEC(1000));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return (link_remote->status == Z_LOG_MULTIDOMAIN_STATUS_OK) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int link_remote_get_domain_count(struct log_multidomain_link *link_remote,
|
||||
uint16_t *cnt)
|
||||
{
|
||||
int err;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_CNT,
|
||||
};
|
||||
|
||||
err = getter_msg_process(link_remote, &msg, sizeof(msg));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*cnt = link_remote->dst.count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_remote_get_source_count(struct log_multidomain_link *link_remote,
|
||||
uint32_t domain_id,
|
||||
uint16_t *cnt)
|
||||
{
|
||||
int err;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_CNT,
|
||||
.data = { .source_cnt = { .domain_id = domain_id } }
|
||||
};
|
||||
|
||||
err = getter_msg_process(link_remote, &msg, sizeof(msg));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*cnt = link_remote->dst.count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_remote_ready(struct log_multidomain_link *link_remote)
|
||||
{
|
||||
int err;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_READY
|
||||
};
|
||||
|
||||
err = getter_msg_process(link_remote, &msg, sizeof(msg));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_remote_initiate(const struct log_link *link,
|
||||
struct log_link_config *config)
|
||||
{
|
||||
struct log_multidomain_link *link_remote = link->ctx;
|
||||
|
||||
link_remote->link = link;
|
||||
k_sem_init(&link_remote->rdy_sem, 0, 1);
|
||||
|
||||
return link_remote->transport_api->init(link_remote);
|
||||
}
|
||||
|
||||
static int link_remote_activate(const struct log_link *link)
|
||||
{
|
||||
struct log_multidomain_link *link_remote = link->ctx;
|
||||
int err;
|
||||
|
||||
if (!link_remote->ready) {
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
if (link_remote->status != 0) {
|
||||
return link_remote->status;
|
||||
}
|
||||
|
||||
uint16_t cnt;
|
||||
|
||||
err = link_remote_get_domain_count(link_remote, &cnt);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (cnt > ARRAY_SIZE(link->ctrl_blk->source_cnt)) {
|
||||
__ASSERT(0, "Number of domains not supported.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
link->ctrl_blk->domain_cnt = cnt;
|
||||
for (int i = 0; i < link->ctrl_blk->domain_cnt; i++) {
|
||||
err = link_remote_get_source_count(link_remote, i, &cnt);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
link->ctrl_blk->source_cnt[i] = cnt;
|
||||
}
|
||||
|
||||
err = link_remote_ready(link_remote);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int link_remote_get_domain_name(const struct log_link *link,
|
||||
uint32_t domain_id,
|
||||
char *name, uint32_t *length)
|
||||
{
|
||||
struct log_multidomain_link *link_remote = link->ctx;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME,
|
||||
.data = { .domain_name = { .domain_id = domain_id } }
|
||||
};
|
||||
int err;
|
||||
|
||||
|
||||
link_remote->dst.name.dst = name;
|
||||
link_remote->dst.name.len = length;
|
||||
|
||||
err = getter_msg_process(link_remote, &msg, sizeof(msg));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_remote_get_source_name(const struct log_link *link,
|
||||
uint32_t domain_id, uint16_t source_id,
|
||||
char *name, size_t *length)
|
||||
{
|
||||
struct log_multidomain_link *link_remote = link->ctx;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME,
|
||||
.data = {
|
||||
.source_name = {
|
||||
.domain_id = domain_id,
|
||||
.source_id = source_id
|
||||
}
|
||||
}
|
||||
};
|
||||
int err;
|
||||
|
||||
link_remote->dst.name.dst = name;
|
||||
link_remote->dst.name.len = length;
|
||||
|
||||
err = getter_msg_process(link_remote, &msg, sizeof(msg));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_remote_get_levels(const struct log_link *link,
|
||||
uint32_t domain_id, uint16_t source_id,
|
||||
uint8_t *level, uint8_t *runtime_level)
|
||||
{
|
||||
struct log_multidomain_link *link_remote = link->ctx;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_GET_LEVELS,
|
||||
.data = {
|
||||
.levels = {
|
||||
.domain_id = domain_id,
|
||||
.source_id = source_id
|
||||
}
|
||||
}
|
||||
};
|
||||
int err;
|
||||
|
||||
err = getter_msg_process(link_remote, &msg, sizeof(msg));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (level) {
|
||||
*level = link_remote->dst.levels.level;
|
||||
}
|
||||
if (runtime_level) {
|
||||
*runtime_level = link_remote->dst.levels.runtime_level;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_remote_set_runtime_level(const struct log_link *link,
|
||||
uint32_t domain_id, uint16_t source_id,
|
||||
uint8_t level)
|
||||
{
|
||||
struct log_multidomain_link *link_remote = link->ctx;
|
||||
struct log_multidomain_msg msg = {
|
||||
.id = Z_LOG_MULTIDOMAIN_ID_SET_RUNTIME_LEVEL,
|
||||
.data = {
|
||||
.set_rt_level = {
|
||||
.domain_id = domain_id,
|
||||
.source_id = source_id,
|
||||
.runtime_level = level
|
||||
}
|
||||
}
|
||||
};
|
||||
int err;
|
||||
|
||||
err = getter_msg_process(link_remote, &msg, sizeof(msg));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct log_link_api log_multidomain_link_api = {
|
||||
.initiate = link_remote_initiate,
|
||||
.activate = link_remote_activate,
|
||||
.get_domain_name = link_remote_get_domain_name,
|
||||
.get_source_name = link_remote_get_source_name,
|
||||
.get_levels = link_remote_get_levels,
|
||||
.set_runtime_level = link_remote_set_runtime_level
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue