Line data Source code
1 1 : /*
2 : * Copyright (c) 2017-2024 Nordic Semiconductor ASA
3 : * Copyright (c) 2015 Runtime Inc
4 : * Copyright (c) 2023 Sensorfy B.V.
5 : *
6 : * SPDX-License-Identifier: Apache-2.0
7 : */
8 :
9 : /**
10 : * @file
11 : * @brief Public API for flash map
12 : */
13 :
14 : #ifndef ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_
15 : #define ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_
16 :
17 : /**
18 : * @brief Abstraction over flash partitions/areas and their drivers
19 : *
20 : * @defgroup flash_area_api flash area Interface
21 : * @since 1.11
22 : * @version 1.0.0
23 : * @ingroup storage_apis
24 : * @{
25 : */
26 :
27 : /*
28 : * This API makes it possible to operate on flash areas easily and
29 : * effectively.
30 : *
31 : * The system contains global data about flash areas. Every area
32 : * contains an ID number, offset, and length.
33 : */
34 :
35 : /**
36 : *
37 : */
38 : #include <zephyr/types.h>
39 : #include <stddef.h>
40 : #include <sys/types.h>
41 : #include <zephyr/device.h>
42 : #include <zephyr/devicetree.h>
43 :
44 : #ifdef __cplusplus
45 : extern "C" {
46 : #endif
47 :
48 : /**
49 : * @brief Flash partition
50 : *
51 : * This structure represents a fixed-size partition on a flash device.
52 : * Each partition contains one or more flash sectors.
53 : */
54 1 : struct flash_area {
55 : /** ID number */
56 1 : uint8_t fa_id;
57 0 : uint16_t pad16;
58 : /** Start offset from the beginning of the flash device */
59 1 : off_t fa_off;
60 : /** Total size */
61 1 : size_t fa_size;
62 : /** Backing flash device */
63 1 : const struct device *fa_dev;
64 : #if CONFIG_FLASH_MAP_LABELS
65 : /** Partition label if defined in DTS. Otherwise nullptr; */
66 : const char *fa_label;
67 : #endif
68 : };
69 :
70 : /**
71 : * @brief Structure for transfer flash sector boundaries
72 : *
73 : * This template is used for presentation of flash memory structure. It
74 : * consumes much less RAM than @ref flash_area
75 : */
76 1 : struct flash_sector {
77 : /** Sector offset from the beginning of the flash device */
78 1 : off_t fs_off;
79 : /** Sector size in bytes */
80 1 : size_t fs_size;
81 : };
82 :
83 : #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY)
84 : /**
85 : * @brief Structure for verify flash region integrity
86 : *
87 : * This is used to pass data to be used to check flash integrity using SHA-256
88 : * algorithm.
89 : */
90 : struct flash_area_check {
91 : const uint8_t *match; /** 256 bits match vector */
92 : size_t clen; /** Content len to be compared */
93 : size_t off; /** Start Offset */
94 : uint8_t *rbuf; /** Temporary read buffer */
95 : size_t rblen; /** Size of read buffer */
96 : };
97 :
98 : /**
99 : * Verify flash memory length bytes integrity from a flash area. The start
100 : * point is indicated by an offset value.
101 : *
102 : * @param[in] fa Flash area
103 : * @param[in] fic Flash area check integrity data
104 : *
105 : * @return 0 on success, negative errno code on fail
106 : */
107 : int flash_area_check_int_sha256(const struct flash_area *fa,
108 : const struct flash_area_check *fac);
109 : #endif
110 :
111 : /**
112 : * @brief Retrieve partitions flash area from the flash_map.
113 : *
114 : * Function Retrieves flash_area from flash_map for given partition.
115 : *
116 : * @param[in] id ID of the flash partition.
117 : * @param[out] fa Pointer which has to reference flash_area. If
118 : * @p ID is unknown, it will be NULL on output.
119 : *
120 : * @return 0 on success, -EACCES if the flash_map is not available ,
121 : * -ENOENT if @p ID is unknown, -ENODEV if there is no driver attached
122 : * to the area.
123 : */
124 1 : int flash_area_open(uint8_t id, const struct flash_area **fa);
125 :
126 : /**
127 : * @brief Close flash_area
128 : *
129 : * Reserved for future usage and external projects compatibility reason.
130 : * Currently is NOP.
131 : *
132 : * @param[in] fa Flash area to be closed.
133 : */
134 1 : void flash_area_close(const struct flash_area *fa);
135 :
136 : /**
137 : * @brief Verify that a device assigned to flash area is ready for use.
138 : *
139 : * Indicates whether the provided flash area has a device known to be
140 : * in a state where it can be used with Flash Map API.
141 : *
142 : * This can be used with struct flash_area pointers captured from FIXED_PARTITION().
143 : * At minimum this means that the device has been successfully initialized.
144 : *
145 : * @param fa pointer to flash_area object to check.
146 : *
147 : * @retval true If the device is ready for use.
148 : * @retval false If the device is not ready for use or if a NULL pointer is
149 : * passed as flash area pointer or device pointer within flash area object
150 : * is NULL.
151 : */
152 1 : static ALWAYS_INLINE bool flash_area_device_is_ready(const struct flash_area *fa)
153 : {
154 : return (fa != NULL && device_is_ready(fa->fa_dev));
155 : }
156 :
157 : /**
158 : * @brief Read flash area data
159 : *
160 : * Read data from flash area. Area readout boundaries are asserted before read
161 : * request. API has the same limitation regard read-block alignment and size
162 : * as wrapped flash driver.
163 : *
164 : * @param[in] fa Flash area
165 : * @param[in] off Offset relative from beginning of flash area to read
166 : * @param[out] dst Buffer to store read data
167 : * @param[in] len Number of bytes to read
168 : *
169 : * @return 0 on success, negative errno code on fail.
170 : */
171 1 : int flash_area_read(const struct flash_area *fa, off_t off, void *dst,
172 : size_t len);
173 :
174 : /**
175 : * @brief Write data to flash area
176 : *
177 : * Write data to flash area. Area write boundaries are asserted before write
178 : * request. API has the same limitation regard write-block alignment and size
179 : * as wrapped flash driver.
180 : *
181 : * @param[in] fa Flash area
182 : * @param[in] off Offset relative from beginning of flash area to write
183 : * @param[in] src Buffer with data to be written
184 : * @param[in] len Number of bytes to write
185 : *
186 : * @return 0 on success, negative errno code on fail.
187 : */
188 1 : int flash_area_write(const struct flash_area *fa, off_t off, const void *src,
189 : size_t len);
190 :
191 : /**
192 : * @brief Copy flash memory from one flash area to another.
193 : *
194 : * Copy data to flash area. Area boundaries are asserted before copy
195 : * request.
196 : *
197 : * For more information, see flash_copy().
198 : *
199 : * @param[in] src_fa Source Flash area
200 : * @param[in] src_off Offset relative from beginning of source flash area.
201 : * @param[in] dst_fa Destination Flash area
202 : * @param[in] dst_off Offset relative from beginning of destination flash area.
203 : * @param[in] len Number of bytes to copy, in bytes.
204 : * @param[out] buf Pointer to a buffer of size @a buf_size.
205 : * @param[in] buf_size Size of the buffer pointed to by @a buf.
206 : *
207 : * @return 0 on success, negative errno code on fail.
208 : */
209 1 : int flash_area_copy(const struct flash_area *src_fa, off_t src_off,
210 : const struct flash_area *dst_fa, off_t dst_off,
211 : off_t len, uint8_t *buf, size_t buf_size);
212 :
213 : /**
214 : * @brief Erase flash area
215 : *
216 : * Erase given flash area range. Area boundaries are asserted before erase
217 : * request. API has the same limitation regard erase-block alignment and size
218 : * as wrapped flash driver.
219 : *
220 : * @param[in] fa Flash area
221 : * @param[in] off Offset relative from beginning of flash area.
222 : * @param[in] len Number of bytes to be erase
223 : *
224 : * @return 0 on success, negative errno code on fail.
225 : */
226 1 : int flash_area_erase(const struct flash_area *fa, off_t off, size_t len);
227 :
228 : /**
229 : * @brief Erase flash area or fill with erase-value
230 : *
231 : * On program-erase devices this function behaves exactly like flash_area_erase.
232 : * On RAM non-volatile device it will call erase, if driver provides such
233 : * callback, or will fill given range with erase-value defined by driver.
234 : * This function should be only used by code that has not been written
235 : * to directly support devices that do not require erase and rely on
236 : * device being erased prior to some operations.
237 : * Note that emulated erase, on devices that do not require, is done
238 : * via write, which affects endurance of device.
239 : *
240 : * @see flash_area_erase()
241 : * @see flash_flatten()
242 : *
243 : * @param[in] fa Flash area
244 : * @param[in] off Offset relative from beginning of flash area.
245 : * @param[in] len Number of bytes to be erase
246 : *
247 : * @return 0 on success, negative errno code on fail.
248 : */
249 1 : int flash_area_flatten(const struct flash_area *fa, off_t off, size_t len);
250 :
251 : /**
252 : * @brief Get write block size of the flash area
253 : *
254 : * Currently write block size might be treated as read block size, although
255 : * most of drivers supports unaligned readout.
256 : *
257 : * @param[in] fa Flash area
258 : *
259 : * @return Alignment restriction for flash writes in [B].
260 : */
261 1 : uint32_t flash_area_align(const struct flash_area *fa);
262 :
263 : /**
264 : * Retrieve info about sectors within the area.
265 : *
266 : * @param[in] fa_id Given flash area ID
267 : * @param[in,out] count On input Capacity of @p sectors, on output number of
268 : * sectors Retrieved.
269 : * @param[out] sectors buffer for sectors data
270 : *
271 : * @return 0 on success, negative errno code on fail. Especially returns
272 : * -ENOMEM if There are too many flash pages on the flash_area to fit in the
273 : * array.
274 : */
275 1 : int flash_area_get_sectors(int fa_id, uint32_t *count,
276 : struct flash_sector *sectors);
277 :
278 : /**
279 : * Retrieve info about sectors within the area.
280 : *
281 : * @param[in] fa pointer to flash area object.
282 : * @param[in,out] count On input Capacity of @p sectors, on output number of
283 : * sectors retrieved.
284 : * @param[out] sectors buffer for sectors data
285 : *
286 : * @return 0 on success, negative errno code on fail. Especially returns
287 : * -ENOMEM if There are too many flash pages on the flash_area to fit in the
288 : * array.
289 : */
290 1 : int flash_area_sectors(const struct flash_area *fa, uint32_t *count, struct flash_sector *sectors);
291 :
292 : /**
293 : * Flash map iteration callback
294 : *
295 : * @param fa flash area
296 : * @param user_data User supplied data
297 : *
298 : */
299 1 : typedef void (*flash_area_cb_t)(const struct flash_area *fa,
300 : void *user_data);
301 :
302 : /**
303 : * Iterate over flash map
304 : *
305 : * @param user_cb User callback
306 : * @param user_data User supplied data
307 : */
308 1 : void flash_area_foreach(flash_area_cb_t user_cb, void *user_data);
309 :
310 : /**
311 : * Check whether given flash area has supporting flash driver
312 : * in the system.
313 : *
314 : * @param[in] fa Flash area.
315 : *
316 : * @return 1 On success. -ENODEV if no driver match.
317 : */
318 1 : int flash_area_has_driver(const struct flash_area *fa);
319 :
320 : /**
321 : * Get driver for given flash area.
322 : *
323 : * @param[in] fa Flash area.
324 : *
325 : * @return device driver.
326 : */
327 1 : const struct device *flash_area_get_device(const struct flash_area *fa);
328 :
329 : #if CONFIG_FLASH_MAP_LABELS
330 : /**
331 : * Get the label property from the device tree
332 : *
333 : * @param[in] fa Flash area.
334 : *
335 : * @return The label property if it is defined, otherwise NULL
336 : */
337 : const char *flash_area_label(const struct flash_area *fa);
338 : #endif
339 :
340 : /**
341 : * Get the value expected to be read when accessing any erased
342 : * flash byte.
343 : * This API is compatible with the MCUBoot's porting layer.
344 : *
345 : * @param fa Flash area.
346 : *
347 : * @return Byte value of erase memory.
348 : */
349 1 : uint8_t flash_area_erased_val(const struct flash_area *fa);
350 :
351 : /**
352 : * Returns non-0 value if fixed-partition of given DTS node label exists.
353 : *
354 : * @param label DTS node label
355 : *
356 : * @return non-0 if fixed-partition node exists and is enabled;
357 : * 0 if node does not exist, is not enabled or is not fixed-partition.
358 : */
359 1 : #define FIXED_PARTITION_EXISTS(label) DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(label))
360 :
361 : /**
362 : * Get flash area ID from fixed-partition DTS node label
363 : *
364 : * @param label DTS node label of a partition
365 : *
366 : * @return flash area ID
367 : */
368 1 : #define FIXED_PARTITION_ID(label) DT_FIXED_PARTITION_ID(DT_NODELABEL(label))
369 :
370 : /**
371 : * Get fixed-partition offset from DTS node label
372 : *
373 : * @param label DTS node label of a partition
374 : *
375 : * @return fixed-partition offset, as defined for the partition in DTS.
376 : */
377 1 : #define FIXED_PARTITION_OFFSET(label) DT_REG_ADDR(DT_NODELABEL(label))
378 :
379 : /**
380 : * Get fixed-partition offset from DTS node
381 : *
382 : * @param node DTS node of a partition
383 : *
384 : * @return fixed-partition offset, as defined for the partition in DTS.
385 : */
386 1 : #define FIXED_PARTITION_NODE_OFFSET(node) DT_REG_ADDR(node)
387 :
388 : /**
389 : * Get fixed-partition size for DTS node label
390 : *
391 : * @param label DTS node label
392 : *
393 : * @return fixed-partition offset, as defined for the partition in DTS.
394 : */
395 1 : #define FIXED_PARTITION_SIZE(label) DT_REG_SIZE(DT_NODELABEL(label))
396 :
397 : /**
398 : * Get fixed-partition size for DTS node
399 : *
400 : * @param node DTS node of a partition
401 : *
402 : * @return fixed-partition size, as defined for the partition in DTS.
403 : */
404 1 : #define FIXED_PARTITION_NODE_SIZE(node) DT_REG_SIZE(node)
405 :
406 : /**
407 : * Get device pointer for device the area/partition resides on
408 : *
409 : * @param label DTS node label of a partition
410 : *
411 : * @return const struct device type pointer
412 : */
413 1 : #define FLASH_AREA_DEVICE(label) \
414 : DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODE_BY_FIXED_PARTITION_LABEL(label)))
415 :
416 : /**
417 : * Get device pointer for device the area/partition resides on
418 : *
419 : * @param label DTS node label of a partition
420 : *
421 : * @return Pointer to a device.
422 : */
423 1 : #define FIXED_PARTITION_DEVICE(label) \
424 : DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label)))
425 :
426 : /**
427 : * Get device pointer for device the area/partition resides on
428 : *
429 : * @param node DTS node of a partition
430 : *
431 : * @return Pointer to a device.
432 : */
433 1 : #define FIXED_PARTITION_NODE_DEVICE(node) \
434 : DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(node))
435 :
436 : /**
437 : * Get pointer to flash_area object by partition label
438 : *
439 : * @param label DTS node label of a partition
440 : *
441 : * @return Pointer to flash_area type object representing partition
442 : */
443 1 : #define FIXED_PARTITION(label) FIXED_PARTITION_1(DT_NODELABEL(label))
444 :
445 : /**
446 : * Get pointer to flash_area object by partition node in DTS
447 : *
448 : * @param node DTS node of a partition
449 : *
450 : * @return Pointer to flash_area type object representing partition
451 : */
452 1 : #define FIXED_PARTITION_BY_NODE(node) FIXED_PARTITION_1(node)
453 :
454 : /** @cond INTERNAL_HIDDEN */
455 : #define FIXED_PARTITION_1(node) FIXED_PARTITION_0(DT_DEP_ORD(node))
456 : #define FIXED_PARTITION_0(ord) \
457 : ((const struct flash_area *)&DT_CAT(global_fixed_partition_ORD_, ord))
458 :
459 : #define DECLARE_PARTITION(node) DECLARE_PARTITION_0(DT_DEP_ORD(node))
460 : #define DECLARE_PARTITION_0(ord) \
461 : extern const struct flash_area DT_CAT(global_fixed_partition_ORD_, ord);
462 : #define FOR_EACH_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DECLARE_PARTITION)
463 :
464 : /* Generate declarations */
465 : DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE)
466 :
467 : #undef DECLARE_PARTITION
468 : #undef DECLARE_PARTITION_0
469 : #undef FOR_EACH_PARTITION_TABLE
470 : /** @endcond */
471 :
472 : #ifdef __cplusplus
473 : }
474 : #endif
475 :
476 : /**
477 : * @}
478 : */
479 :
480 : #endif /* ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_ */
|