changed the semantics of eeprom__copy()

the direction in which the data is copied is now well defined.  this
allows us to copy a large block a small distance (where the block's new
address range overlaps with its old one), in either direction (to a
higher block of addresses or a lower one), in a well defined and
documented manner.
partial-rewrite
Ben Blazak 2013-07-24 14:20:39 -07:00
parent a32a9b59d6
commit 0bf0181ffa
2 changed files with 21 additions and 22 deletions

View File

@ -125,26 +125,17 @@ uint8_t eeprom__copy (uint8_t * to, uint8_t * from, uint8_t length);
* - success: `0`
* - failure: [other]
*
*
* Implementation notes:
* - Undefined behavior will result if
* - `to` is not a valid address.
* - `from` is not a valid address.
* - Any address in either the block you're copying from
* (`from`..`from+length-1`) or the block you're copying to
* (`to`..`to+length-1`) is invalid.
* - The block you're copying from overlaps with the block you're copying
* to.
* - The direction in which the block is copied (beginning with `to` and
* incrementing, or beginning with `to + length - 1` and decrementing) is
* undefined.
* - Ideally, one would probably want to start with `to` and increment if
* one was copying from a higher address to a lower one, and with `to +
* length - 1` and decrement if one was copying from a lower address to a
* higher one. This way, copying overlapping blocks would work as one
* would expect (i.e. data would be moved up or down by `length` bytes).
* But it seems like this might become more complicated than I'd like it
* to be, and it also (if it turns out to matter) would be inordinately
* difficult to make safe against data corruption in the event of power
* loss.
*
* - If `to == from`, nothing should be done
* - If `to < from`, copying should start with the given addresses, and
* increment for `length - 1` bytes
* - If `to > from`, copying should start with the given addresses, and
* decrement for `length - 1` bytes
*
* - Undefined behavior will result if any address in either the block you're
* copying from (`from`..`from+length-1`) or the block you're copying to
* (`to`..`to+length-1`) is invalid.
*/

View File

@ -380,8 +380,13 @@ static void write_queued(void) {
// copy 1 byte
write( next_write.to, eeprom__read( (uint8_t *) next_copy.from ) );
// prepare for the next
++(next_write.to);
++(next_copy.from);
if (next_write.to < next_write.from) {
++(next_write.to);
++(next_copy.from);
} else {
--(next_write.to);
--(next_copy.from);
}
--(next_write.value);
} else {
@ -449,6 +454,9 @@ uint8_t eeprom__write(uint8_t * address, uint8_t data) {
// note: this should be the only function adding elements to `to_copy`
uint8_t eeprom__copy(uint8_t * to, uint8_t * from, uint8_t length) {
if (to == from)
return 0; // nothing to do
to_write.unused_back--;
to_copy.unused_back--;
if (resize_to_write() || resize_to_copy()) {