Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | /* * Copyright (c) 2017 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include <drivers/flash.h> static int flash_get_page_info(const struct device *dev, off_t offs, bool use_addr, struct flash_pages_info *info) { const struct flash_driver_api *api = dev->api; const struct flash_pages_layout *layout; size_t page_count = 0; off_t group_offs = 0; uint32_t num_in_group; off_t end = 0; size_t layout_size; api->page_layout(dev, &layout, &layout_size); while (layout_size--) { if (use_addr) { end += layout->pages_count * layout->pages_size; } else { end += layout->pages_count; } if (offs < end) { info->size = layout->pages_size; if (use_addr) { num_in_group = (offs - group_offs) / layout->pages_size; } else { num_in_group = offs - page_count; } info->start_offset = group_offs + num_in_group * layout->pages_size; info->index = page_count + num_in_group; return 0; } group_offs += layout->pages_count * layout->pages_size; page_count += layout->pages_count; layout++; } return -EINVAL; /* page of the index doesn't exist */ } int z_impl_flash_get_page_info_by_offs(const struct device *dev, off_t offs, struct flash_pages_info *info) { return flash_get_page_info(dev, offs, true, info); } int z_impl_flash_get_page_info_by_idx(const struct device *dev, uint32_t page_index, struct flash_pages_info *info) { return flash_get_page_info(dev, page_index, false, info); } size_t z_impl_flash_get_page_count(const struct device *dev) { const struct flash_driver_api *api = dev->api; const struct flash_pages_layout *layout; size_t layout_size; size_t count = 0; api->page_layout(dev, &layout, &layout_size); while (layout_size--) { count += layout->pages_count; layout++; } return count; } void flash_page_foreach(const struct device *dev, flash_page_cb cb, void *data) { const struct flash_driver_api *api = dev->api; const struct flash_pages_layout *layout; struct flash_pages_info page_info; size_t block, num_blocks, page = 0, i; off_t off = 0; api->page_layout(dev, &layout, &num_blocks); for (block = 0; block < num_blocks; block++) { const struct flash_pages_layout *l = &layout[block]; page_info.size = l->pages_size; for (i = 0; i < l->pages_count; i++) { page_info.start_offset = off; page_info.index = page; if (!cb(&page_info, data)) { return; } off += page_info.size; page++; } } } |