1 /*
2  * Copyright (c) 2017, 2020 Nordic Semiconductor ASA
3  * Copyright (c) 2017 Linaro Limited
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief Public API for stream writes to flash
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_STORAGE_STREAM_FLASH_H_
14 #define ZEPHYR_INCLUDE_STORAGE_STREAM_FLASH_H_
15 
16 /**
17  * @brief Abstraction over stream writes to flash
18  *
19  * @defgroup stream_flash Stream to flash interface
20  * @since 2.3
21  * @version 0.1.0
22  * @ingroup storage_apis
23  * @{
24  */
25 
26 #include <stdbool.h>
27 #include <zephyr/drivers/flash.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /**
34  * @typedef stream_flash_callback_t
35  *
36  * @brief Signature for callback invoked after flash write completes.
37  *
38  * @details Functions of this type are invoked with a buffer containing
39  * data read back from the flash after a flash write has completed.
40  * This enables verifying that the data has been correctly stored (for
41  * instance by using a SHA function). The write buffer 'buf' provided in
42  * stream_flash_init is used as a read buffer for this purpose.
43  *
44  * @param buf Pointer to the data read.
45  * @param len The length of the data read.
46  * @param offset The offset the data was read from.
47  */
48 typedef int (*stream_flash_callback_t)(uint8_t *buf, size_t len, size_t offset);
49 
50 /**
51  * @brief Structure for stream flash context
52  *
53  * Users should treat these structures as opaque values and only interact
54  * with them through the below API.
55  */
56 struct stream_flash_ctx {
57 	uint8_t *buf; /* Write buffer */
58 	size_t buf_len; /* Length of write buffer */
59 	size_t buf_bytes; /* Number of bytes currently stored in write buf */
60 	const struct device *fdev; /* Flash device */
61 	size_t bytes_written; /* Number of bytes written to flash */
62 	size_t offset; /* Offset from base of flash device to write area */
63 	size_t available; /* Available bytes in write area */
64 #ifdef CONFIG_STREAM_FLASH_POST_WRITE_CALLBACK
65 	stream_flash_callback_t callback; /* Callback invoked after write op */
66 #endif
67 #ifdef CONFIG_STREAM_FLASH_ERASE
68 	off_t last_erased_page_start_offset; /* Last erased offset */
69 #endif
70 	size_t write_block_size;	/* Offset/size device write alignment */
71 	uint8_t erase_value;
72 };
73 
74 /**
75  * @brief Initialize context needed for stream writes to flash.
76  *
77  * @param ctx context to be initialized
78  * @param fdev Flash device to operate on
79  * @param buf Write buffer
80  * @param buf_len Length of write buffer. Can not be larger than the page size.
81  *                Must be multiple of the flash device write-block-size.
82  * @param offset Offset within flash device to start writing to
83  * @param size Number of bytes available for performing buffered write.
84  *             If this is '0', the size will be set to the total size
85  *             of the flash device minus the offset.
86  * @param cb Callback to be invoked on completed flash write operations.
87  *           Callback is supported when CONFIG_STREAM_FLASH_POST_WRITE_CALLBACK
88  *           is enabled.
89  *
90  * @return non-negative on success, negative errno code on fail
91  */
92 int stream_flash_init(struct stream_flash_ctx *ctx, const struct device *fdev,
93 		      uint8_t *buf, size_t buf_len, size_t offset, size_t size,
94 		      stream_flash_callback_t cb);
95 /**
96  * @brief Read number of bytes written to the flash.
97  *
98  * @note api-tags: pre-kernel-ok isr-ok
99  *
100  * @param ctx context
101  *
102  * @return Number of payload bytes written to flash.
103  */
104 size_t stream_flash_bytes_written(const struct stream_flash_ctx *ctx);
105 
106 /**
107  * @brief Process input buffers to be written to flash device in single blocks.
108  * Will store remainder between calls.
109  *
110  * A write with the @p flush set to true has to be issued as the last
111  * write request for a given context, as it concludes write of a stream,
112  * and flushes buffers to storage device.
113  *
114  * @warning There must not be any additional write requests issued for a flushed context,
115  * unless it is re-initialized, as such write attempts may result in the function
116  * failing and returning error.
117  * Once context has been flushed, it can be re-initialized and re-used for new
118  * stream flash session.
119  *
120  * @param ctx context
121  * @param data data to write
122  * @param len Number of bytes to write
123  * @param flush when true this forces any buffered data to be written to flash
124  *
125  * @return non-negative on success, negative errno code on fail
126  */
127 int stream_flash_buffered_write(struct stream_flash_ctx *ctx, const uint8_t *data,
128 				size_t len, bool flush);
129 
130 /**
131  * @brief Erase the flash page to which a given offset belongs.
132  *
133  * This function erases a flash page to which an offset belongs if this page
134  * is not the page previously erased by the provided ctx
135  * (ctx->last_erased_page_start_offset).
136  *
137  * @param ctx context
138  * @param off offset from the base address of the flash device
139  *
140  * @return non-negative on success, negative errno code on fail
141  */
142 int stream_flash_erase_page(struct stream_flash_ctx *ctx, off_t off);
143 
144 /**
145  * @brief Load persistent stream write progress stored with key
146  *        @p settings_key .
147  *
148  * This function should be called directly after @ref stream_flash_init to
149  * load previous stream write progress before writing any data. If the loaded
150  * progress has fewer bytes written than @p ctx then it will be ignored.
151  *
152  * @param ctx context
153  * @param settings_key key to use with the settings module for loading
154  *                     the stream write progress
155  *
156  * @return non-negative on success, -ERANGE in case when @p off is out
157  * of area designated for stream or negative errno code on fail
158  */
159 int stream_flash_progress_load(struct stream_flash_ctx *ctx,
160 			       const char *settings_key);
161 
162 /**
163  * @brief Save persistent stream write progress using key @p settings_key .
164  *
165  * @param ctx context
166  * @param settings_key key to use with the settings module for storing
167  *                     the stream write progress
168  *
169  * @return non-negative on success, negative errno code on fail
170  */
171 int stream_flash_progress_save(const struct stream_flash_ctx *ctx,
172 			       const char *settings_key);
173 
174 /**
175  * @brief Clear persistent stream write progress stored with key
176  *        @p settings_key .
177  *
178  * @param ctx context
179  * @param settings_key key previously used for storing the stream write progress
180  *
181  * @return non-negative on success, negative errno code on fail
182  */
183 int stream_flash_progress_clear(const struct stream_flash_ctx *ctx,
184 				const char *settings_key);
185 
186 #ifdef __cplusplus
187 }
188 #endif
189 
190 /**
191  * @}
192  */
193 
194 #endif /* ZEPHYR_INCLUDE_STORAGE_STREAM_FLASH_H_ */
195