Skip to content

Commit

Permalink
Add socket callbacks and memory layout
Browse files Browse the repository at this point in the history
  • Loading branch information
diondokter committed Sep 22, 2023
1 parent c613be0 commit f9d4a24
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 35 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.4.1 (2023-09-22)

- Added a new modem init function where the memory layout can be manually specified
- Sockets now use the built-in nrfxlib callbacks instead of waking at every IPC interrupt

## 0.4.0 (2023-09-07)

- Update nrfxlib-sys to 2.4.2, removing the need for the `EGU1` interrupt
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nrf-modem"
version = "0.4.0"
version = "0.4.1"
edition = "2021"
rust-version = "1.64"
license = "MIT OR Apache-2.0"
Expand All @@ -15,16 +15,16 @@ keywords = ["nRF9160", "LTE", "GPS", "NB-IoT", "embedded"]
[dependencies]
nrfxlib-sys = "2.4.2"
futures = { version = "0.3.24", default-features = false, features = ["async-await"] }
num_enum = { version = "0.6.1", default-features = false }
defmt = { version = "0.3.2", optional = true }
num_enum = { version = "0.7.0", default-features = false }
defmt = { version = "0.3", optional = true }
cortex-m = "0.7"
linked_list_allocator = { version="0.10.1", default-features=false, features=["use_spin"] }
nrf9160-pac = "0.12.2"
arrayvec = { version = "0.7", default-features = false }
at-commands = "0.5.2"
no-std-net = "0.6.0"
critical-section = "1.1"
embassy-sync = "0.2.0"
embassy-sync = "0.3.0"

[features]
default = []
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ The `EGU1` and `IPC` interrupts must be routed to the modem software.
#[allow(non_snake_case)]
fn IPC() {
nrf_modem::ipc_irq_handler();
cortex_m::asm::sev();
}
let mut cp = unwrap!(cortex_m::Peripherals::take());
Expand Down
8 changes: 8 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ use crate::socket::SocketOptionError;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
/// The global error type of this crate
pub enum Error {
/// An operation was tried for which the modem needs to be initialized, but the modem is not yet initialized
ModemNotInitialized,
/// There can only be one Gnss instance, yet a second was requested
GnssAlreadyTaken,
/// An unkown error occured. Check [nrf_errno.h](https://github.com/nrfconnect/sdk-nrfxlib/blob/main/nrf_modem/include/nrf_errno.h) to see what it means.
///
/// Sometimes the sign is flipped, but ignore that and just look at the number.
NrfError(isize),
BufferTooSmall(Option<usize>),
OutOfMemory,
Expand All @@ -30,6 +36,8 @@ pub enum Error {
Disconnected,
TooManyLteLinks,
InternalRuntimeMutexLocked,
/// The given memory layout falls outside of the acceptable range
BadMemoryLayout,
}

pub trait ErrorSource {
Expand Down
84 changes: 68 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use crate::error::ErrorSource;
use core::{
cell::RefCell,
ops::Range,
sync::atomic::{AtomicBool, Ordering},
};
use cortex_m::interrupt::Mutex;
Expand Down Expand Up @@ -69,6 +70,31 @@ pub(crate) static MODEM_RUNTIME_STATE: RuntimeState = RuntimeState::new();

/// Start the NRF Modem library
pub async fn init(mode: SystemMode) -> Result<(), Error> {
init_with_custom_layout(mode, Default::default()).await
}

/// Start the NRF Modem library with a manually specified memory layout
pub async fn init_with_custom_layout(
mode: SystemMode,
memory_layout: MemoryLayout,
) -> Result<(), Error> {
const SHARED_MEMORY_RANGE: Range<u32> = 0x2000_0000..0x2002_0000;

if !SHARED_MEMORY_RANGE.contains(&memory_layout.base_address) {
return Err(Error::BadMemoryLayout);
}
if !SHARED_MEMORY_RANGE.contains(
&(memory_layout.base_address
+ nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE
+ memory_layout.tx_area_size
+ memory_layout.rx_area_size
+ memory_layout.trace_area_size
// Minus one, because this check should be inclusive
- 1),
) {
return Err(Error::BadMemoryLayout);
}

// The modem is only certified when the DC/DC converter is enabled and it isn't by default
unsafe {
(*nrf9160_pac::REGULATORS_NS::PTR)
Expand All @@ -90,27 +116,25 @@ pub async fn init(mode: SystemMode) -> Result<(), Error> {
let params = nrfxlib_sys::nrf_modem_init_params {
shmem: nrfxlib_sys::nrf_modem_shmem_cfg {
ctrl: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_1 {
// At start of shared memory (see memory.x)
base: 0x2001_0000,
// This is the amount specified in the NCS 1.5.1 release.
base: memory_layout.base_address,
size: nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE,
},
tx: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_2 {
// Follows on from control buffer
base: 0x2001_0000 + nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE,
// This is the amount specified in the NCS 1.5.1 release.
size: 0x0000_2000,
base: memory_layout.base_address + nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE,
size: memory_layout.tx_area_size,
},
rx: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_3 {
// Follows on from TX buffer
base: 0x2001_0000 + nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE + 0x2000,
// This is the amount specified in the NCS 1.5.1 release.
size: 0x0000_2000,
base: memory_layout.base_address
+ nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE
+ memory_layout.tx_area_size,
size: memory_layout.rx_area_size,
},
// No trace info
trace: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_4 {
base: 0x2001_0000,
size: 0,
base: memory_layout.base_address
+ nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE
+ memory_layout.tx_area_size
+ memory_layout.rx_area_size,
size: memory_layout.trace_area_size,
},
},
ipc_irq_prio: 0,
Expand Down Expand Up @@ -159,6 +183,35 @@ pub async fn init(mode: SystemMode) -> Result<(), Error> {
Ok(())
}

/// The memory layout used by the modem library.
///
/// The full range needs to be in the lower 128k of ram.
/// This also contains the fixed [nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE].
///
/// Nordic guide: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.4.1/nrfxlib/nrf_modem/doc/architecture.html#shared-memory-configuration
pub struct MemoryLayout {
/// The start of the memory area
pub base_address: u32,
/// The buffer size of the socket send operations, as well as sent AT commands and TLS certs
pub tx_area_size: u32,
/// The buffer size of the socket receive operations, as well as received AT commands, gnss messages and TLS certs
pub rx_area_size: u32,
/// The buffer size of the trace logs
pub trace_area_size: u32,
}

impl Default for MemoryLayout {
fn default() -> Self {
Self {
base_address: 0x2001_0000,
tx_area_size: 0x2000,
rx_area_size: 0x2000,
// Trace is not implemented yet
trace_area_size: 0,
}
}
}

unsafe extern "C" fn modem_fault_handler(_info: *mut nrfxlib_sys::nrf_modem_fault_info) {
#[cfg(feature = "defmt")]
defmt::error!(
Expand All @@ -172,9 +225,8 @@ unsafe extern "C" fn modem_fault_handler(_info: *mut nrfxlib_sys::nrf_modem_faul
pub fn ipc_irq_handler() {
unsafe {
crate::ffi::nrf_ipc_irq_handler();
nrfxlib_sys::nrf_modem_os_event_notify(0);
crate::socket::wake_sockets();
}
cortex_m::asm::sev();
}

/// Identifies which radios in the nRF9160 should be active
Expand Down
1 change: 1 addition & 0 deletions src/lte_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use core::{mem, ops::ControlFlow, task::Poll};
///
/// The user can prevent this by creating his own instance that the user only drops when all network tasks are done.
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LteLink(());

impl LteLink {
Expand Down
Loading

0 comments on commit f9d4a24

Please sign in to comment.