base write function. The addr offset is within the bytes allocated for the storage type of this StorageAccess object */
| 191 | for the storage type of this StorageAccess object |
| 192 | */ |
| 193 | bool StorageAccess::write_block(uint16_t addr, const void *data, size_t n) const |
| 194 | { |
| 195 | const uint8_t *b = (const uint8_t *)data; |
| 196 | |
| 197 | #if AP_SDCARD_STORAGE_ENABLED |
| 198 | if (file != nullptr) { |
| 199 | if (addr > file->bufsize) { |
| 200 | return false; |
| 201 | } |
| 202 | // using microSD data |
| 203 | WITH_SEMAPHORE(file->sem); |
| 204 | const size_t n2 = MIN(n, file->bufsize - addr); |
| 205 | memcpy(&file->buffer[addr], b, n2); |
| 206 | for (uint8_t i=addr/1024U; i<(addr+n2+1023U)/1024U; i++) { |
| 207 | file->dirty_mask |= (1ULL<<i); |
| 208 | } |
| 209 | return n == n2; |
| 210 | } |
| 211 | #endif |
| 212 | |
| 213 | for (uint8_t i=0; i<STORAGE_NUM_AREAS; i++) { |
| 214 | const StorageManager::StorageArea &area = StorageManager::layout[i]; |
| 215 | uint16_t length = area.length; |
| 216 | uint16_t offset = area.offset; |
| 217 | if (area.type != type) { |
| 218 | continue; |
| 219 | } |
| 220 | if (addr >= length) { |
| 221 | // the data isn't in this area |
| 222 | addr -= length; |
| 223 | continue; |
| 224 | } |
| 225 | uint16_t count = n; |
| 226 | if (count+addr > length) { |
| 227 | // the data crosses a boundary between two areas |
| 228 | count = length - addr; |
| 229 | } |
| 230 | hal.storage->write_block(addr+offset, b, count); |
| 231 | n -= count; |
| 232 | |
| 233 | if (n == 0) { |
| 234 | break; |
| 235 | } |
| 236 | |
| 237 | // move pointer after written bytes |
| 238 | b += count; |
| 239 | // continue writing at the beginning of next valid area |
| 240 | addr = 0; |
| 241 | } |
| 242 | |
| 243 | return (n == 0); |
| 244 | } |
| 245 | |
| 246 | /* |
| 247 | read a byte |