Skip to content

Commit

Permalink
lib: nrf_modem: trace: add shell command
Browse files Browse the repository at this point in the history
Move modem_trace command from modem_shell sample to nrf_modem_lib. Can
be used in any application or sample that have CONFIG_SHELL and
CONFIG_NRF_MODEM_LIB_TRACE enabled.

The send to memfault command was removed as it doesn't belong in the
nrf modem library. The dump to UART command was added to demonstrate
reading of the modem traces.

The introduction of snippets in Zephyr also allowed a clean-up of
Kconfig and device-tree overlays.

Enable the modem_trace shell command using
CONFIG_NRF_MODEM_LIB_SHELL_TRACE=y

Signed-off-by: Gregers Gram Rygg <gregers.gram.rygg@nordicsemi.no>
  • Loading branch information
gregersrygg authored and rlubos committed Feb 20, 2024
1 parent 7d209a5 commit ecf2c9b
Show file tree
Hide file tree
Showing 23 changed files with 396 additions and 372 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ Kconfig* @tejlmand
/scripts/print_toolchain_checksum.sh @nrfconnect/ncs-ci
/share/zephyrbuild-package/ @tejlmand
/share/ncs-package/ @tejlmand
/snippets/nrf91-modem-trace-ext-flash/ @nrfconnect/ncs-cia
/snippets/nrf91-modem-trace-uart/ @eivindj-nordic
/snippets/tfm-enable-share-uart/ @nrfconnect/ncs-cia
/snippets/nrf70-debug/ @krish2718 @sachinthegreen
Expand Down
24 changes: 23 additions & 1 deletion doc/nrf/device_guides/working_with_nrf/nrf91/nrf91_snippet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,33 @@ Snippets for an nRF91 Series device


:ref:`snippets` are tailored for tracing on the nRF91 Series devices but can work with other boards as well.
In |NCS|, snippets are used for the following functionalities:
On nRF91 Series devices, snippets are used for the following functionalities:

* Modem tracing with the flash backend
* Modem tracing with the UART backend
* To activate TF-M logging while having modem traces enabled

.. _nrf91_modem_trace_ext_flash_snippet:

nRF91 modem traces with flash backend using snippets
====================================================

Snippet enables modem tracing, the flash backend, and external flash and configures them to store modem traces to a dedicated partition on the external flash for supported boards.
To change the partition size, the project needs to configure the :kconfig:option:`CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_FLASH_PARTITION_SIZE` Kconfig option.

The following build targets have support for this snippet:

* ``nrf9161dk_nrf9161_ns``
* ``nrf9160dk_nrf9160_ns``
* ``nrf9131ek_nrf9131_ns``

To enable modem traces with the flash backend, use the following command:

.. parsed-literal::
:class: highlight
west build --board *build target* -S nrf91-modem-trace-ext-flash
.. _nrf91_modem_trace_uart_snippet:

nRF91 modem tracing with UART backend using snippets
Expand Down
46 changes: 45 additions & 1 deletion doc/nrf/libraries/modem/nrf_modem_lib/nrf_modem_lib_trace.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ The modem trace flash backend has some additional configuration options:

* :kconfig:option:`CONFIG_FCB` - Required for the flash circular buffer used in the backend.
* :kconfig:option:`CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_FLASH_PARTITION_SIZE` - Defines the space to be used for the modem trace partition.
The external flash size on the nRF9160 DK is 8 MB (equal to ``0x800000`` in HEX).
In order to improve the modem trace write performance, this partition is erased during system boot.
This might lead to a significant increase in the boot time on the nRF9160 DK.
The external flash size on the nRF9160 DK is 8 MB (equal to ``0x800000`` in HEX) and 32 MB on the nRF9161 DK (equal to ``0x2000000`` in HEX).

It is also recommended to enable high drive mode and high-performance mode in devicetree.
High drive is to ensure that the communication with the flash device is reliable at high speed.
Expand Down Expand Up @@ -316,3 +318,45 @@ Complete the following steps to add a custom trace backend:
CONFIG_NRF_MODEM_LIB_TRACE=y
CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_MY_TRACE_BACKEND=y
.. _modem_trace_shell_command:

Modem trace shell command
*************************

Shell command: ``modem_trace``

You can use the modem trace commands to control the trace functionality in the modem when the :kconfig:option:`CONFIG_NRF_MODEM_LIB_SHELL_TRACE` Kconfig option is enabled.
A trace backend that can store modem traces is required to send modem traces to the cloud.
The ``modem_trace dump_uart`` command is a simple demonstration of how trace data can be read out from storage using the :c:func:`nrf_modem_lib_trace_read` function.

Be aware that the default trace level is :kconfig:option:`CONFIG_NRF_MODEM_LIB_TRACE_LEVEL_FULL` and starts modem traces during system boot automatically.
In case you want to start modem tracing using shell commands instead, set the :kconfig:option:`CONFIG_NRF_MODEM_LIB_TRACE_LEVEL_OFF` Kconfig option to ``y``.

Following are some examples of modem tracing:

* To trace everything (LTE, IP, and GNSS):

.. code-block:: console
modem_trace start full
<use the modem by triggering functionality in the app or use at-commands>
modem_trace stop
* To read out the size of stored modem traces:

.. code-block:: console
modem_trace size
* To read out stored traces and send over UART:

.. code-block:: console
modem_trace dump_uart
* To delete all stored modem traces:

.. code-block:: console
modem_trace clear
14 changes: 11 additions & 3 deletions doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,10 @@ Cellular samples
* Support for PDN CID 0 in the ``-I`` argument for the ``sock connect`` command.
* Support for listing interface addresses using the ``link ifaddrs`` command.

* Removed the nRF7002 EK devicetree overlay file :file:`nrf91xxdk_with_nrf7002ek.overlay`, because UART1 is disabled through the shield configuration.
* Removed:

* The nRF7002 EK devicetree overlay file :file:`nrf91xxdk_with_nrf7002ek.overlay`, because UART1 is disabled through the shield configuration.
* The ``modem_trace send memfault`` shell command.

* Updated:

Expand All @@ -408,6 +411,8 @@ Cellular samples
The ``rai_no_data`` option requires the socket to be connected and have a peer address set.
This bug is caused by the non-secure datagram socket not being connected when using the ``connect`` subcommand.
* The ``send`` subcommand to use the :c:func:`send` function for non-secure datagram sockets that are connected and have a peer address set.
* The ``modem_trace`` command has been moved to :ref:`nrf_modem_lib_readme`.
See :ref:`modem_trace_shell_command` for information about modem trace commands.

* :ref:`nrf_cloud_multi_service` sample:

Expand Down Expand Up @@ -799,9 +804,12 @@ Modem libraries
* A mention about enabling TF-M logging while using modem traces in the :ref:`modem_trace_module`.
* The :kconfig:option:`CONFIG_NRF_MODEM_LIB_NET_IF_DOWN_DEFAULT_LTE_DISCONNECT` option, allowing the user to change the behavior of the driver's :c:func:`net_if_down` implementation at build time.

* Updated by renaming ``lte_connectivity`` module to ``lte_net_if``.
* Updated:

* The library by renaming ``lte_connectivity`` module to ``lte_net_if``.
All related Kconfig options have been renamed accordingly.
* Changed the default value of the :kconfig:option:`CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START`, :kconfig:option:`CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT`, and :kconfig:option:`CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_DOWN` Kconfig options from enabled to disabled.
* The default value of the :kconfig:option:`CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START`, :kconfig:option:`CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT`, and :kconfig:option:`CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_DOWN` Kconfig options from enabled to disabled.
* The modem trace shell command implementation is moved from :ref:`modem_shell_application` sample into :ref:`nrf_modem_lib_readme` to be used by any application with the :kconfig:option:`CONFIG_NRF_MODEM_LIB_SHELL_TRACE` option enabled.

* Fixed:

Expand Down
1 change: 1 addition & 0 deletions lib/nrf_modem_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS nrf91_sockets.c)
zephyr_library_include_directories_ifdef(CONFIG_NET_SOCKETS ${ZEPHYR_BASE}/subsys/net/lib/sockets)

add_subdirectory_ifdef(CONFIG_NRF_MODEM_LIB_NET_IF lte_net_if)
add_subdirectory_ifdef(CONFIG_SHELL shell)

if(CONFIG_NRF_MODEM_LIB_TRACE)
zephyr_library_sources(nrf_modem_lib_trace.c)
Expand Down
1 change: 1 addition & 0 deletions lib/nrf_modem_lib/Kconfig.modemlib
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ config NRF_MODEM_LIB_FAULT_STRERROR
The description can be retrieved with nrf_modem_lib_fault_strerror().

rsource "lte_net_if/Kconfig"
rsource "shell/Kconfig"

DT_IPC := $(dt_nodelabel_path,ipc)
config NRF_MODEM_LIB_IPC_IRQ_PRIO
Expand Down
7 changes: 7 additions & 0 deletions lib/nrf_modem_lib/shell/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

zephyr_library_sources_ifdef(CONFIG_NRF_MODEM_LIB_SHELL_TRACE trace.c)
20 changes: 20 additions & 0 deletions lib/nrf_modem_lib/shell/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

menu "Shell"

config NRF_MODEM_LIB_SHELL_TRACE
bool "Modem trace shell commands"

if NRF_MODEM_LIB_SHELL_TRACE

DT_CHOSEN_NORDIC_MODEM_TRACE_UART := nordic,modem-trace-uart
config NRF_MODEM_LIB_SHELL_TRACE_UART
bool
default $(dt_chosen_enabled,$(DT_CHOSEN_NORDIC_MODEM_TRACE_UART))

endif # NRF_MODEM_LIB_SHELL_TRACE

endmenu
188 changes: 188 additions & 0 deletions lib/nrf_modem_lib/shell/trace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/kernel.h>
#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <modem/nrf_modem_lib_trace.h>

#ifdef CONFIG_NRF_MODEM_LIB_SHELL_TRACE_UART

#include <stdint.h>
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>

#define UART_DEVICE_NODE DT_CHOSEN(nordic_modem_trace_uart)
#define READ_BUF_SIZE 256

#endif /* CONFIG_NRF_MODEM_LIB_SHELL_TRACE_UART */

static int modem_trace_start(const struct shell *sh, enum nrf_modem_lib_trace_level trace_level)
{
int err;

shell_print(sh, "Starting modem traces with trace level: %d", trace_level);

err = nrf_modem_lib_trace_level_set(trace_level);
if (err) {
shell_error(sh, "Failed to enable modem traces, error: %d", err);
return err;
}

return 0;
}

static int modem_trace_stop(const struct shell *sh, size_t argc, char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
int err;

err = nrf_modem_lib_trace_level_set(NRF_MODEM_LIB_TRACE_LEVEL_OFF);
if (err) {
shell_error(sh, "Failed to turn off modem traces, error: %d", err);
return err;
}

shell_print(sh, "Modem trace stop command issued. This may produce a few more traces. "
"Please wait at least 1 second before attempting to read out trace data.");

return 0;
}

static void modem_trace_clear(const struct shell *sh, size_t argc, char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
int err;

shell_print(sh, "Clearing modem traces");

err = nrf_modem_lib_trace_clear();
if (err == -ENOTSUP) {
shell_error(sh, "The current modem trace backend does not support this operation");
} else if (err) {
shell_error(sh, "Failed to clear modem traces: %d", err);
}
}

static void modem_trace_size(const struct shell *sh, size_t argc, char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
int ret;

ret = nrf_modem_lib_trace_data_size();
if (ret == -ENOTSUP) {
shell_error(sh, "The current modem trace backend does not support this operation");
} else if (ret < 0) {
shell_error(sh, "Failed to get modem traces size: %d", ret);
} else {
shell_print(sh, "Modem trace data size: %d bytes", ret);
}
}

#ifdef CONFIG_NRF_MODEM_LIB_SHELL_TRACE_UART

static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE);

static void print_uart(const struct shell *sh, char *buf, int len)
{
if (!device_is_ready(uart_dev)) {
shell_error(sh, "uart device not found/ready!");
return;
}

for (int i = 0; i < len; i++) {
uart_poll_out(uart_dev, buf[i]);
}
}

void modem_trace_uart_send(const struct shell *sh, size_t size)
{
static uint8_t read_buf[READ_BUF_SIZE];
int ret = 1;
size_t read_offset = 0;

shell_print(sh, "Reading out %d bytes of trace data", size);
/* Read out the trace data from flash */
while (ret > 0) {
ret = nrf_modem_lib_trace_read(read_buf, READ_BUF_SIZE);
if (ret == 0 || ret == -ENODATA) {
break;
} else if (ret < 0) {
shell_error(sh, "Error reading modem traces: %d", ret);
break;
}
read_offset += ret;
print_uart(sh, read_buf, ret);
}
shell_print(sh, "Total trace bytes read from flash: %d", read_offset);
}

#endif /* CONFIG_NRF_MODEM_LIB_SHELL_TRACE_UART */

static void modem_trace_dump_uart(const struct shell *sh, size_t argc, char **argv, void *data)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
ARG_UNUSED(data);

if (IS_ENABLED(CONFIG_NRF_MODEM_LIB_SHELL_TRACE_UART)) {
size_t size = nrf_modem_lib_trace_data_size();

if (size == -ENOTSUP) {
shell_error(sh,
"The current modem trace backend does not support this operation");
return;
} else if (size < 0) {
shell_error(sh, "Failed to get modem traces size: %d", size);
return;
} else if (size == 0) {
shell_error(sh, "No data to send");
return;
}

modem_trace_uart_send(sh, size);
} else {
shell_error(sh, "Missing chosen node for nordic,modem-trace-uart. "
"Please configure which uart to use.");
}
}

static int modem_trace_shell_start(const struct shell *sh, size_t argc, char **argv, void *data)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
enum nrf_modem_lib_trace_level level = (enum nrf_modem_lib_trace_level)data;

return modem_trace_start(sh, level);
}

SHELL_SUBCMD_DICT_SET_CREATE(start_cmd, modem_trace_shell_start,
(full, 2, "Full"),
(coredump_only, 1, "Coredump only"),
(ip_only, 4, "IP only"),
(lte_and_ip, 5, "LTE and IP")
);

SHELL_STATIC_SUBCMD_SET_CREATE(modem_trace_cmd,
SHELL_CMD(start, &start_cmd,
"Start modem tracing.", NULL),
SHELL_CMD(stop, NULL,
"Stop modem tracing.", modem_trace_stop),
SHELL_CMD(clear, NULL,
"Clear captured trace data and prepare the backend for capturing new traces.\n"
"This operation is only supported with some trace backends.", modem_trace_clear),
SHELL_CMD(size, NULL,
"Read out the size of stored modem traces.\n"
"This operation is only supported with some trace backends.", modem_trace_size),
SHELL_CMD(dump_uart, NULL,
"Dump stored traces to UART.", modem_trace_dump_uart),
SHELL_SUBCMD_SET_END);

SHELL_CMD_REGISTER(modem_trace, &modem_trace_cmd,
"Commands for controlling modem trace functionality.", NULL);
1 change: 0 additions & 1 deletion samples/cellular/modem_shell/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ add_subdirectory_ifdef(CONFIG_MOSH_FOTA src/fota)
add_subdirectory_ifdef(CONFIG_MOSH_REST src/rest)
add_subdirectory_ifdef(CONFIG_MOSH_STARTUP_CMDS src/startup_cmd)
add_subdirectory_ifdef(CONFIG_MOSH_GPIO_COUNT src/gpio_count)
add_subdirectory_ifdef(CONFIG_NRF_MODEM_LIB_TRACE src/modem_trace)
add_subdirectory(src/cloud)

if(NOT ENV{PROJECT_NAME})
Expand Down
Loading

0 comments on commit ecf2c9b

Please sign in to comment.