From 5bae23b89171ef4db5665ae7ec84038cb61e2802 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 22 Feb 2023 13:29:37 +0000 Subject: [PATCH] drivers: retained_mem: Add RAM driver Adds a non-initialised RAM-based retained memory driver. Signed-off-by: Jamie McCrae --- drivers/retained_mem/CMakeLists.txt | 1 + drivers/retained_mem/Kconfig | 2 + drivers/retained_mem/Kconfig.zephyr | 9 ++ .../retained_mem/retained_mem_zephyr_ram.c | 139 ++++++++++++++++++ .../retained_mem/zephyr,retained-ram.yaml | 8 + 5 files changed, 159 insertions(+) create mode 100644 drivers/retained_mem/Kconfig.zephyr create mode 100644 drivers/retained_mem/retained_mem_zephyr_ram.c create mode 100644 dts/bindings/retained_mem/zephyr,retained-ram.yaml diff --git a/drivers/retained_mem/CMakeLists.txt b/drivers/retained_mem/CMakeLists.txt index 027db434a32..c3c9ea6d0bd 100644 --- a/drivers/retained_mem/CMakeLists.txt +++ b/drivers/retained_mem/CMakeLists.txt @@ -2,3 +2,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_NRF_GPREGRET retained_mem_nrf_gpregret.c) +zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_ZEPHYR_RAM retained_mem_zephyr_ram.c) diff --git a/drivers/retained_mem/Kconfig b/drivers/retained_mem/Kconfig index c8cd06b6920..c8a9862dfe0 100644 --- a/drivers/retained_mem/Kconfig +++ b/drivers/retained_mem/Kconfig @@ -21,4 +21,6 @@ source "subsys/logging/Kconfig.template.log_config" source "drivers/retained_mem/Kconfig.nrf" +source "drivers/retained_mem/Kconfig.zephyr" + endif # RETAINED_MEM diff --git a/drivers/retained_mem/Kconfig.zephyr b/drivers/retained_mem/Kconfig.zephyr new file mode 100644 index 00000000000..4a4231c4968 --- /dev/null +++ b/drivers/retained_mem/Kconfig.zephyr @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config RETAINED_MEM_ZEPHYR_RAM + bool "Generic Zephyr RAM retained memory driver" + default y + depends on DT_HAS_ZEPHYR_RETAINED_RAM_ENABLED + help + Enable driver for retained memory in RAM. diff --git a/drivers/retained_mem/retained_mem_zephyr_ram.c b/drivers/retained_mem/retained_mem_zephyr_ram.c new file mode 100644 index 00000000000..55c86c392c2 --- /dev/null +++ b/drivers/retained_mem/retained_mem_zephyr_ram.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_retained_ram + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(retained_mem_zephyr_ram, CONFIG_RETAINED_MEM_LOG_LEVEL); + +#ifdef CONFIG_MULTITHREADING +struct zephyr_retained_mem_ram_data { + struct k_mutex lock; +}; +#endif + +struct zephyr_retained_mem_ram_config { + uint8_t *address; + size_t size; +}; + +static inline void zephyr_retained_mem_ram_lock_take(const struct device *dev) +{ +#ifdef CONFIG_MULTITHREADING + struct zephyr_retained_mem_ram_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); +#else + ARG_UNUSED(dev); +#endif +} + +static inline void zephyr_retained_mem_ram_lock_release(const struct device *dev) +{ +#ifdef CONFIG_MULTITHREADING + struct zephyr_retained_mem_ram_data *data = dev->data; + + k_mutex_unlock(&data->lock); +#else + ARG_UNUSED(dev); +#endif +} + +static int zephyr_retained_mem_ram_init(const struct device *dev) +{ +#ifdef CONFIG_MULTITHREADING + struct zephyr_retained_mem_ram_data *data = dev->data; + + k_mutex_init(&data->lock); +#endif + + return 0; +} + +static ssize_t zephyr_retained_mem_ram_size(const struct device *dev) +{ + const struct zephyr_retained_mem_ram_config *config = dev->config; + + return (ssize_t)config->size; +} + +static int zephyr_retained_mem_ram_read(const struct device *dev, off_t offset, uint8_t *buffer, + size_t size) +{ + const struct zephyr_retained_mem_ram_config *config = dev->config; + + zephyr_retained_mem_ram_lock_take(dev); + + memcpy(buffer, (config->address + offset), size); + + zephyr_retained_mem_ram_lock_release(dev); + + return 0; +} + +static int zephyr_retained_mem_ram_write(const struct device *dev, off_t offset, + const uint8_t *buffer, size_t size) +{ + const struct zephyr_retained_mem_ram_config *config = dev->config; + + zephyr_retained_mem_ram_lock_take(dev); + + memcpy((config->address + offset), buffer, size); + + zephyr_retained_mem_ram_lock_release(dev); + + return 0; +} + +static int zephyr_retained_mem_ram_clear(const struct device *dev) +{ + const struct zephyr_retained_mem_ram_config *config = dev->config; + + zephyr_retained_mem_ram_lock_take(dev); + + memset(config->address, 0, config->size); + + zephyr_retained_mem_ram_lock_release(dev); + + return 0; +} + +static const struct retained_mem_driver_api zephyr_retained_mem_ram_api = { + .size = zephyr_retained_mem_ram_size, + .read = zephyr_retained_mem_ram_read, + .write = zephyr_retained_mem_ram_write, + .clear = zephyr_retained_mem_ram_clear, +}; + +#define ZEPHYR_RETAINED_MEM_RAM_DEVICE(inst) \ + IF_ENABLED(CONFIG_MULTITHREADING, \ + (static struct zephyr_retained_mem_ram_data \ + zephyr_retained_mem_ram_data_##inst;) \ + ) \ + static const struct zephyr_retained_mem_ram_config \ + zephyr_retained_mem_ram_config_##inst = { \ + .address = (uint8_t *)DT_REG_ADDR(DT_PARENT(DT_INST(inst, DT_DRV_COMPAT))), \ + .size = DT_REG_SIZE(DT_PARENT(DT_INST(inst, DT_DRV_COMPAT))), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, \ + &zephyr_retained_mem_ram_init, \ + NULL, \ + COND_CODE_1(CONFIG_MULTITHREADING, \ + (&zephyr_retained_mem_ram_data_##inst), (NULL) \ + ), \ + &zephyr_retained_mem_ram_config_##inst, \ + POST_KERNEL, \ + CONFIG_RETAINED_MEM_INIT_PRIORITY, \ + &zephyr_retained_mem_ram_api); + +DT_INST_FOREACH_STATUS_OKAY(ZEPHYR_RETAINED_MEM_RAM_DEVICE) diff --git a/dts/bindings/retained_mem/zephyr,retained-ram.yaml b/dts/bindings/retained_mem/zephyr,retained-ram.yaml new file mode 100644 index 00000000000..4a543304d85 --- /dev/null +++ b/dts/bindings/retained_mem/zephyr,retained-ram.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Unitialised RAM-based retained memory area. + +compatible: "zephyr,retained-ram" + +include: base.yaml