Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ target_sources(app PRIVATE src/sm_at_icmp.c)
target_sources(app PRIVATE src/sm_at_fota.c)
target_sources(app PRIVATE src/sm_at_dfu.c)
target_sources(app PRIVATE src/sm_uart_handler.c)
target_sources(app PRIVATE src/sm_log.c)
# NORDIC SDK APP END
target_sources_ifdef(CONFIG_SM_SMS app PRIVATE src/sm_at_sms.c)
target_sources_ifdef(CONFIG_SM_PPP app PRIVATE src/sm_ppp.c)
Expand Down
9 changes: 9 additions & 0 deletions app/boards/nrf9151dk_nrf9151_ns.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
chosen {
ncs,sm-uart = &dtr_uart0;
nordic,pm-ext-flash = &gd25wb256;
zephyr,console = &uart1;
};
};

Expand Down Expand Up @@ -69,3 +70,11 @@
&i2c2 {
status = "disabled";
};

/* Enable UART1 as the shared backend for Zephyr logs and modem traces (VCOM1 on the DK).
* Modem traces require 1 000 000 baud. Hardware flow control is not used.
*/
&uart1 {
status = "okay";
current-speed = <1000000>;
};
9 changes: 9 additions & 0 deletions app/boards/thingy91x_nrf9151_ns.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/ {
chosen {
ncs,sm-uart = &dtr_uart0;
zephyr,console = &uart1;
};
};

Expand All @@ -27,3 +28,11 @@
/* Use PORT event for DTR (26) pin to save power */
sense-edge-mask = <BIT(26)>;
};

/* Enable UART1 as the shared backend for Zephyr logs and modem traces.
* Modem traces require 1 000 000 baud. Hardware flow control is not used.
*/
&uart1 {
status = "okay";
current-speed = <1000000>;
};
8 changes: 0 additions & 8 deletions app/overlay-trace-backend-uart.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable UART logging backend - shared with nRF modem traces.
CONFIG_UART_CONSOLE=y
CONFIG_RTT_CONSOLE=n
CONFIG_LOG_BACKEND_RTT=n
# Log backend starts disabled; the UART is off until activated via AT#XLOG=1.
CONFIG_LOG_BACKEND_UART=y
CONFIG_LOG_BACKEND_UART_AUTOSTART=n

# Enable UART modem trace backend - shared with the UART log backend.
CONFIG_SM_MODEM_TRACE_BACKEND_UART=y
CONFIG_NRF_MODEM_LIB_TRACE=y
Expand Down
14 changes: 0 additions & 14 deletions app/overlay-trace-backend-uart.overlay

This file was deleted.

27 changes: 13 additions & 14 deletions app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,19 @@ CONFIG_RING_BUFFER=y
CONFIG_REBOOT=y
CONFIG_EVENTFD=y

# Segger RTT
CONFIG_USE_SEGGER_RTT=y
# Where console messages (printk) are output.
# By itself, SM does not output any.
CONFIG_RTT_CONSOLE=y
CONFIG_UART_CONSOLE=n
# Where logs are output.
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n
# Increase the buffer so that all Serial Modem boot logs fit into the buffer.
# Because J-Link RTT Viewer has to be connected after the bootup,
# only logs that fit into the buffer are shown. This is especially useful in showing
# errors if Serial Modem does not start properly.
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=2048
# Enable UART logging by default.
CONFIG_UART_CONSOLE=y
CONFIG_LOG_BACKEND_UART=y
# Logging does not start until activated via AT#XLOG=1 and is deactivated with AT#XLOG=0.
CONFIG_LOG_BACKEND_UART_AUTOSTART=n

# Disable Segger RTT logging by default.
CONFIG_USE_SEGGER_RTT=n
CONFIG_RTT_CONSOLE=n
CONFIG_LOG_BACKEND_RTT=n
# Optional: when RTT logging is enabled, increase the RTT buffer so that
# all Serial Modem boot logs fit into the buffer.
#CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=2048

# Network
CONFIG_NETWORKING=y
Expand Down
2 changes: 1 addition & 1 deletion app/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ tests:
build_only: true
extra_args:
- EXTRA_CONF_FILE="overlay-cmux.conf;overlay-ppp.conf;overlay-trace-backend-uart.conf;overlay-nrf-device-provisioning.conf"
- EXTRA_DTC_OVERLAY_FILE="overlay-nrf91m1.overlay;overlay-trace-backend-uart.overlay"
- EXTRA_DTC_OVERLAY_FILE="overlay-nrf91m1.overlay"
extra_configs:
- CONFIG_SM_LOG_LEVEL_DBG=y
platform_allow:
Expand Down
146 changes: 146 additions & 0 deletions app/src/sm_log.c
Comment thread
MarkusLassila marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright (c) 2026 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/*
* AT#XLOG command — enable/disable the Zephyr UART log backend at runtime.
*
* The UART (zephyr,console) is shared with the modem-trace backend
* (sm_trace_backend_uart.c). AT#XLOG and AT#XTRACE are mutually exclusive:
* each refuses to activate while the other is in use.
*
*/

#include <zephyr/devicetree.h>

/* Only compiled if zephyr,console is present and active in the devicetree. */
#if DT_HAS_CHOSEN(zephyr_console) && DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_console), okay)

#include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/logging/log_ctrl.h>
#include <zephyr/pm/device.h>

#include "sm_at_host.h"

LOG_MODULE_REGISTER(sm_log, CONFIG_SM_LOG_LEVEL);

/* Zephyr console UART is used both for application logs and modem traces. */
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_console)
static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE);

static bool log_active;

static int uart_suspend(void)
{
int ret = pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND);

if (ret && ret != -EALREADY) {
LOG_ERR("Failed to %s UART device: %d", "suspend", ret);
return ret;
}

return 0;
}

static int uart_resume(void)
{
int ret = pm_device_action_run(uart_dev, PM_DEVICE_ACTION_RESUME);

if (ret && ret != -EALREADY) {
LOG_ERR("Failed to %s UART device: %d", "resume", ret);
return ret;
}
return 0;
}

static bool uart_is_active(void)
{
enum pm_device_state state = PM_DEVICE_STATE_OFF;
int err = pm_device_state_get(uart_dev, &state);

if (err) {
LOG_ERR("Failed to get UART device state (%d).", err);
return false;
}
return state == PM_DEVICE_STATE_ACTIVE;
}

SM_AT_CMD_CUSTOM(xlog, "AT#XLOG", handle_at_log);
STATIC int handle_at_log(enum at_parser_cmd_type cmd_type, struct at_parser *parser, uint32_t)
{
const struct log_backend *log_be = log_backend_get_by_name("log_backend_uart");

if (!log_be) {
return -ENODEV;
}

if (cmd_type == AT_PARSER_CMD_TYPE_SET) {
int mode;
int ret = at_parser_num_get(parser, 1, &mode);

if (ret || (mode < 0) || (mode > 1)) {
return -EINVAL;
}

if (mode == (int)log_active) {
return 0;
}

if (mode == 1 && uart_is_active()) {
return -EBUSY;
}

if (mode == 1) {
ret = uart_resume();
if (ret) {
return ret;
}
if (!log_be->cb->initialized) {
log_backend_init(log_be);
}
log_backend_enable(log_be, log_be->cb->ctx, CONFIG_LOG_DEFAULT_LEVEL);
log_active = true;
} else {
log_backend_disable(log_be);
ret = uart_suspend();
if (ret) {
return ret;
}
log_active = false;
}
return 0;
} else if (cmd_type == AT_PARSER_CMD_TYPE_READ) {
rsp_send("\r\n#XLOG: %d\r\n", (int)log_active);
return 0;
} else if (cmd_type == AT_PARSER_CMD_TYPE_TEST) {
rsp_send("\r\n#XLOG: (0,1)\r\n");
return 0;
}

return -EINVAL;
}

static int sm_log_init(void)
{
if (!IS_ENABLED(CONFIG_LOG_BACKEND_UART) ||
!IS_ENABLED(CONFIG_LOG_BACKEND_UART_AUTOSTART)) {
/* Start with UART log backend disabled. */
if (uart_suspend()) {
LOG_ERR("Failed to suspend UART log backend");
sm_init_failed = true;
return -EFAULT;
Comment on lines +129 to +135
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intended. If customer changes to RTT-traces, they do not need to disable the UART from the DTS, although they are free to do so.

}
} else {
log_active = true;
}

return 0;
}

SYS_INIT(sm_log_init, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY);

#endif /* DT_HAS_CHOSEN(zephyr_console) */
Loading
Loading