ringfs.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright © 2014 Kosma Moczek <kosma@cloudyourcar.com>
  3. * This program is free software. It comes without any warranty, to the extent
  4. * permitted by applicable law. You can redistribute it and/or modify it under
  5. * the terms of the Do What The Fuck You Want To Public License, Version 2, as
  6. * published by Sam Hocevar. See the COPYING file for more details.
  7. */
  8. #ifndef RINGFS_H
  9. #define RINGFS_H
  10. /**
  11. * @defgroup ringfs_api RingFS API
  12. * @{
  13. */
  14. #include <stdint.h>
  15. #if defined ( __GNUC__ )
  16. #include <unistd.h>
  17. #endif
  18. #ifdef PRINTF_STDLIB
  19. #include <stdio.h>
  20. #endif
  21. #ifdef PRINTF_CUSTOM
  22. #include "tinystdio.h"
  23. #endif
  24. #if defined ( __ICCARM__ )
  25. typedef int ssize_t;
  26. #include <stdlib.h>
  27. #endif
  28. /**
  29. * Flash memory+parition descriptor.
  30. */
  31. struct ringfs_flash_partition
  32. {
  33. int sector_size; /**< Sector size, in bytes. */
  34. int sector_offset; /**< Partition offset, in sectors. */
  35. int sector_count; /**< Partition size, in sectors. */
  36. /**
  37. * Erase a sector.
  38. * @param address Any address inside the sector.
  39. * @returns Zero on success, -1 on failure.
  40. */
  41. int (*sector_erase)(struct ringfs_flash_partition *flash, int address);
  42. /**
  43. * Program flash memory bits by toggling them from 1 to 0.
  44. * @param address Start address, in bytes.
  45. * @param data Data to program.
  46. * @param size Size of data.
  47. * @returns size on success, -1 on failure.
  48. */
  49. ssize_t (*program)(struct ringfs_flash_partition *flash, int address, const void *data, size_t size);
  50. /**
  51. * Read flash memory.
  52. * @param address Start address, in bytes.
  53. * @param data Buffer to store read data.
  54. * @param size Size of data.
  55. * @returns size on success, -1 on failure.
  56. */
  57. ssize_t (*read)(struct ringfs_flash_partition *flash, int address, void *data, size_t size);
  58. };
  59. /** @private */
  60. struct ringfs_loc {
  61. int sector;
  62. int slot;
  63. };
  64. /**
  65. * RingFS instance. Should be initialized with ringfs_init() befure use.
  66. * Structure fields should not be accessed directly.
  67. * */
  68. struct ringfs {
  69. /* Constant values, set once at ringfs_init(). */
  70. struct ringfs_flash_partition *flash;
  71. uint32_t version;
  72. int object_size;
  73. /* Cached values. */
  74. int slots_per_sector;
  75. /* Read/write pointers. Modified as needed. */
  76. struct ringfs_loc read;
  77. struct ringfs_loc write;
  78. struct ringfs_loc cursor;
  79. int cursor_position;
  80. };
  81. /**
  82. * Initialize a RingFS instance. Must be called before the instance can be used
  83. * with the other ringfs_* functions.
  84. *
  85. * @param fs RingFS instance to be initialized.
  86. * @param flash Flash memory interface. Must be implemented externally.
  87. * @param version Object version. Should be incremented whenever the object's
  88. * semantics or size change in a backwards-incompatible way.
  89. * @param object_size Size of one stored object, in bytes.
  90. * @returns Zero on success, -1 on failure.
  91. */
  92. int ringfs_init(struct ringfs *fs, struct ringfs_flash_partition *flash, uint32_t version, int object_size);
  93. /**
  94. * Format the flash memory.
  95. *
  96. * @param fs Initialized RingFS instance.
  97. * @returns Zero on success, -1 on failure.
  98. */
  99. int ringfs_format(struct ringfs *fs);
  100. /**
  101. * Scan the flash memory for a valid filesystem.
  102. *
  103. * @param fs Initialized RingFS instance.
  104. * @returns Zero on success, -1 on failure.
  105. */
  106. int ringfs_scan(struct ringfs *fs);
  107. /**
  108. * Calculate maximum RingFS capacity.
  109. *
  110. * @param fs Initialized RingFS instance.
  111. * @returns Maximum capacity on success, -1 on failure.
  112. */
  113. int ringfs_capacity(struct ringfs *fs);
  114. /**
  115. * Calculate approximate object count.
  116. * Runs in O(1).
  117. *
  118. * @param fs Initialized RingFS instance.
  119. * @returns Estimated object count on success, -1 on failure.
  120. */
  121. int ringfs_count_estimate(struct ringfs *fs);
  122. /**
  123. * Calculate exact object count.
  124. * Runs in O(n).
  125. *
  126. * @param fs Initialized RingFS instance.
  127. * @returns Exact object count on success, -1 on failure.
  128. */
  129. int ringfs_count_exact(struct ringfs *fs);
  130. /**
  131. * Get current cursor position.
  132. *
  133. * @param fs Initialized RingFS instance.
  134. * @returns Current cursor position, -1 on failure.
  135. */
  136. int ringfs_cursor_position(struct ringfs *fs);
  137. /**
  138. * Append an object at the end of the ring. Deletes oldest objects as needed.
  139. *
  140. * @param fs Initialized RingFS instance.
  141. * @param object Object to be stored.
  142. * @returns Zero on success, -1 on failure.
  143. */
  144. int ringfs_append(struct ringfs *fs, const void *object);
  145. /**
  146. * Fetch next object from the ring, oldest-first. Advances read cursor.
  147. *
  148. * @param fs Initialized RingFS instance.
  149. * @param object Buffer to store retrieved object.
  150. * @returns Zero on success, -1 on failure.
  151. */
  152. int ringfs_fetch(struct ringfs *fs, void *object);
  153. /**
  154. * Discard all fetched objects up to the read cursor.
  155. *
  156. * @param fs Initialized RingFS instance.
  157. * @returns Zero on success, -1 on failure.
  158. */
  159. int ringfs_discard(struct ringfs *fs);
  160. /**
  161. * Rewind the read cursor back to the oldest object.
  162. *
  163. * @param fs Initialized RingFS instance.
  164. * @returns Zero on success, -1 on failure.
  165. */
  166. int ringfs_rewind(struct ringfs *fs);
  167. /**
  168. * @}
  169. */
  170. #endif
  171. /* vim: set ts=4 sw=4 et: */