hal_mfs.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
  3. This file is part of ChibiOS.
  4. ChibiOS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. ChibiOS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. /**
  16. * @file hal_mfs.h
  17. * @brief Managed Flash Storage module header.
  18. *
  19. * @addtogroup HAL_MFS
  20. * @{
  21. */
  22. #ifndef HAL_MFS_H
  23. #define HAL_MFS_H
  24. #include "hal_flash.h"
  25. /*===========================================================================*/
  26. /* Driver constants. */
  27. /*===========================================================================*/
  28. #define MFS_BANK_MAGIC_1 0xEC705ADEU
  29. #define MFS_BANK_MAGIC_2 0xF0339CC5U
  30. #define MFS_HEADER_MAGIC 0x5FAE45F0U
  31. /*===========================================================================*/
  32. /* Driver pre-compile time settings. */
  33. /*===========================================================================*/
  34. /**
  35. * @name Configuration options
  36. * @{
  37. */
  38. /**
  39. * @brief Maximum number of indexed records in the managed storage.
  40. * @note Record indexes go from 0 to @p MFS_CFG_MAX_RECORDS - 1.
  41. */
  42. #if !defined(MFS_CFG_MAX_RECORDS) || defined(__DOXYGEN__)
  43. #define MFS_CFG_MAX_RECORDS 32
  44. #endif
  45. /**
  46. * @brief Maximum number of repair attempts on partition mount.
  47. */
  48. #if !defined(MFS_CFG_MAX_REPAIR_ATTEMPTS) || defined(__DOXYGEN__)
  49. #define MFS_CFG_MAX_REPAIR_ATTEMPTS 3
  50. #endif
  51. /**
  52. * @brief Verify written data.
  53. */
  54. #if !defined(MFS_CFG_WRITE_VERIFY) || defined(__DOXYGEN__)
  55. #define MFS_CFG_WRITE_VERIFY TRUE
  56. #endif
  57. /**
  58. * @brief Enables a stronger and slower check procedure on mount.
  59. * @details Strong checking requires reading of the whole written data and
  60. * this can be slow, normal checking only checks integrity of
  61. * metadata, data errors would be detected on read.
  62. */
  63. #if !defined(MFS_CFG_STRONG_CHECKING) || defined(__DOXYGEN__)
  64. #define MFS_CFG_STRONG_CHECKING TRUE
  65. #endif
  66. /**
  67. * @brief Size of the buffer used for data copying.
  68. * @note The buffer size must be a power of two and not smaller than
  69. * 16 bytes.
  70. * @note Larger buffers improve performance, buffers with size multiple
  71. * of the flash program page size work better.
  72. */
  73. #if !defined(MFS_CFG_BUFFER_SIZE) || defined(__DOXYGEN__)
  74. #define MFS_CFG_BUFFER_SIZE 32
  75. #endif
  76. /**
  77. * @brief Enforced memory alignment.
  78. * @details This value must be a power of two, it enforces a memory alignment
  79. * for records in the flash array. This is required when alignment
  80. * constraints exist, for example when using a DTR mode on OSPI
  81. * devices.
  82. * @note When enforcing an alignment you need to use buffers with size
  83. * aligned to the specified value. For example, if you need to
  84. * write a 5 bytes object with alignment of 4 then you need to
  85. * use a 8 bytes data buffer, the last 3 bytes are used as filler
  86. * so ==initialize== those to zero (buffer->DDDDD000) or garbage
  87. * will be written after data.
  88. */
  89. #if !defined(MFS_CFG_MEMORY_ALIGNMENT) || defined(__DOXYGEN__)
  90. #define MFS_CFG_MEMORY_ALIGNMENT 1
  91. #endif
  92. /** @} */
  93. /*===========================================================================*/
  94. /* Derived constants and error checks. */
  95. /*===========================================================================*/
  96. #if MFS_CFG_MAX_RECORDS < 0
  97. #error "invalid MFS_CFG_MAX_RECORDS value"
  98. #endif
  99. #if (MFS_CFG_MAX_REPAIR_ATTEMPTS < 1) || (MFS_CFG_MAX_REPAIR_ATTEMPTS > 10)
  100. #error "invalid MFS_MAX_REPAIR_ATTEMPTS value"
  101. #endif
  102. #if MFS_CFG_BUFFER_SIZE < 16
  103. #error "invalid MFS_CFG_BUFFER_SIZE value"
  104. #endif
  105. #if (MFS_CFG_BUFFER_SIZE & (MFS_CFG_BUFFER_SIZE - 1)) != 0
  106. #error "MFS_CFG_BUFFER_SIZE is not a power of two"
  107. #endif
  108. #if MFS_CFG_MEMORY_ALIGNMENT < 1
  109. #error "invalid MFS_CFG_MEMORY_ALIGNMENT value"
  110. #endif
  111. #if (MFS_CFG_MEMORY_ALIGNMENT & (MFS_CFG_MEMORY_ALIGNMENT - 1)) != 0
  112. #error "MFS_CFG_MEMORY_ALIGNMENT is not a power of two"
  113. #endif
  114. /*===========================================================================*/
  115. /* Driver data structures and types. */
  116. /*===========================================================================*/
  117. /**
  118. * @brief Type of a flash bank.
  119. */
  120. typedef enum {
  121. MFS_BANK_0 = 0,
  122. MFS_BANK_1 = 1
  123. } mfs_bank_t;
  124. /**
  125. * @brief Type of driver state machine states.
  126. */
  127. typedef enum {
  128. MFS_UNINIT = 0,
  129. MFS_STOP = 1,
  130. MFS_READY = 2,
  131. MFS_ERROR = 3
  132. } mfs_state_t;
  133. /**
  134. * @brief Type of an MFS error code.
  135. * @note Errors are negative integers, informative warnings are positive
  136. * integers.
  137. */
  138. typedef enum {
  139. MFS_NO_ERROR = 0,
  140. MFS_WARN_REPAIR = 1,
  141. MFS_WARN_GC = 2,
  142. MFS_ERR_INV_STATE = -1,
  143. MFS_ERR_INV_SIZE = -2,
  144. MFS_ERR_NOT_FOUND = -3,
  145. MFS_ERR_OUT_OF_MEM = -4,
  146. MFS_ERR_NOT_ERASED = -5,
  147. MFS_ERR_FLASH_FAILURE = -6,
  148. MFS_ERR_INTERNAL = -7
  149. } mfs_error_t;
  150. /**
  151. * @brief Type of a bank state assessment.
  152. */
  153. typedef enum {
  154. MFS_BANK_ERASED = 0,
  155. MFS_BANK_OK = 1,
  156. MFS_BANK_PARTIAL = 2,
  157. MFS_BANK_GARBAGE = 3
  158. } mfs_bank_state_t;
  159. /**
  160. * @brief Type of a record state assessment.
  161. */
  162. typedef enum {
  163. MFS_RECORD_ERASED = 0,
  164. MFS_RECORD_OK = 1,
  165. MFS_RECORD_CRC = 2,
  166. MFS_RECORD_GARBAGE = 3
  167. } mfs_record_state_t;
  168. /**
  169. * @brief Type of a record identifier.
  170. */
  171. typedef uint32_t mfs_id_t;
  172. /**
  173. * @brief Type of a bank header.
  174. * @note The header resides in the first 16 bytes of a bank.
  175. */
  176. typedef union {
  177. struct {
  178. /**
  179. * @brief Bank magic 1.
  180. */
  181. uint32_t magic1;
  182. /**
  183. * @brief Bank magic 2.
  184. */
  185. uint32_t magic2;
  186. /**
  187. * @brief Usage counter of the bank.
  188. * @details This value is increased each time a bank swap is performed. It
  189. * indicates how much wearing the flash has already endured.
  190. */
  191. uint32_t counter;
  192. /**
  193. * @brief Reserved field.
  194. */
  195. uint16_t reserved1;
  196. /**
  197. * @brief Header CRC.
  198. */
  199. uint16_t crc;
  200. } fields;
  201. uint8_t hdr8[16];
  202. uint32_t hdr32[4];
  203. } mfs_bank_header_t;
  204. /**
  205. * @brief Type of a data block header.
  206. * @details This structure is placed before each written data block.
  207. */
  208. typedef union {
  209. struct {
  210. /**
  211. * @brief Data header magic.
  212. */
  213. uint32_t magic;
  214. /**
  215. * @brief Data identifier.
  216. */
  217. uint16_t id;
  218. /**
  219. * @brief Data CRC.
  220. */
  221. uint16_t crc;
  222. /**
  223. * @brief Data size.
  224. * @note The next record is located at @p MFS_ALIGN_NEXT(size).
  225. */
  226. uint32_t size;
  227. } fields;
  228. uint8_t hdr8[12];
  229. uint32_t hdr32[3];
  230. } mfs_data_header_t;
  231. typedef struct {
  232. /**
  233. * @brief Offset of the record header.
  234. */
  235. flash_offset_t offset;
  236. /**
  237. * @brief Record data size.
  238. */
  239. uint32_t size;
  240. } mfs_record_descriptor_t;
  241. /**
  242. * @brief Type of a MFS configuration structure.
  243. */
  244. typedef struct {
  245. /**
  246. * @brief Flash driver associated to this MFS instance.
  247. */
  248. BaseFlash *flashp;
  249. /**
  250. * @brief Erased value.
  251. */
  252. uint32_t erased;
  253. /**
  254. * @brief Banks size.
  255. */
  256. flash_offset_t bank_size;
  257. /**
  258. * @brief Base sector index for bank 0.
  259. */
  260. flash_sector_t bank0_start;
  261. /**
  262. * @brief Number of sectors for bank 0.
  263. * @note The total size of bank0 sectors must be greater or equal to
  264. * @p bank_size.
  265. */
  266. flash_sector_t bank0_sectors;
  267. /**
  268. * @brief Base sector index for bank 1.
  269. */
  270. flash_sector_t bank1_start;
  271. /**
  272. * @brief Number of sectors for bank 1.
  273. * @note The total size of bank1 sectors must be greater or equal to
  274. * @p bank_size.
  275. */
  276. flash_sector_t bank1_sectors;
  277. } MFSConfig;
  278. /**
  279. * @extends BaseFlash
  280. *
  281. * @brief Type of an MFS instance.
  282. */
  283. typedef struct {
  284. /**
  285. * @brief Driver state.
  286. */
  287. mfs_state_t state;
  288. /**
  289. * @brief Current configuration data.
  290. */
  291. const MFSConfig *config;
  292. /**
  293. * @brief Bank currently in use.
  294. */
  295. mfs_bank_t current_bank;
  296. /**
  297. * @brief Usage counter of the current bank.
  298. */
  299. uint32_t current_counter;
  300. /**
  301. * @brief Pointer to the next free position in the current bank.
  302. */
  303. flash_offset_t next_offset;
  304. /**
  305. * @brief Used space in the current bank without considering erased records.
  306. */
  307. flash_offset_t used_space;
  308. /**
  309. * @brief Offsets of the most recent instance of the records.
  310. * @note Zero means that there is not a record with that id.
  311. */
  312. mfs_record_descriptor_t descriptors[MFS_CFG_MAX_RECORDS];
  313. /**
  314. * @brief Transient buffer.
  315. */
  316. union {
  317. mfs_data_header_t dhdr;
  318. mfs_bank_header_t bhdr;
  319. uint8_t data8[MFS_CFG_BUFFER_SIZE];
  320. uint16_t data16[MFS_CFG_BUFFER_SIZE / sizeof (uint16_t)];
  321. uint32_t data32[MFS_CFG_BUFFER_SIZE / sizeof (uint32_t)];
  322. } buffer;
  323. } MFSDriver;
  324. /*===========================================================================*/
  325. /* Driver macros. */
  326. /*===========================================================================*/
  327. /**
  328. * @name Error codes handling macros
  329. * @{
  330. */
  331. #define MFS_IS_ERROR(err) ((err) < MFS_NO_ERROR)
  332. #define MFS_IS_WARNING(err) ((err) > MFS_NO_ERROR)
  333. /** @} */
  334. /**
  335. * @name Alignment macros
  336. * @{
  337. */
  338. #define MFS_ALIGN_MASK ((uint32_t)MFS_CFG_MEMORY_ALIGNMENT - 1U)
  339. #define MFS_IS_ALIGNED(v) (((uint32_t)(v) & MFS_ALIGN_MASK) == 0U)
  340. #define MFS_ALIGN_PREV(v) ((uint32_t)(v) & ~MFS_ALIGN_MASK)
  341. #define MFS_ALIGN_NEXT(v) MFS_ALIGN_PREV((size_t)(v) + MFS_ALIGN_MASK)
  342. /** @} */
  343. /*===========================================================================*/
  344. /* External declarations. */
  345. /*===========================================================================*/
  346. #ifdef __cplusplus
  347. extern "C" {
  348. #endif
  349. void mfsObjectInit(MFSDriver *devp);
  350. mfs_error_t mfsStart(MFSDriver *devp, const MFSConfig *config);
  351. void mfsStop(MFSDriver *devp);
  352. mfs_error_t mfsErase(MFSDriver *mfsp);
  353. mfs_error_t mfsReadRecord(MFSDriver *devp, mfs_id_t id,
  354. size_t *np, uint8_t *buffer);
  355. mfs_error_t mfsWriteRecord(MFSDriver *devp, mfs_id_t id,
  356. size_t n, const uint8_t *buffer);
  357. mfs_error_t mfsEraseRecord(MFSDriver *devp, mfs_id_t id);
  358. mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp);
  359. #ifdef __cplusplus
  360. }
  361. #endif
  362. #endif /* HAL_MFS_H */
  363. /** @} */