StorageManager.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. /*
  15. Management for hal.storage to allow for backwards compatible mapping
  16. of storage offsets to available storage
  17. */
  18. #include <AP_HAL/AP_HAL.h>
  19. #include "StorageManager.h"
  20. extern const AP_HAL::HAL& hal;
  21. /*
  22. the layouts below are carefully designed to ensure backwards
  23. compatibility with older firmwares
  24. */
  25. #if STORAGE_NUM_AREAS == 1
  26. /*
  27. layout for peripherals
  28. */
  29. const StorageManager::StorageArea StorageManager::layout_default[STORAGE_NUM_AREAS] = {
  30. { StorageParam, 0, HAL_STORAGE_SIZE}
  31. };
  32. #else
  33. /*
  34. layout for fixed wing and rovers
  35. On PX4v1 this gives 309 waypoints, 30 rally points and 52 fence points
  36. On Pixhawk this gives 724 waypoints, 50 rally points and 84 fence points
  37. */
  38. const StorageManager::StorageArea StorageManager::layout_default[STORAGE_NUM_AREAS] = {
  39. { StorageParam, 0, 1280}, // 0x500 parameter bytes
  40. { StorageMission, 1280, 2506},
  41. { StorageRally, 3786, 150}, // 10 rally points
  42. { StorageFence, 3936, 160}, // 20 fence points
  43. #if STORAGE_NUM_AREAS >= 8
  44. { StorageParam, 4096, 1280},
  45. { StorageRally, 5376, 300},
  46. { StorageFence, 5676, 256},
  47. { StorageMission, 5932, 2132},
  48. { StorageKeys, 8064, 64},
  49. { StorageBindInfo,8128, 56},
  50. #endif
  51. #if STORAGE_NUM_AREAS == 11
  52. // optimised for lots of parameters for 15k boards with OSD
  53. { StorageParam, 8192, 7168},
  54. #endif
  55. #if STORAGE_NUM_AREAS >= 12
  56. { StorageParam, 8192, 1280},
  57. { StorageRally, 9472, 300},
  58. { StorageFence, 9772, 256},
  59. { StorageMission, 10028, 6228}, // leave 128 byte gap for expansion
  60. #endif
  61. };
  62. /*
  63. layout for copter.
  64. On PX4v1 this gives 303 waypoints, 26 rally points and 38 fence points
  65. On Pixhawk this gives 718 waypoints, 46 rally points and 70 fence points
  66. */
  67. const StorageManager::StorageArea StorageManager::layout_copter[STORAGE_NUM_AREAS] = {
  68. { StorageParam, 0, 1536}, // 0x600 param bytes
  69. { StorageMission, 1536, 2422},
  70. { StorageRally, 3958, 90}, // 6 rally points
  71. { StorageFence, 4048, 48}, // 6 fence points
  72. #if STORAGE_NUM_AREAS >= 8
  73. { StorageParam, 4096, 1280},
  74. { StorageRally, 5376, 300},
  75. { StorageFence, 5676, 256},
  76. { StorageMission, 5932, 2132},
  77. { StorageKeys, 8064, 64},
  78. { StorageBindInfo,8128, 56},
  79. #endif
  80. #if STORAGE_NUM_AREAS == 11
  81. // optimised for lots of parameters for 15k boards with OSD
  82. { StorageParam, 8192, 7168},
  83. #endif
  84. #if STORAGE_NUM_AREAS >= 12
  85. { StorageParam, 8192, 1280},
  86. { StorageRally, 9472, 300},
  87. { StorageFence, 9772, 256},
  88. { StorageMission, 10028, 6228}, // leave 128 byte gap for expansion
  89. #endif
  90. };
  91. #endif // STORAGE_NUM_AREAS == 1
  92. // setup default layout
  93. const StorageManager::StorageArea *StorageManager::layout = layout_default;
  94. /*
  95. erase all storage
  96. */
  97. void StorageManager::erase(void)
  98. {
  99. uint8_t blk[16];
  100. memset(blk, 0, sizeof(blk));
  101. for (uint8_t i=0; i<STORAGE_NUM_AREAS; i++) {
  102. const StorageManager::StorageArea &area = StorageManager::layout[i];
  103. uint16_t length = area.length;
  104. uint16_t offset = area.offset;
  105. for (uint16_t ofs=0; ofs<length; ofs += sizeof(blk)) {
  106. uint8_t n = 16;
  107. if (ofs + n > length) {
  108. n = length - ofs;
  109. }
  110. hal.storage->write_block(offset + ofs, blk, n);
  111. }
  112. }
  113. }
  114. /*
  115. constructor for StorageAccess
  116. */
  117. StorageAccess::StorageAccess(StorageManager::StorageType _type) :
  118. type(_type)
  119. {
  120. // calculate available bytes
  121. total_size = 0;
  122. for (uint8_t i=0; i<STORAGE_NUM_AREAS; i++) {
  123. const StorageManager::StorageArea &area = StorageManager::layout[i];
  124. if (area.type == type) {
  125. total_size += area.length;
  126. }
  127. }
  128. }
  129. /*
  130. base read function. The src offset is within the bytes allocated
  131. for the storage type of this StorageAccess object
  132. */
  133. bool StorageAccess::read_block(void *data, uint16_t addr, size_t n) const
  134. {
  135. uint8_t *b = (uint8_t *)data;
  136. for (uint8_t i=0; i<STORAGE_NUM_AREAS; i++) {
  137. const StorageManager::StorageArea &area = StorageManager::layout[i];
  138. uint16_t length = area.length;
  139. uint16_t offset = area.offset;
  140. if (area.type != type) {
  141. continue;
  142. }
  143. if (addr >= length) {
  144. // the data isn't in this area
  145. addr -= length;
  146. continue;
  147. }
  148. uint8_t count = n;
  149. if (count+addr > length) {
  150. // the data crosses a boundary between two areas
  151. count = length - addr;
  152. }
  153. hal.storage->read_block(b, addr+offset, count);
  154. n -= count;
  155. if (n == 0) {
  156. break;
  157. }
  158. // move pointer after written bytes
  159. b += count;
  160. // continue writing at the beginning of next valid area
  161. addr = 0;
  162. }
  163. return (n == 0);
  164. }
  165. /*
  166. base read function. The addr offset is within the bytes allocated
  167. for the storage type of this StorageAccess object
  168. */
  169. bool StorageAccess::write_block(uint16_t addr, const void *data, size_t n) const
  170. {
  171. const uint8_t *b = (const uint8_t *)data;
  172. for (uint8_t i=0; i<STORAGE_NUM_AREAS; i++) {
  173. const StorageManager::StorageArea &area = StorageManager::layout[i];
  174. uint16_t length = area.length;
  175. uint16_t offset = area.offset;
  176. if (area.type != type) {
  177. continue;
  178. }
  179. if (addr >= length) {
  180. // the data isn't in this area
  181. addr -= length;
  182. continue;
  183. }
  184. uint8_t count = n;
  185. if (count+addr > length) {
  186. // the data crosses a boundary between two areas
  187. count = length - addr;
  188. }
  189. hal.storage->write_block(addr+offset, b, count);
  190. n -= count;
  191. if (n == 0) {
  192. break;
  193. }
  194. // move pointer after written bytes
  195. b += count;
  196. // continue writing at the beginning of next valid area
  197. addr = 0;
  198. }
  199. return (n == 0);
  200. }
  201. /*
  202. read a byte
  203. */
  204. uint8_t StorageAccess::read_byte(uint16_t loc) const
  205. {
  206. uint8_t v;
  207. read_block(&v, loc, sizeof(v));
  208. return v;
  209. }
  210. /*
  211. read 16 bit value
  212. */
  213. uint16_t StorageAccess::read_uint16(uint16_t loc) const
  214. {
  215. uint16_t v;
  216. read_block(&v, loc, sizeof(v));
  217. return v;
  218. }
  219. /*
  220. read 32 bit value
  221. */
  222. uint32_t StorageAccess::read_uint32(uint16_t loc) const
  223. {
  224. uint32_t v;
  225. read_block(&v, loc, sizeof(v));
  226. return v;
  227. }
  228. /*
  229. write a byte
  230. */
  231. void StorageAccess::write_byte(uint16_t loc, uint8_t value) const
  232. {
  233. write_block(loc, &value, sizeof(value));
  234. }
  235. /*
  236. write a uint16
  237. */
  238. void StorageAccess::write_uint16(uint16_t loc, uint16_t value) const
  239. {
  240. write_block(loc, &value, sizeof(value));
  241. }
  242. /*
  243. write a uint32
  244. */
  245. void StorageAccess::write_uint32(uint16_t loc, uint32_t value) const
  246. {
  247. write_block(loc, &value, sizeof(value));
  248. }