/* * 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 #include #include #include #include #include #include #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 * @since 3.4 * @version 0.8.0 * @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. */ __subsystem 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 #endif /* ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_ */