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 /** Provided for compatibility with MCUboot */ 49 #define SOC_FLASH_0_ID 0 50 /** Provided for compatibility with MCUboot */ 51 #define SPI_FLASH_0_ID 1 52 53 /** 54 * @brief Flash partition 55 * 56 * This structure represents a fixed-size partition on a flash device. 57 * Each partition contains one or more flash sectors. 58 */ 59 struct flash_area { 60 /** ID number */ 61 uint8_t fa_id; 62 uint16_t pad16; 63 /** Start offset from the beginning of the flash device */ 64 off_t fa_off; 65 /** Total size */ 66 size_t fa_size; 67 /** Backing flash device */ 68 const struct device *fa_dev; 69 #if CONFIG_FLASH_MAP_LABELS 70 /** Partition label if defined in DTS. Otherwise nullptr; */ 71 const char *fa_label; 72 #endif 73 }; 74 75 /** 76 * @brief Structure for transfer flash sector boundaries 77 * 78 * This template is used for presentation of flash memory structure. It 79 * consumes much less RAM than @ref flash_area 80 */ 81 struct flash_sector { 82 /** Sector offset from the beginning of the flash device */ 83 off_t fs_off; 84 /** Sector size in bytes */ 85 size_t fs_size; 86 }; 87 88 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY) 89 /** 90 * @brief Structure for verify flash region integrity 91 * 92 * This is used to pass data to be used to check flash integrity using SHA-256 93 * algorithm. 94 */ 95 struct flash_area_check { 96 const uint8_t *match; /** 256 bits match vector */ 97 size_t clen; /** Content len to be compared */ 98 size_t off; /** Start Offset */ 99 uint8_t *rbuf; /** Temporary read buffer */ 100 size_t rblen; /** Size of read buffer */ 101 }; 102 103 /** 104 * Verify flash memory length bytes integrity from a flash area. The start 105 * point is indicated by an offset value. 106 * 107 * @param[in] fa Flash area 108 * @param[in] fic Flash area check integrity data 109 * 110 * @return 0 on success, negative errno code on fail 111 */ 112 int flash_area_check_int_sha256(const struct flash_area *fa, 113 const struct flash_area_check *fac); 114 #endif 115 116 /** 117 * @brief Retrieve partitions flash area from the flash_map. 118 * 119 * Function Retrieves flash_area from flash_map for given partition. 120 * 121 * @param[in] id ID of the flash partition. 122 * @param[out] fa Pointer which has to reference flash_area. If 123 * @p ID is unknown, it will be NULL on output. 124 * 125 * @return 0 on success, -EACCES if the flash_map is not available , 126 * -ENOENT if @p ID is unknown, -ENODEV if there is no driver attached 127 * to the area. 128 */ 129 int flash_area_open(uint8_t id, const struct flash_area **fa); 130 131 /** 132 * @brief Close flash_area 133 * 134 * Reserved for future usage and external projects compatibility reason. 135 * Currently is NOP. 136 * 137 * @param[in] fa Flash area to be closed. 138 */ 139 void flash_area_close(const struct flash_area *fa); 140 141 /** 142 * @brief Read flash area data 143 * 144 * Read data from flash area. Area readout boundaries are asserted before read 145 * request. API has the same limitation regard read-block alignment and size 146 * as wrapped flash driver. 147 * 148 * @param[in] fa Flash area 149 * @param[in] off Offset relative from beginning of flash area to read 150 * @param[out] dst Buffer to store read data 151 * @param[in] len Number of bytes to read 152 * 153 * @return 0 on success, negative errno code on fail. 154 */ 155 int flash_area_read(const struct flash_area *fa, off_t off, void *dst, 156 size_t len); 157 158 /** 159 * @brief Write data to flash area 160 * 161 * Write data to flash area. Area write boundaries are asserted before write 162 * request. API has the same limitation regard write-block alignment and size 163 * as wrapped flash driver. 164 * 165 * @param[in] fa Flash area 166 * @param[in] off Offset relative from beginning of flash area to write 167 * @param[in] src Buffer with data to be written 168 * @param[in] len Number of bytes to write 169 * 170 * @return 0 on success, negative errno code on fail. 171 */ 172 int flash_area_write(const struct flash_area *fa, off_t off, const void *src, 173 size_t len); 174 175 /** 176 * @brief Erase flash area 177 * 178 * Erase given flash area range. Area boundaries are asserted before erase 179 * request. API has the same limitation regard erase-block alignment and size 180 * as wrapped flash driver. 181 * 182 * @param[in] fa Flash area 183 * @param[in] off Offset relative from beginning of flash area. 184 * @param[in] len Number of bytes to be erase 185 * 186 * @return 0 on success, negative errno code on fail. 187 */ 188 int flash_area_erase(const struct flash_area *fa, off_t off, size_t len); 189 190 /** 191 * @brief Erase flash area or fill with erase-value 192 * 193 * On program-erase devices this function behaves exactly like flash_area_erase. 194 * On RAM non-volatile device it will call erase, if driver provides such 195 * callback, or will fill given range with erase-value defined by driver. 196 * This function should be only used by code that has not been written 197 * to directly support devices that do not require erase and rely on 198 * device being erased prior to some operations. 199 * Note that emulated erase, on devices that do not require, is done 200 * via write, which affects endurance of device. 201 * 202 * @see flash_area_erase() 203 * @see flash_flatten() 204 * 205 * @param[in] fa Flash area 206 * @param[in] off Offset relative from beginning of flash area. 207 * @param[in] len Number of bytes to be erase 208 * 209 * @return 0 on success, negative errno code on fail. 210 */ 211 int flash_area_flatten(const struct flash_area *fa, off_t off, size_t len); 212 213 /** 214 * @brief Get write block size of the flash area 215 * 216 * Currently write block size might be treated as read block size, although 217 * most of drivers supports unaligned readout. 218 * 219 * @param[in] fa Flash area 220 * 221 * @return Alignment restriction for flash writes in [B]. 222 */ 223 uint32_t flash_area_align(const struct flash_area *fa); 224 225 /** 226 * Retrieve info about sectors within the area. 227 * 228 * @param[in] fa_id Given flash area ID 229 * @param[out] sectors buffer for sectors data 230 * @param[in,out] count On input Capacity of @p sectors, on output number of 231 * sectors Retrieved. 232 * 233 * @return 0 on success, negative errno code on fail. Especially returns 234 * -ENOMEM if There are too many flash pages on the flash_area to fit in the 235 * array. 236 */ 237 int flash_area_get_sectors(int fa_id, uint32_t *count, 238 struct flash_sector *sectors); 239 240 /** 241 * Flash map iteration callback 242 * 243 * @param fa flash area 244 * @param user_data User supplied data 245 * 246 */ 247 typedef void (*flash_area_cb_t)(const struct flash_area *fa, 248 void *user_data); 249 250 /** 251 * Iterate over flash map 252 * 253 * @param user_cb User callback 254 * @param user_data User supplied data 255 */ 256 void flash_area_foreach(flash_area_cb_t user_cb, void *user_data); 257 258 /** 259 * Check whether given flash area has supporting flash driver 260 * in the system. 261 * 262 * @param[in] fa Flash area. 263 * 264 * @return 1 On success. -ENODEV if no driver match. 265 */ 266 int flash_area_has_driver(const struct flash_area *fa); 267 268 /** 269 * Get driver for given flash area. 270 * 271 * @param[in] fa Flash area. 272 * 273 * @return device driver. 274 */ 275 const struct device *flash_area_get_device(const struct flash_area *fa); 276 277 #if CONFIG_FLASH_MAP_LABELS 278 /** 279 * Get the label property from the device tree 280 * 281 * @param[in] fa Flash area. 282 * 283 * @return The label property if it is defined, otherwise NULL 284 */ 285 const char *flash_area_label(const struct flash_area *fa); 286 #endif 287 288 /** 289 * Get the value expected to be read when accessing any erased 290 * flash byte. 291 * This API is compatible with the MCUBoot's porting layer. 292 * 293 * @param fa Flash area. 294 * 295 * @return Byte value of erase memory. 296 */ 297 uint8_t flash_area_erased_val(const struct flash_area *fa); 298 299 /** 300 * Returns non-0 value if fixed-partition of given DTS node label exists. 301 * 302 * @param label DTS node label 303 * 304 * @return non-0 if fixed-partition node exists and is enabled; 305 * 0 if node does not exist, is not enabled or is not fixed-partition. 306 */ 307 #define FIXED_PARTITION_EXISTS(label) DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(label)) 308 309 /** 310 * Get flash area ID from fixed-partition DTS node label 311 * 312 * @param label DTS node label of a partition 313 * 314 * @return flash area ID 315 */ 316 #define FIXED_PARTITION_ID(label) DT_FIXED_PARTITION_ID(DT_NODELABEL(label)) 317 318 /** 319 * Get fixed-partition offset from DTS node label 320 * 321 * @param label DTS node label of a partition 322 * 323 * @return fixed-partition offset, as defined for the partition in DTS. 324 */ 325 #define FIXED_PARTITION_OFFSET(label) DT_REG_ADDR(DT_NODELABEL(label)) 326 327 /** 328 * Get fixed-partition offset from DTS node 329 * 330 * @param node DTS node of a partition 331 * 332 * @return fixed-partition offset, as defined for the partition in DTS. 333 */ 334 #define FIXED_PARTITION_NODE_OFFSET(node) DT_REG_ADDR(node) 335 336 /** 337 * Get fixed-partition size for DTS node label 338 * 339 * @param label DTS node label 340 * 341 * @return fixed-partition offset, as defined for the partition in DTS. 342 */ 343 #define FIXED_PARTITION_SIZE(label) DT_REG_SIZE(DT_NODELABEL(label)) 344 345 /** 346 * Get fixed-partition size for DTS node 347 * 348 * @param node DTS node of a partition 349 * 350 * @return fixed-partition size, as defined for the partition in DTS. 351 */ 352 #define FIXED_PARTITION_NODE_SIZE(node) DT_REG_SIZE(node) 353 354 /** 355 * Get device pointer for device the area/partition resides on 356 * 357 * @param label DTS node label of a partition 358 * 359 * @return const struct device type pointer 360 */ 361 #define FLASH_AREA_DEVICE(label) \ 362 DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODE_BY_FIXED_PARTITION_LABEL(label))) 363 364 /** 365 * Get device pointer for device the area/partition resides on 366 * 367 * @param label DTS node label of a partition 368 * 369 * @return Pointer to a device. 370 */ 371 #define FIXED_PARTITION_DEVICE(label) \ 372 DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) 373 374 /** 375 * Get device pointer for device the area/partition resides on 376 * 377 * @param node DTS node of a partition 378 * 379 * @return Pointer to a device. 380 */ 381 #define FIXED_PARTITION_NODE_DEVICE(node) \ 382 DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(node)) 383 384 #ifdef __cplusplus 385 } 386 #endif 387 388 /** 389 * @} 390 */ 391 392 #endif /* ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_ */ 393