drivers: Add retained memory driver interface
Adds a new driver interface for retained memory devices which can be used to store data and have it retained whilst the device is powered thorugh different application execution states (though this data may be lost in low power states). Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
This commit is contained in:
parent
db193332fa
commit
2fedb306f7
6 changed files with 262 additions and 0 deletions
|
@ -62,6 +62,7 @@ add_subdirectory_ifdef(CONFIG_PTP_CLOCK ptp_clock)
|
||||||
add_subdirectory_ifdef(CONFIG_PWM pwm)
|
add_subdirectory_ifdef(CONFIG_PWM pwm)
|
||||||
add_subdirectory_ifdef(CONFIG_REGULATOR regulator)
|
add_subdirectory_ifdef(CONFIG_REGULATOR regulator)
|
||||||
add_subdirectory_ifdef(CONFIG_RESET reset)
|
add_subdirectory_ifdef(CONFIG_RESET reset)
|
||||||
|
add_subdirectory_ifdef(CONFIG_RETAINED_MEM retained_mem)
|
||||||
add_subdirectory_ifdef(CONFIG_SDHC sdhc)
|
add_subdirectory_ifdef(CONFIG_SDHC sdhc)
|
||||||
add_subdirectory_ifdef(CONFIG_SENSOR sensor)
|
add_subdirectory_ifdef(CONFIG_SENSOR sensor)
|
||||||
add_subdirectory_ifdef(CONFIG_SERIAL_HAS_DRIVER serial)
|
add_subdirectory_ifdef(CONFIG_SERIAL_HAS_DRIVER serial)
|
||||||
|
|
|
@ -63,6 +63,7 @@ source "drivers/ptp_clock/Kconfig"
|
||||||
source "drivers/pwm/Kconfig"
|
source "drivers/pwm/Kconfig"
|
||||||
source "drivers/regulator/Kconfig"
|
source "drivers/regulator/Kconfig"
|
||||||
source "drivers/reset/Kconfig"
|
source "drivers/reset/Kconfig"
|
||||||
|
source "drivers/retained_mem/Kconfig"
|
||||||
source "drivers/sdhc/Kconfig"
|
source "drivers/sdhc/Kconfig"
|
||||||
source "drivers/sensor/Kconfig"
|
source "drivers/sensor/Kconfig"
|
||||||
source "drivers/serial/Kconfig"
|
source "drivers/serial/Kconfig"
|
||||||
|
|
3
drivers/retained_mem/CMakeLists.txt
Normal file
3
drivers/retained_mem/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
zephyr_library()
|
22
drivers/retained_mem/Kconfig
Normal file
22
drivers/retained_mem/Kconfig
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (c) Nordic Semiconductor ASA
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
menuconfig RETAINED_MEM
|
||||||
|
bool "Retained memory support"
|
||||||
|
help
|
||||||
|
Enables support for drivers that can retain their data whilst the
|
||||||
|
device is powered (may be lost in low power states).
|
||||||
|
|
||||||
|
if RETAINED_MEM
|
||||||
|
|
||||||
|
config RETAINED_MEM_INIT_PRIORITY
|
||||||
|
int "Retained memory devices init priority"
|
||||||
|
default 40
|
||||||
|
help
|
||||||
|
Retained memory devices initialization priority,
|
||||||
|
|
||||||
|
module = RETAINED_MEM
|
||||||
|
module-str = retained_mem
|
||||||
|
source "subsys/logging/Kconfig.template.log_config"
|
||||||
|
|
||||||
|
endif # RETAINED_MEM
|
40
drivers/retained_mem/retained_mem_handlers.c
Normal file
40
drivers/retained_mem/retained_mem_handlers.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/retained_mem.h>
|
||||||
|
#include <zephyr/syscall_handler.h>
|
||||||
|
|
||||||
|
static inline ssize_t z_vrfy_retained_mem_size(const struct device *dev)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM));
|
||||||
|
return z_impl_retained_mem_size(dev);
|
||||||
|
}
|
||||||
|
#include <syscalls/retained_mem_size_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_retained_mem_read(const struct device *dev, off_t offset,
|
||||||
|
uint8_t *buffer, size_t size)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buffer, size));
|
||||||
|
return z_impl_retained_mem_read(dev, offset, buffer, size);
|
||||||
|
}
|
||||||
|
#include <syscalls/retained_mem_read_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_retained_mem_write(const struct device *dev, off_t offset,
|
||||||
|
const uint8_t *buffer, size_t size)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM));
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_READ(buffer, size));
|
||||||
|
return z_impl_retained_mem_write(dev, offset, buffer, size);
|
||||||
|
}
|
||||||
|
#include <syscalls/retained_mem_write_mrsh.c>
|
||||||
|
|
||||||
|
static inline int z_vrfy_retained_mem_clear(const struct device *dev)
|
||||||
|
{
|
||||||
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_RETAINED_MEM));
|
||||||
|
return z_impl_retained_mem_clear(dev);
|
||||||
|
}
|
||||||
|
#include <syscalls/retained_mem_clear_mrsh.c>
|
195
include/zephyr/drivers/retained_mem.h
Normal file
195
include/zephyr/drivers/retained_mem.h
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Public API for retained memory drivers
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_
|
||||||
|
#define ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <zephyr/sys/math_extras.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BUILD_ASSERT(!(sizeof(off_t) > sizeof(size_t)),
|
||||||
|
"Size of off_t must be equal or less than size of size_t");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retained memory driver interface
|
||||||
|
* @defgroup retained_mem_interface Retained memory driver interface
|
||||||
|
* @ingroup io_interfaces
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef retained_mem_size_api
|
||||||
|
* @brief Callback API to get size of retained memory area.
|
||||||
|
* See retained_mem_size() for argument description.
|
||||||
|
*/
|
||||||
|
typedef ssize_t (*retained_mem_size_api)(const struct device *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef retained_mem_read_api
|
||||||
|
* @brief Callback API to read from retained memory area.
|
||||||
|
* See retained_mem_read() for argument description.
|
||||||
|
*/
|
||||||
|
typedef int (*retained_mem_read_api)(const struct device *dev, off_t offset, uint8_t *buffer,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef retained_mem_write_api
|
||||||
|
* @brief Callback API to write to retained memory area.
|
||||||
|
* See retained_mem_write() for argument description.
|
||||||
|
*/
|
||||||
|
typedef int (*retained_mem_write_api)(const struct device *dev, off_t offset,
|
||||||
|
const uint8_t *buffer, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef retained_mem_clear_api
|
||||||
|
* @brief Callback API to clear retained memory area (reset all data to 0x00).
|
||||||
|
* See retained_mem_clear() for argument description.
|
||||||
|
*/
|
||||||
|
typedef int (*retained_mem_clear_api)(const struct device *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retained memory driver API
|
||||||
|
* API which can be used by a device to store data in a retained memory area. Retained memory is
|
||||||
|
* memory that is retained while the device is powered but is lost when power to the device is
|
||||||
|
* lost (note that low power modes in some devices may clear the data also). This may be in a
|
||||||
|
* non-initialised RAM region, or in specific registers, but is not reset when a different
|
||||||
|
* application begins execution or the device is rebooted (without power loss). It must support
|
||||||
|
* byte-level reading and writing without a need to erase data before writing.
|
||||||
|
*
|
||||||
|
* Note that drivers must implement all functions, none of the functions are optional.
|
||||||
|
*/
|
||||||
|
struct retained_mem_driver_api {
|
||||||
|
retained_mem_size_api size;
|
||||||
|
retained_mem_read_api read;
|
||||||
|
retained_mem_write_api write;
|
||||||
|
retained_mem_clear_api clear;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the size of the retained memory area.
|
||||||
|
*
|
||||||
|
* @param dev Retained memory device to use.
|
||||||
|
*
|
||||||
|
* @retval Positive value indicating size in bytes on success, else negative errno
|
||||||
|
* code.
|
||||||
|
*/
|
||||||
|
__syscall ssize_t retained_mem_size(const struct device *dev);
|
||||||
|
|
||||||
|
static inline ssize_t z_impl_retained_mem_size(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct retained_mem_driver_api *api = (struct retained_mem_driver_api *)dev->api;
|
||||||
|
|
||||||
|
return api->size(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads data from the Retained memory area.
|
||||||
|
*
|
||||||
|
* @param dev Retained memory device to use.
|
||||||
|
* @param offset Offset to read data from.
|
||||||
|
* @param buffer Buffer to store read data in.
|
||||||
|
* @param size Size of data to read.
|
||||||
|
*
|
||||||
|
* @retval 0 on success else negative errno code.
|
||||||
|
*/
|
||||||
|
__syscall int retained_mem_read(const struct device *dev, off_t offset, uint8_t *buffer,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
static inline int z_impl_retained_mem_read(const struct device *dev, off_t offset,
|
||||||
|
uint8_t *buffer, size_t size)
|
||||||
|
{
|
||||||
|
struct retained_mem_driver_api *api = (struct retained_mem_driver_api *)dev->api;
|
||||||
|
size_t area_size;
|
||||||
|
|
||||||
|
/* Validate user-supplied parameters */
|
||||||
|
if (size == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
area_size = api->size(dev);
|
||||||
|
|
||||||
|
if (offset < 0 || size > area_size || (area_size - size) < (size_t)offset) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->read(dev, offset, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes data to the Retained memory area - underlying data does not need to
|
||||||
|
* be cleared prior to writing.
|
||||||
|
*
|
||||||
|
* @param dev Retained memory device to use.
|
||||||
|
* @param offset Offset to write data to.
|
||||||
|
* @param buffer Data to write.
|
||||||
|
* @param size Size of data to be written.
|
||||||
|
*
|
||||||
|
* @retval 0 on success else negative errno code.
|
||||||
|
*/
|
||||||
|
__syscall int retained_mem_write(const struct device *dev, off_t offset, const uint8_t *buffer,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
static inline int z_impl_retained_mem_write(const struct device *dev, off_t offset,
|
||||||
|
const uint8_t *buffer, size_t size)
|
||||||
|
{
|
||||||
|
struct retained_mem_driver_api *api = (struct retained_mem_driver_api *)dev->api;
|
||||||
|
size_t area_size;
|
||||||
|
|
||||||
|
/* Validate user-supplied parameters */
|
||||||
|
if (size == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
area_size = api->size(dev);
|
||||||
|
|
||||||
|
if (offset < 0 || size > area_size || (area_size - size) < (size_t)offset) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api->write(dev, offset, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears data in the retained memory area by setting it to 0x00.
|
||||||
|
*
|
||||||
|
* @param dev Retained memory device to use.
|
||||||
|
*
|
||||||
|
* @retval 0 on success else negative errno code.
|
||||||
|
*/
|
||||||
|
__syscall int retained_mem_clear(const struct device *dev);
|
||||||
|
|
||||||
|
static inline int z_impl_retained_mem_clear(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct retained_mem_driver_api *api = (struct retained_mem_driver_api *)dev->api;
|
||||||
|
|
||||||
|
return api->clear(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <syscalls/retained_mem.h>
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_ */
|
Loading…
Add table
Add a link
Reference in a new issue