169 lines
4.3 KiB
C
169 lines
4.3 KiB
C
/*
|
|
* Copyright (c) 2020 Nordic Semiconductor
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/syscall_handler.h>
|
|
#include <zephyr/logging/log_internal.h>
|
|
#include <zephyr/logging/log_ctrl.h>
|
|
#include <zephyr/logging/log_frontend.h>
|
|
#include <zephyr/logging/log_backend.h>
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(log);
|
|
|
|
BUILD_ASSERT(sizeof(struct log_msg_desc) == sizeof(uint32_t),
|
|
"Descriptor must fit in 32 bits");
|
|
|
|
/* Returns true if any backend is in use. */
|
|
#define BACKENDS_IN_USE() \
|
|
!(IS_ENABLED(CONFIG_LOG_FRONTEND) && \
|
|
(IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY) || log_backend_count_get() == 0))
|
|
|
|
void z_log_msg_finalize(struct log_msg *msg, const void *source,
|
|
const struct log_msg_desc desc, const void *data)
|
|
{
|
|
if (!msg) {
|
|
z_log_dropped(false);
|
|
|
|
return;
|
|
}
|
|
|
|
if (data) {
|
|
uint8_t *d = msg->data + desc.package_len;
|
|
|
|
memcpy(d, data, desc.data_len);
|
|
}
|
|
|
|
msg->hdr.desc = desc;
|
|
msg->hdr.source = source;
|
|
#if CONFIG_LOG_THREAD_ID_PREFIX
|
|
msg->hdr.tid = k_is_in_isr() ? NULL : k_current_get();
|
|
#endif
|
|
z_log_msg_commit(msg);
|
|
}
|
|
|
|
void z_impl_z_log_msg_static_create(const void *source,
|
|
const struct log_msg_desc desc,
|
|
uint8_t *package, const void *data)
|
|
{
|
|
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
|
log_frontend_msg(source, desc, package, data);
|
|
}
|
|
|
|
if (!BACKENDS_IN_USE()) {
|
|
return;
|
|
}
|
|
|
|
struct log_msg_desc out_desc = desc;
|
|
int inlen = desc.package_len;
|
|
struct log_msg *msg;
|
|
|
|
if (inlen > 0) {
|
|
uint32_t flags = CBPRINTF_PACKAGE_CONVERT_RW_STR |
|
|
CBPRINTF_PACKAGE_CONVERT_PTR_CHECK;
|
|
uint16_t strl[4];
|
|
int len;
|
|
|
|
len = cbprintf_package_copy(package, inlen,
|
|
NULL, 0, flags,
|
|
strl, ARRAY_SIZE(strl));
|
|
|
|
if (len > Z_LOG_MSG_MAX_PACKAGE) {
|
|
struct cbprintf_package_hdr_ext *pkg =
|
|
(struct cbprintf_package_hdr_ext *)package;
|
|
|
|
LOG_WRN("Message (\"%s\") dropped because it exceeds size limitation (%u)",
|
|
pkg->fmt, (uint32_t)Z_LOG_MSG_MAX_PACKAGE);
|
|
return;
|
|
}
|
|
/* Update package length with calculated value (which may be extended
|
|
* when strings are copied into the package.
|
|
*/
|
|
out_desc.package_len = len;
|
|
msg = z_log_msg_alloc(log_msg_get_total_wlen(out_desc));
|
|
if (msg) {
|
|
len = cbprintf_package_copy(package, inlen,
|
|
msg->data, out_desc.package_len,
|
|
flags, strl, ARRAY_SIZE(strl));
|
|
__ASSERT_NO_MSG(len >= 0);
|
|
}
|
|
} else {
|
|
msg = z_log_msg_alloc(log_msg_get_total_wlen(out_desc));
|
|
}
|
|
|
|
z_log_msg_finalize(msg, source, out_desc, data);
|
|
}
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
static inline void z_vrfy_z_log_msg_static_create(const void *source,
|
|
const struct log_msg_desc desc,
|
|
uint8_t *package, const void *data)
|
|
{
|
|
return z_impl_z_log_msg_static_create(source, desc, package, data);
|
|
}
|
|
#include <syscalls/z_log_msg_static_create_mrsh.c>
|
|
#endif
|
|
|
|
void z_impl_z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source,
|
|
uint8_t level, const void *data, size_t dlen,
|
|
uint32_t package_flags, const char *fmt, va_list ap)
|
|
{
|
|
int plen;
|
|
|
|
if (fmt) {
|
|
va_list ap2;
|
|
|
|
va_copy(ap2, ap);
|
|
plen = cbvprintf_package(NULL, Z_LOG_MSG_ALIGN_OFFSET,
|
|
package_flags, fmt, ap2);
|
|
__ASSERT_NO_MSG(plen >= 0);
|
|
va_end(ap2);
|
|
} else {
|
|
plen = 0;
|
|
}
|
|
|
|
size_t msg_wlen = Z_LOG_MSG_ALIGNED_WLEN(plen, dlen);
|
|
struct log_msg *msg;
|
|
uint8_t *pkg;
|
|
struct log_msg_desc desc =
|
|
Z_LOG_MSG_DESC_INITIALIZER(domain_id, level, plen, dlen);
|
|
|
|
if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED) && BACKENDS_IN_USE()) {
|
|
msg = z_log_msg_alloc(msg_wlen);
|
|
if (IS_ENABLED(CONFIG_LOG_FRONTEND) && msg == NULL) {
|
|
pkg = alloca(plen);
|
|
} else {
|
|
pkg = msg ? msg->data : NULL;
|
|
}
|
|
} else {
|
|
msg = alloca(msg_wlen * sizeof(int));
|
|
pkg = msg->data;
|
|
}
|
|
|
|
if (pkg && fmt) {
|
|
plen = cbvprintf_package(pkg, (size_t)plen, package_flags, fmt, ap);
|
|
__ASSERT_NO_MSG(plen >= 0);
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
|
log_frontend_msg(source, desc, pkg, data);
|
|
}
|
|
|
|
if (BACKENDS_IN_USE()) {
|
|
z_log_msg_finalize(msg, source, desc, data);
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
static inline void z_vrfy_z_log_msg_runtime_vcreate(uint8_t domain_id,
|
|
const void *source,
|
|
uint8_t level, const void *data, size_t dlen,
|
|
uint32_t package_flags, const char *fmt, va_list ap)
|
|
{
|
|
return z_impl_z_log_msg_runtime_vcreate(domain_id, source, level, data,
|
|
dlen, package_flags, fmt, ap);
|
|
}
|
|
#include <syscalls/z_log_msg_runtime_vcreate_mrsh.c>
|
|
#endif
|