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  * @ingroup storage_apis
21  * @{
22  */
23 
24 #include <stdbool.h>
25 #include <zephyr/drivers/flash.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /**
32  * @typedef stream_flash_callback_t
33  *
34  * @brief Signature for callback invoked after flash write completes.
35  *
36  * @details Functions of this type are invoked with a buffer containing
37  * data read back from the flash after a flash write has completed.
38  * This enables verifying that the data has been correctly stored (for
39  * instance by using a SHA function). The write buffer 'buf' provided in
40  * stream_flash_init is used as a read buffer for this purpose.
41  *
42  * @param buf Pointer to the data read.
43  * @param len The length of the data read.
44  * @param offset The offset the data was read from.
45  */
46 typedef int (*stream_flash_callback_t)(uint8_t *buf, size_t len, size_t offset);
47 
48 /**
49  * @brief Structure for stream flash context
50  *
51  * Users should treat these structures as opaque values and only interact
52  * with them through the below API.
53  */
54 struct stream_flash_ctx {
55 	uint8_t *buf; /* Write buffer */
56 	size_t buf_len; /* Length of write buffer */
57 	size_t buf_bytes; /* Number of bytes currently stored in write buf */
58 	const struct device *fdev; /* Flash device */
59 	size_t bytes_written; /* Number of bytes written to flash */
60 	size_t offset; /* Offset from base of flash device to write area */
61 	size_t available; /* Available bytes in write area */
62 	stream_flash_callback_t callback; /* Callback invoked after write op */
63 #ifdef CONFIG_STREAM_FLASH_ERASE
64 	off_t last_erased_page_start_offset; /* Last erased offset */
65 #endif
66 };
67 
68 /**
69  * @brief Initialize context needed for stream writes to flash.
70  *
71  * @param ctx context to be initialized
72  * @param fdev Flash device to operate on
73  * @param buf Write buffer
74  * @param buf_len Length of write buffer. Can not be larger than the page size.
75  *                Must be multiple of the flash device write-block-size.
76  * @param offset Offset within flash device to start writing to
77  * @param size Number of bytes available for performing buffered write.
78  *             If this is '0', the size will be set to the total size
79  *             of the flash device minus the offset.
80  * @param cb Callback to be invoked on completed flash write operations.
81  *
82  * @return non-negative on success, negative errno code on fail
83  */
84 int stream_flash_init(struct stream_flash_ctx *ctx, const struct device *fdev,
85 		      uint8_t *buf, size_t buf_len, size_t offset, size_t size,
86 		      stream_flash_callback_t cb);
87 /**
88  * @brief Read number of bytes written to the flash.
89  *
90  * @note api-tags: pre-kernel-ok isr-ok
91  *
92  * @param ctx context
93  *
94  * @return Number of payload bytes written to flash.
95  */
96 size_t stream_flash_bytes_written(struct stream_flash_ctx *ctx);
97 
98 /**
99  * @brief  Process input buffers to be written to flash device in single blocks.
100  * Will store remainder between calls.
101  *
102  * A final call to this function with flush set to true
103  * will write out the remaining block buffer to flash.
104  *
105  * @param ctx context
106  * @param data data to write
107  * @param len Number of bytes to write
108  * @param flush when true this forces any buffered data to be written to flash
109  *        A flush write should be the last write operation in a sequence of
110  *        write operations for given context (although this is not mandatory
111  *        if the total data size is a multiple of the buffer size).
112  *
113  * @return non-negative on success, negative errno code on fail
114  */
115 int stream_flash_buffered_write(struct stream_flash_ctx *ctx, const uint8_t *data,
116 				size_t len, bool flush);
117 
118 /**
119  * @brief Erase the flash page to which a given offset belongs.
120  *
121  * This function erases a flash page to which an offset belongs if this page
122  * is not the page previously erased by the provided ctx
123  * (ctx->last_erased_page_start_offset).
124  *
125  * @param ctx context
126  * @param off offset from the base address of the flash device
127  *
128  * @return non-negative on success, negative errno code on fail
129  */
130 int stream_flash_erase_page(struct stream_flash_ctx *ctx, off_t off);
131 
132 /**
133  * @brief Load persistent stream write progress stored with key
134  *        @p settings_key .
135  *
136  * This function should be called directly after @ref stream_flash_init to
137  * load previous stream write progress before writing any data. If the loaded
138  * progress has fewer bytes written than @p ctx then it will be ignored.
139  *
140  * @param ctx context
141  * @param settings_key key to use with the settings module for loading
142  *                     the stream write progress
143  *
144  * @return non-negative on success, negative errno code on fail
145  */
146 int stream_flash_progress_load(struct stream_flash_ctx *ctx,
147 			       const char *settings_key);
148 
149 /**
150  * @brief Save persistent stream write progress using key @p settings_key .
151  *
152  * @param ctx context
153  * @param settings_key key to use with the settings module for storing
154  *                     the stream write progress
155  *
156  * @return non-negative on success, negative errno code on fail
157  */
158 int stream_flash_progress_save(struct stream_flash_ctx *ctx,
159 			       const char *settings_key);
160 
161 /**
162  * @brief Clear persistent stream write progress stored with key
163  *        @p settings_key .
164  *
165  * @param ctx context
166  * @param settings_key key previously used for storing the stream write progress
167  *
168  * @return non-negative on success, negative errno code on fail
169  */
170 int stream_flash_progress_clear(struct stream_flash_ctx *ctx,
171 				const char *settings_key);
172 
173 #ifdef __cplusplus
174 }
175 #endif
176 
177 /**
178  * @}
179  */
180 
181 #endif /* ZEPHYR_INCLUDE_STORAGE_STREAM_FLASH_H_ */
182