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