AP_FlashStorage.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /*
  2. Please contribute your ideas! See http://dev.ardupilot.org for details
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <AP_HAL/AP_HAL.h>
  15. #include <AP_FlashStorage/AP_FlashStorage.h>
  16. #include <AP_Math/AP_Math.h>
  17. #include <stdio.h>
  18. #define FLASHSTORAGE_DEBUG 0
  19. #if FLASHSTORAGE_DEBUG
  20. #define debug(fmt, args...) do { printf(fmt, ##args); } while(0)
  21. #else
  22. #define debug(fmt, args...) do { } while(0)
  23. #endif
  24. // constructor.
  25. AP_FlashStorage::AP_FlashStorage(uint8_t *_mem_buffer,
  26. uint32_t _flash_sector_size,
  27. FlashWrite _flash_write,
  28. FlashRead _flash_read,
  29. FlashErase _flash_erase,
  30. FlashEraseOK _flash_erase_ok) :
  31. mem_buffer(_mem_buffer),
  32. flash_sector_size(_flash_sector_size),
  33. flash_write(_flash_write),
  34. flash_read(_flash_read),
  35. flash_erase(_flash_erase),
  36. flash_erase_ok(_flash_erase_ok) {}
  37. // initialise storage
  38. bool AP_FlashStorage::init(void)
  39. {
  40. debug("running init()\n");
  41. // start with empty memory buffer
  42. memset(mem_buffer, 0, storage_size);
  43. // find state of sectors
  44. struct sector_header header[2];
  45. // read headers and possibly initialise if bad signature
  46. for (uint8_t i=0; i<2; i++) {
  47. if (!flash_read(i, 0, (uint8_t *)&header[i], sizeof(header[i]))) {
  48. return false;
  49. }
  50. bool bad_header = (header[i].signature != signature);
  51. enum SectorState state = (enum SectorState)header[i].state;
  52. if (state != SECTOR_STATE_AVAILABLE &&
  53. state != SECTOR_STATE_IN_USE &&
  54. state != SECTOR_STATE_FULL) {
  55. bad_header = true;
  56. }
  57. // initialise if bad header
  58. if (bad_header) {
  59. return erase_all();
  60. }
  61. }
  62. // work out the first sector to read from using sector states
  63. enum SectorState states[2] {(enum SectorState)header[0].state, (enum SectorState)header[1].state};
  64. uint8_t first_sector;
  65. if (states[0] == states[1]) {
  66. if (states[0] != SECTOR_STATE_AVAILABLE) {
  67. return erase_all();
  68. }
  69. first_sector = 0;
  70. } else if (states[0] == SECTOR_STATE_FULL) {
  71. first_sector = 0;
  72. } else if (states[1] == SECTOR_STATE_FULL) {
  73. first_sector = 1;
  74. } else if (states[0] == SECTOR_STATE_IN_USE) {
  75. first_sector = 0;
  76. } else if (states[1] == SECTOR_STATE_IN_USE) {
  77. first_sector = 1;
  78. } else {
  79. // doesn't matter which is first
  80. first_sector = 0;
  81. }
  82. // load data from any current sectors
  83. for (uint8_t i=0; i<2; i++) {
  84. uint8_t sector = (first_sector + i) & 1;
  85. if (states[sector] == SECTOR_STATE_IN_USE ||
  86. states[sector] == SECTOR_STATE_FULL) {
  87. if (!load_sector(sector)) {
  88. return erase_all();
  89. }
  90. }
  91. }
  92. // clear any write error
  93. write_error = false;
  94. reserved_space = 0;
  95. // if the first sector is full then write out all data so we can erase it
  96. if (states[first_sector] == SECTOR_STATE_FULL) {
  97. current_sector = first_sector ^ 1;
  98. if (!write_all()) {
  99. return erase_all();
  100. }
  101. }
  102. // erase any sectors marked full
  103. for (uint8_t i=0; i<2; i++) {
  104. if (states[i] == SECTOR_STATE_FULL) {
  105. if (!erase_sector(i)) {
  106. return false;
  107. }
  108. }
  109. }
  110. reserved_space = 0;
  111. // ready to use
  112. return true;
  113. }
  114. // switch full sector - should only be called when safe to have CPU
  115. // offline for considerable periods as an erase will be needed
  116. bool AP_FlashStorage::switch_full_sector(void)
  117. {
  118. debug("running switch_full_sector()\n");
  119. // clear any write error
  120. write_error = false;
  121. reserved_space = 0;
  122. if (!write_all()) {
  123. return false;
  124. }
  125. if (!erase_sector(current_sector ^ 1)) {
  126. return false;
  127. }
  128. return switch_sectors();
  129. }
  130. // write some data to virtual EEPROM
  131. bool AP_FlashStorage::write(uint16_t offset, uint16_t length)
  132. {
  133. if (write_error) {
  134. return false;
  135. }
  136. //debug("write at %u for %u write_offset=%u\n", offset, length, write_offset);
  137. while (length > 0) {
  138. uint8_t n = max_write;
  139. if (length < n) {
  140. n = length;
  141. }
  142. if (write_offset > flash_sector_size - (sizeof(struct block_header) + max_write + reserved_space)) {
  143. if (!switch_sectors()) {
  144. if (!flash_erase_ok()) {
  145. return false;
  146. }
  147. if (!switch_full_sector()) {
  148. return false;
  149. }
  150. }
  151. }
  152. struct block_header header;
  153. header.state = BLOCK_STATE_WRITING;
  154. header.block_num = offset / block_size;
  155. header.num_blocks_minus_one = ((n + (block_size - 1)) / block_size)-1;
  156. uint16_t block_ofs = header.block_num*block_size;
  157. uint16_t block_nbytes = (header.num_blocks_minus_one+1)*block_size;
  158. #if AP_FLASHSTORAGE_MULTI_WRITE
  159. if (!flash_write(current_sector, write_offset, (uint8_t*)&header, sizeof(header))) {
  160. return false;
  161. }
  162. #endif
  163. if (!flash_write(current_sector, write_offset+sizeof(header), &mem_buffer[block_ofs], block_nbytes)) {
  164. return false;
  165. }
  166. header.state = BLOCK_STATE_VALID;
  167. if (!flash_write(current_sector, write_offset, (uint8_t*)&header, sizeof(header))) {
  168. return false;
  169. }
  170. write_offset += sizeof(header) + block_nbytes;
  171. uint8_t n2 = block_nbytes - (offset % block_size);
  172. //debug("write_block at %u for %u n2=%u\n", block_ofs, block_nbytes, n2);
  173. if (n2 > length) {
  174. break;
  175. }
  176. offset += n2;
  177. length -= n2;
  178. }
  179. // handle wrap to next sector
  180. // write data
  181. // write header word
  182. return true;
  183. }
  184. /*
  185. load all data from a flash sector into mem_buffer
  186. */
  187. bool AP_FlashStorage::load_sector(uint8_t sector)
  188. {
  189. uint32_t ofs = sizeof(sector_header);
  190. while (ofs < flash_sector_size - sizeof(struct block_header)) {
  191. struct block_header header;
  192. if (!flash_read(sector, ofs, (uint8_t *)&header, sizeof(header))) {
  193. return false;
  194. }
  195. enum BlockState state = (enum BlockState)header.state;
  196. switch (state) {
  197. case BLOCK_STATE_AVAILABLE:
  198. // we've reached the end
  199. write_offset = ofs;
  200. return true;
  201. case BLOCK_STATE_WRITING: {
  202. /*
  203. we were interrupted while writing a block. We can't
  204. re-use the data in this block as it may have some bits
  205. that are not set to 1, so by flash rules can't be set to
  206. an arbitrary value. So we skip over this block, leaving
  207. a gap. The gap size is limited to (7+1)*8=64 bytes. That
  208. gap won't be recovered until we next do an erase of this
  209. sector
  210. */
  211. uint16_t block_nbytes = (header.num_blocks_minus_one+1)*block_size;
  212. ofs += block_nbytes + sizeof(header);
  213. break;
  214. }
  215. case BLOCK_STATE_VALID: {
  216. uint16_t block_nbytes = (header.num_blocks_minus_one+1)*block_size;
  217. uint16_t block_ofs = header.block_num*block_size;
  218. if (block_ofs + block_nbytes > storage_size) {
  219. // the data is invalid (out of range)
  220. return false;
  221. }
  222. if (!flash_read(sector, ofs+sizeof(header), &mem_buffer[block_ofs], block_nbytes)) {
  223. return false;
  224. }
  225. //debug("read at %u for %u\n", block_ofs, block_nbytes);
  226. ofs += block_nbytes + sizeof(header);
  227. break;
  228. }
  229. default:
  230. // invalid state
  231. return false;
  232. }
  233. }
  234. write_offset = ofs;
  235. return true;
  236. }
  237. /*
  238. erase one sector
  239. */
  240. bool AP_FlashStorage::erase_sector(uint8_t sector)
  241. {
  242. if (!flash_erase(sector)) {
  243. return false;
  244. }
  245. struct sector_header header;
  246. header.signature = signature;
  247. header.state = SECTOR_STATE_AVAILABLE;
  248. return flash_write(sector, 0, (const uint8_t *)&header, sizeof(header));
  249. }
  250. /*
  251. erase both sectors
  252. */
  253. bool AP_FlashStorage::erase_all(void)
  254. {
  255. write_error = false;
  256. current_sector = 0;
  257. write_offset = sizeof(struct sector_header);
  258. if (!erase_sector(0) || !erase_sector(1)) {
  259. return false;
  260. }
  261. // mark current sector as in-use
  262. struct sector_header header;
  263. header.signature = signature;
  264. header.state = SECTOR_STATE_IN_USE;
  265. return flash_write(current_sector, 0, (const uint8_t *)&header, sizeof(header));
  266. }
  267. /*
  268. write all of mem_buffer to current sector
  269. */
  270. bool AP_FlashStorage::write_all()
  271. {
  272. debug("write_all to sector %u at %u with reserved_space=%u\n",
  273. current_sector, write_offset, reserved_space);
  274. for (uint16_t ofs=0; ofs<storage_size; ofs += max_write) {
  275. // local variable needed to overcome problem with MIN() macro and -O0
  276. const uint8_t max_write_local = max_write;
  277. uint8_t n = MIN(max_write_local, storage_size-ofs);
  278. if (!all_zero(ofs, n)) {
  279. if (!write(ofs, n)) {
  280. return false;
  281. }
  282. }
  283. }
  284. return true;
  285. }
  286. // return true if all bytes are zero
  287. bool AP_FlashStorage::all_zero(uint16_t ofs, uint16_t size)
  288. {
  289. while (size--) {
  290. if (mem_buffer[ofs++] != 0) {
  291. return false;
  292. }
  293. }
  294. return true;
  295. }
  296. // switch to next sector for writing
  297. bool AP_FlashStorage::switch_sectors(void)
  298. {
  299. if (reserved_space != 0) {
  300. // other sector is already full
  301. debug("both sectors are full\n");
  302. return false;
  303. }
  304. struct sector_header header;
  305. header.signature = signature;
  306. uint8_t new_sector = current_sector ^ 1;
  307. debug("switching to sector %u\n", new_sector);
  308. // check sector is available
  309. if (!flash_read(new_sector, 0, (uint8_t *)&header, sizeof(header))) {
  310. return false;
  311. }
  312. if (header.signature != signature) {
  313. write_error = true;
  314. return false;
  315. }
  316. if (SECTOR_STATE_AVAILABLE != (enum SectorState)header.state) {
  317. write_error = true;
  318. debug("both sectors full\n");
  319. return false;
  320. }
  321. // mark current sector as full. This needs to be done before we
  322. // mark the new sector as in-use so that a power failure between
  323. // the two steps doesn't leave us with an erase on the
  324. // reboot. Thanks to night-ghost for spotting this.
  325. header.state = SECTOR_STATE_FULL;
  326. if (!flash_write(current_sector, 0, (const uint8_t *)&header, sizeof(header))) {
  327. return false;
  328. }
  329. // mark new sector as in-use
  330. header.state = SECTOR_STATE_IN_USE;
  331. if (!flash_write(new_sector, 0, (const uint8_t *)&header, sizeof(header))) {
  332. return false;
  333. }
  334. // switch sectors
  335. current_sector = new_sector;
  336. // we need to reserve some space in next sector to ensure we can successfully do a
  337. // full write out on init()
  338. reserved_space = reserve_size;
  339. write_offset = sizeof(header);
  340. return true;
  341. }
  342. /*
  343. re-initialise, using current mem_buffer
  344. */
  345. bool AP_FlashStorage::re_initialise(void)
  346. {
  347. if (!flash_erase_ok()) {
  348. return false;
  349. }
  350. if (!erase_all()) {
  351. return false;
  352. }
  353. return write_all();
  354. }