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 	size_t erased_up_to;		/* Offset of last erased byte, relative to
69 					 * offset in this context.
70 					 */
71 #endif
72 	size_t write_block_size;	/* Offset/size device write alignment */
73 	uint8_t erase_value;
74 };
75 
76 /**
77  * @brief Initialize context needed for stream writes to flash.
78  *
79  * @param ctx context to be initialized
80  * @param fdev Flash device to operate on
81  * @param buf Write buffer
82  * @param buf_len Length of write buffer. Can not be larger than the page size.
83  *                Must be multiple of the flash device write-block-size.
84  * @param offset Offset within flash device to start writing to
85  * @param size Number of bytes available for performing buffered write.
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  * @deprecated Use @a flash_area_erase() or flash_erase(). Note that there
134  * is no Stream Flash API equivalent for that.
135  *
136  * This function erases a flash page to which an offset belongs if this page
137  * is not the page previously erased by the provided ctx
138  * (ctx->last_erased_page_start_offset).
139  *
140  * @param ctx context
141  * @param off offset from the base address of the flash device
142  *
143  * @return non-negative on success, negative errno code on fail
144  */
145 __deprecated int stream_flash_erase_page(struct stream_flash_ctx *ctx, off_t off);
146 
147 /**
148  * @brief Load persistent stream write progress stored with key
149  *        @p settings_key .
150  *
151  * This function should be called directly after @ref stream_flash_init to
152  * load previous stream write progress before writing any data. If the loaded
153  * progress has fewer bytes written than @p ctx then it will be ignored.
154  *
155  * @param ctx context
156  * @param settings_key key to use with the settings module for loading
157  *                     the stream write progress
158  *
159  * @return non-negative on success, -ERANGE in case when @p off is out
160  * of area designated for stream or negative errno code on fail
161  */
162 int stream_flash_progress_load(struct stream_flash_ctx *ctx,
163 			       const char *settings_key);
164 
165 /**
166  * @brief Save persistent stream write progress using key @p settings_key .
167  *
168  * @param ctx context
169  * @param settings_key key to use with the settings module for storing
170  *                     the stream write progress
171  *
172  * @return non-negative on success, negative errno code on fail
173  */
174 int stream_flash_progress_save(const struct stream_flash_ctx *ctx,
175 			       const char *settings_key);
176 
177 /**
178  * @brief Clear persistent stream write progress stored with key
179  *        @p settings_key .
180  *
181  * @param ctx context
182  * @param settings_key key previously used for storing the stream write progress
183  *
184  * @return non-negative on success, negative errno code on fail
185  */
186 int stream_flash_progress_clear(const struct stream_flash_ctx *ctx,
187 				const char *settings_key);
188 
189 #ifdef __cplusplus
190 }
191 #endif
192 
193 /**
194  * @}
195  */
196 
197 #endif /* ZEPHYR_INCLUDE_STORAGE_STREAM_FLASH_H_ */
198