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
18 changes: 18 additions & 0 deletions MAINTAINERS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3385,6 +3385,24 @@ NEORV32 platform:
tests:
- boards.neorv32

NVMEM:
status: maintained
maintainers:
- pdgendt
collaborators:
- henrikbrixandersen
files:
- doc/services/nvmem/
- dts/bindings/nvmem/
- include/zephyr/devicetree/nvmem.h
- include/zephyr/nvmem.h
- subsys/nvmem/
- tests/subsys/nvmem/
labels:
- "area: NVMEM"
tests:
- nvmem

NXP Platform Drivers:
status: maintained
maintainers:
Expand Down
13 changes: 13 additions & 0 deletions doc/releases/release-notes-4.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,19 @@ New APIs and options

* :kconfig:option:`CONFIG_MODEM_DEDICATED_WORKQUEUE`

* NVMEM

* Introduced :ref:`Non-Volatile Memory (NVMEM)<nvmem>` subsystem

* :kconfig:option:`CONFIG_NVMEM`
* :kconfig:option:`CONFIG_NVMEM_EEPROM`
* :c:struct:`nvmem_cell`
* :c:func:`nvmem_cell_read`
* :c:func:`nvmem_cell_write`
* :c:func:`nvmem_cell_is_ready`
* :c:macro:`NVMEM_CELL_GET_BY_NAME` - and variants
* :c:macro:`NVMEM_CELL_GET_BY_IDX` - and variants

* Networking

* Sockets
Expand Down
1 change: 1 addition & 0 deletions doc/services/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ OS Services
resource_management/index.rst
mem_mgmt/index.rst
net_buf/index.rst
nvmem/index.rst
modem/index.rst
notify.rst
pm/index.rst
Expand Down
18 changes: 18 additions & 0 deletions doc/services/nvmem/devicetree_bindings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
&eeprom0 {

Check warning on line 1 in doc/services/nvmem/devicetree_bindings.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

Copyright missing

doc/services/nvmem/devicetree_bindings.txt:1 File has no SPDX-FileCopyrightText header, consider adding one.

Check warning on line 1 in doc/services/nvmem/devicetree_bindings.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License missing

doc/services/nvmem/devicetree_bindings.txt:1 File has no SPDX-License-Identifier header, consider adding one.
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;

mac_address: mac_address@0 {
reg = <0x0 6>;
#nvmem-cell-cells = <0>;
read-only;
};

calibration_data: calibration_data@6 {
reg = <0x6 100>;
#nvmem-cell-cells = <0>;
};
};
};
68 changes: 68 additions & 0 deletions doc/services/nvmem/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.. _nvmem:

Non-Volatile Memory (NVMEM)
###########################

The NVMEM subsystem provides a generic interface for accessing non-volatile
memory devices. It abstracts the underlying hardware and provides a unified API
for reading and writing data.

Key Concepts
************

NVMEM Provider
==============

An NVMEM provider is a driver that exposes NVMEM cells. For example, an EEPROM
driver can be an NVMEM provider. The NVMEM provider is responsible for reading
and writing data to the underlying hardware.

NVMEM Cell
==========

An NVMEM cell is a region of non-volatile memory. It is defined in the
devicetree and has properties like offset, size, and read-only status.

NVMEM Consumer
==============

An NVMEM consumer is a driver or application that uses NVMEM cells to store or
retrieve data.

Configuration
*************

* :kconfig:option:`CONFIG_NVMEM`: Enables the NVMEM subsystem.
* :kconfig:option:`CONFIG_NVMEM_EEPROM`: Enables NVMEM support for EEPROM devices.

Devicetree Bindings
*******************

The NVMEM subsystem relies on devicetree bindings to define NVMEM cells.
The following is an example of how to define an NVMEM provider and cells in the
devicetree:

.. literalinclude:: devicetree_bindings.txt
:language: dts


A consumer can then reference the NVMEM cells like this:

.. literalinclude:: my_consumer.txt
:language: dts


Usage Example
*************

The following is an example of how to use the NVMEM API to read data from an
NVMEM cell:

.. literalinclude:: usage_example.txt
:language: c


API Reference
*************

.. doxygengroup:: nvmem_interface
5 changes: 5 additions & 0 deletions doc/services/nvmem/my_consumer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
my_consumer: my-consumer {

Check warning on line 1 in doc/services/nvmem/my_consumer.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

Copyright missing

doc/services/nvmem/my_consumer.txt:1 File has no SPDX-FileCopyrightText header, consider adding one.

Check warning on line 1 in doc/services/nvmem/my_consumer.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License missing

doc/services/nvmem/my_consumer.txt:1 File has no SPDX-License-Identifier header, consider adding one.
compatible = "my,consumer";
nvmem-cells = <&mac_address>, <&calibration_data>;
nvmem-cell-names = "mac-address", "calibration-data";
};
23 changes: 23 additions & 0 deletions doc/services/nvmem/usage_example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <zephyr/nvmem.h>

Check warning on line 1 in doc/services/nvmem/usage_example.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

Copyright missing

doc/services/nvmem/usage_example.txt:1 File has no SPDX-FileCopyrightText header, consider adding one.

Check warning on line 1 in doc/services/nvmem/usage_example.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License missing

doc/services/nvmem/usage_example.txt:1 File has no SPDX-License-Identifier header, consider adding one.

static const struct nvmem_cell mac_address =
NVMEM_CELL_GET_BY_NAME(DT_NODELABEL(my_consumer), mac_address);

int main(void)
{
uint8_t mac[6];
int ret;

if (!nvmem_cell_is_ready(&mac_address)) {
printk("NVMEM cell is not ready\n");
return -ENODEV;
}

ret = nvmem_cell_read(&mac_address, mac, 0, sizeof(mac));
if (ret < 0) {
printk("Failed to read MAC address: %d\n", ret);
return ret;
}

/* ... */
}
46 changes: 46 additions & 0 deletions dts/bindings/nvmem/fixed-layout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright (c) 2025 Basalte bv
# SPDX-License-Identifier: Apache-2.0

description: |
Fixed layout for Non-Volatile memory.
compatible: "fixed-layout"

properties:
"#address-cells":
type: int
const: 1
description: |
Number of cells required to represent a child node's
reg property address.
"#size-cells":
type: int
const: 1
description: |
Number of cells required to represent a child node's size.
child-binding:
description: |
Each child node of the NVMEM provider node represents
an individual NVMEM cell. These should usually
look like this:
cell_nodelabel: cell@START_OFFSET {
reg = <0xSTART_OFFSET 0xSIZE>;
#nvmem-cell-cells = <0>;
Copy link

Choose a reason for hiding this comment

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

Hello Pieter, what are you planning to do with #nvmem-cell-cells? Isn't it enough to work with reg and #address-cells + #size-cells. It's not documented for now so might as well remove it if not necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is required to work with phandle-array binding types (see the docs). I didn't want to introduce special treatment in some of the python code for this.

I don't have plans for this, but it can be used for future types of NVMEM providers. I can't give an example from the top of my head though.

};
properties:
reg:
type: array
required: true
description: |
This should be in the format <OFFSET SIZE>, where OFFSET
is the offset of the NVMEM cell relative to the base
address of the parent memory, and SIZE is the size of
the cell in bytes.
read-only:
type: boolean
description: Set this property if the cell is read-only.
14 changes: 14 additions & 0 deletions dts/bindings/nvmem/nvmem-consumer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) 2024, Andriy Gelman <[email protected]>
# Copyright (c) 2025 Basalte bv
# SPDX-License-Identifier: Apache-2.0

properties:
nvmem-cell-names:
type: string-array
description:
Names for each nvmem-cells specified.

nvmem-cells:
type: phandle-array
description:
List of phandles to the nvmem data cells.
8 changes: 8 additions & 0 deletions dts/bindings/test/vnd,nvmem-consumer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2025 Basalte bv
# SPDX-License-Identifier: Apache-2.0

description: Test NVMEM consumer node

compatible: "vnd,nvmem-consumer"

include: [nvmem-consumer.yaml]
Loading
Loading