Skip to content

drivers: modem: Add nRF91x SLM Socket Offloaded driver #91601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

wilkinsw
Copy link
Contributor

@wilkinsw wilkinsw commented Jun 13, 2025

This is a socket offloaded modem driver for the nRF91 Serial LTE Modem. The driver structure is based on Bjarki's modem_cellular driver and uses the modem chat interface.

For clarity the driver is broken into multiple files. These can be merged in to one file during final rebase/squash if desired.

  1. nrf91_slm.c contains the state machine and events. It is a lightly modified version of Bjark's cellular_modem driver to disable PPP (if enabled).
  2. nrf91_slm_dns.c contains the socket_dns_offload functions.
  3. nrf91_slm_socket.c contains the socket_op_vtable functions.

Right now the driver only supports a single modem and TCP sockets (XSEND and XRECV). I have tested it mostly using MQTT.

Areas for future development:

  • Support more than one driver instance.
  • Support more than one socket per driver instance.
  • Support UDP (XRECVFROM and XSENDTO).
  • Support GNSS

Testing details for the mqtt_publisher sample are here: #91601 (comment)

@wilkinsw
Copy link
Contributor Author

@MarkusLassila you asked to be tagged for this draft PR

@wilkinsw wilkinsw force-pushed the feature/modem-nrf91-slm branch 2 times, most recently from a754256 to fbc525d Compare June 13, 2025 21:15
@wilkinsw wilkinsw force-pushed the feature/modem-nrf91-slm branch 5 times, most recently from 0532468 to 90159c3 Compare July 9, 2025 23:36
@wilkinsw wilkinsw marked this pull request as ready for review July 10, 2025 00:17
@wilkinsw wilkinsw force-pushed the feature/modem-nrf91-slm branch from 90159c3 to 3999046 Compare July 11, 2025 00:26
@wilkinsw
Copy link
Contributor Author

wilkinsw commented Jul 11, 2025

My testing was done with samples/net/mqtt_publisher on an NXP LPC5516.

In config.h I set SERVER_ADDR to the address of my server running mosquitto -v

I applied the following patch to wait for registration. (because wait_for_network requires NET_NATIVE)

diff --git a/samples/net/mqtt_publisher/src/main.c b/samples/net/mqtt_publisher/src/main.c
index 03050685b41..3d14ffb8644 100644
--- a/samples/net/mqtt_publisher/src/main.c
+++ b/samples/net/mqtt_publisher/src/main.c
@@ -563,9 +563,45 @@ K_THREAD_DEFINE(app_thread, STACK_SIZE,
 static K_HEAP_DEFINE(app_mem_pool, 1024 * 2);
 #endif
 
+#include <zephyr/device.h>
+#include <zephyr/pm/device.h>
+#include <zephyr/pm/device_runtime.h>
+#include <zephyr/drivers/cellular.h>
+
+static bool modem_registered(const struct device *modem)
+{
+    enum cellular_registration_status status;
+
+    int ret = cellular_get_registration_status(
+            modem, CELLULAR_ACCESS_TECHNOLOGY_LTE, &status);
+
+    if (ret < 0) {
+        return false;
+    }
+
+    return (status == CELLULAR_REGISTRATION_REGISTERED_HOME
+        || status == CELLULAR_REGISTRATION_REGISTERED_ROAMING);
+}
+
 int main(void)
 {
-	wait_for_network();
+	const struct device *modem = DEVICE_DT_GET(DT_ALIAS(modem));
+    struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(OFFLOADED_NETDEV));
+
+    LOG_INF("powering on modem");
+    pm_device_action_run(modem, PM_DEVICE_ACTION_RESUME);
+
+    LOG_INF("bring up network interface");
+    if (net_if_up(iface) < 0) {
+        LOG_ERR("failed to bring up network interface");
+    }
+
+	while (!modem_registered(modem)) {
+		k_sleep(K_SECONDS(1));
+	}
+	k_sleep(K_SECONDS(1));
 
 #if defined(CONFIG_MQTT_LIB_TLS)
 	int rc;

I used this configuration overlay to disable NET_NATIVE and enable socket offloading

# UART console
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_LOG=y
CONFIG_UART_INTERRUPT_DRIVEN=y

CONFIG_UART_CONSOLE=y
CONFIG_LOG_BACKEND_UART=y
#CONFIG_MODEM_LOG_LEVEL_DBG=y
#CONFIG_MODEM_MODULES_LOG_LEVEL_DBG=y
#CONFIG_MQTT_LOG_LEVEL_DBG=y

# Enable basic networking and sockets.
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y

# Disable NET_NATIVE
CONFIG_NET_NATIVE=n
CONFIG_NET_L2_PPP=n
CONFIG_NET_IPV4=n
CONFIG_NET_IPV6=n
CONFIG_NET_TCP=n
CONFIG_NET_UDP=n

CONFIG_NET_IPV6_RA_RDNSS=n
CONFIG_NET_CONFIG_SETTINGS=n
CONFIG_NET_SHELL=n

# Enable the socket offloaded driver.
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_MODEM=y
CONFIG_MODEM_NRF91_SLM=y
CONFIG_PM_DEVICE=y

And I used this device tree overlay for my LPC5516.

#include <nxp/nxp_lpc55S16_ns.dtsi>

/ {
	aliases {
		modem = &modem;
	};
};

&pinctrl {
	pinmux_flexcomm6_usart: pinmux_flexcomm6_usart {
		group0 {
			pinmux =
				<FC6_TXD_SCL_MISO_WS_PIO1_16>, 
				<FC6_RXD_SDA_MOSI_DATA_PIO1_13>; 
			slew-rate = "standard";
		};
	};
};

&flexcomm6 {
	status = "okay";
	compatible = "nxp,lpc-usart";
	current-speed = <115200>;
	pinctrl-0 = <&pinmux_flexcomm6_usart>;
	pinctrl-names = "default";

	modem: modem {
		compatible = "nordic,nrf91-slm";
		status = "okay";
		mdm-power-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
	};
};

Sample size with socket offloading:

Memory region         Used Size  Region Size  %age Used
           FLASH:       59348 B       246 KB     23.56%
             RAM:       25224 B        64 KB     38.49%
           SRAMX:          0 GB        16 KB      0.00%
           SRAM0:          0 GB        64 KB      0.00%
        USB_SRAM:          0 GB        16 KB      0.00%
        IDT_LIST:          0 GB        32 KB      0.00%

This commit adds a socket offloaded driver for the Nordic
nRF91x Serial LTE Modem.

Signed-off-by: Wilkins White <ww@novadynamics.com>
@wilkinsw wilkinsw force-pushed the feature/modem-nrf91-slm branch from 3999046 to 89494aa Compare July 11, 2025 00:38
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants