flash_page_layout.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (c) 2017 Nordic Semiconductor ASA
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <drivers/flash.h>
  7. static int flash_get_page_info(const struct device *dev, off_t offs,
  8. uint32_t index, struct flash_pages_info *info)
  9. {
  10. const struct flash_driver_api *api = dev->api;
  11. const struct flash_pages_layout *layout;
  12. size_t layout_size;
  13. uint32_t index_jmp;
  14. info->start_offset = 0;
  15. info->index = 0U;
  16. api->page_layout(dev, &layout, &layout_size);
  17. while (layout_size--) {
  18. info->size = layout->pages_size;
  19. if (offs == 0) {
  20. index_jmp = index - info->index;
  21. } else {
  22. index_jmp = (offs - info->start_offset) / info->size;
  23. }
  24. index_jmp = MIN(index_jmp, layout->pages_count);
  25. info->start_offset += (index_jmp * info->size);
  26. info->index += index_jmp;
  27. if (index_jmp < layout->pages_count) {
  28. return 0;
  29. }
  30. layout++;
  31. }
  32. return -EINVAL; /* page at offs or idx doesn't exist */
  33. }
  34. int z_impl_flash_get_page_info_by_offs(const struct device *dev, off_t offs,
  35. struct flash_pages_info *info)
  36. {
  37. return flash_get_page_info(dev, offs, 0U, info);
  38. }
  39. int z_impl_flash_get_page_info_by_idx(const struct device *dev,
  40. uint32_t page_index,
  41. struct flash_pages_info *info)
  42. {
  43. return flash_get_page_info(dev, 0, page_index, info);
  44. }
  45. size_t z_impl_flash_get_page_count(const struct device *dev)
  46. {
  47. const struct flash_driver_api *api = dev->api;
  48. const struct flash_pages_layout *layout;
  49. size_t layout_size;
  50. size_t count = 0;
  51. api->page_layout(dev, &layout, &layout_size);
  52. while (layout_size--) {
  53. count += layout->pages_count;
  54. layout++;
  55. }
  56. return count;
  57. }
  58. void flash_page_foreach(const struct device *dev, flash_page_cb cb,
  59. void *data)
  60. {
  61. const struct flash_driver_api *api = dev->api;
  62. const struct flash_pages_layout *layout;
  63. struct flash_pages_info page_info;
  64. size_t block, num_blocks, page = 0, i;
  65. off_t off = 0;
  66. api->page_layout(dev, &layout, &num_blocks);
  67. for (block = 0; block < num_blocks; block++) {
  68. const struct flash_pages_layout *l = &layout[block];
  69. page_info.size = l->pages_size;
  70. for (i = 0; i < l->pages_count; i++) {
  71. page_info.start_offset = off;
  72. page_info.index = page;
  73. if (!cb(&page_info, data)) {
  74. return;
  75. }
  76. off += page_info.size;
  77. page++;
  78. }
  79. }
  80. }