|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
Where the next copy of the output binding goes. More...
Functions | |
| static bool | usable (const out_store_rec_t *recs, uint8_t sectors, uint8_t per_sector) |
| A geometry this file can index: slots are addressed by uint8_t, and the caller's plan carries them as one. | |
| static bool | sector_erased (const out_store_rec_t *recs, uint8_t sector, uint8_t per_sector) |
| Whether every slot of one sector is erased. | |
| int | out_store_map_newest (const out_store_rec_t *recs, uint8_t sectors, uint8_t per_sector) |
| The live record: the valid one with the highest sequence number. | |
| bool | out_store_map_write (const out_store_rec_t *recs, uint8_t sectors, uint8_t per_sector, out_store_write_t *out) |
| Plan the next save. | |
| bool | out_store_map_write_keep (const out_store_rec_t *recs, uint8_t sectors, uint8_t per_sector, int keep, out_store_write_t *out) |
The same, with sector keep never erased while no record is valid: it holds the live record of the layout before this one (a one-page slot of version 7 or older, out_store_rec.h), which the store reads until its first record of the new layout is written. | |
| int | out_store_map_stale (const out_store_rec_t *recs, uint8_t sectors, uint8_t per_sector) |
| A sector worth erasing now, ahead of the save that would have to wait for it, or -1 when there is none. | |
| int | out_store_map_stale_keep (const out_store_rec_t *recs, uint8_t sectors, uint8_t per_sector, int keep) |
The same, never offering sector keep while no record is valid (see out_store_map_write_keep()). | |
| bool | out_store_intact (uint32_t zeros, uint32_t zeros_inv, uint32_t counted) |
| Whether a record was written whole and has stayed as it was written. | |
| bool out_store_intact | ( | uint32_t | zeros, |
| uint32_t | zeros_inv, | ||
| uint32_t | counted ) |
Whether a record was written whole and has stayed as it was written.
zeros is the number of 0 bits the record held when it was written, zeros_inv is ~zeros, and counted is the number of 0 bits it holds now. The pair says the count itself is untouched; the count says the rest of the record is.
A flash erase only sets bits and a program only clears them, so either one interrupted leaves a record with fewer 0 bits than it was written with. Neither can fake the pair: a bit set in zeros would have to be paid for by a bit cleared in zeros_inv, and a bit cleared by one set, and no single flash operation does both.
This is a stronger check than the record's checksum, and it answers a different question. The checksum says the bytes are the ones that were meant; this says the write that put them there finished.
| zeros | Number of 0 bits when the record was written. |
| zeros_inv | Complement of zeros, as written beside it. |
| counted | Number of 0 bits the record holds now. |
zeros_inv is the complement of zeros and counted equals zeros, false otherwise. | int out_store_map_newest | ( | const out_store_rec_t * | recs, |
| uint8_t | sectors, | ||
| uint8_t | per_sector ) |
The live record: the valid one with the highest sequence number.
-1 when none of them is valid, which is a store that has never been written, one written by a build with a different record in it, and one whose only records are torn. The caller keeps its defaults for all three.
The comparison is a plain unsigned one rather than a wrap-safe difference. The sequence starts at 1 and counts saves; a sector pair of 32 slots at 100,000 erase cycles a sector accepts about 3.2 million saves before the part wears out, and a uint32_t counts to 4,294,967,295.
| recs | The record slots, sectors * per_sector of them. |
| sectors | Number of sectors. |
| per_sector | Record slots per sector. |
| int out_store_map_stale | ( | const out_store_rec_t * | recs, |
| uint8_t | sectors, | ||
| uint8_t | per_sector ) |
A sector worth erasing now, ahead of the save that would have to wait for it, or -1 when there is none.
A sector qualifies when it does not hold the live record and is not already erased. Erasing it costs the same window as erasing it later; the point of taking it early is that the caller chooses the moment, and that the save which finds the sector ready costs a page program alone.
| recs | The record slots, sectors * per_sector of them. |
| sectors | Number of sectors. |
| per_sector | Record slots per sector. |
| int out_store_map_stale_keep | ( | const out_store_rec_t * | recs, |
| uint8_t | sectors, | ||
| uint8_t | per_sector, | ||
| int | keep ) |
The same, never offering sector keep while no record is valid (see out_store_map_write_keep()).
| recs | The record slots, sectors * per_sector of them. |
| sectors | Number of sectors. |
| per_sector | Record slots per sector. |
| keep | Sector never offered while no record is valid, or -1 for none. |
| bool out_store_map_write | ( | const out_store_rec_t * | recs, |
| uint8_t | sectors, | ||
| uint8_t | per_sector, | ||
| out_store_write_t * | out ) |
Plan the next save.
The slot after the live record, while its sector has an erased slot left; then the first sector that is already erased; then the next sector, which has to be erased first. A slot that is neither erased nor valid is a torn write and is skipped rather than programmed over: bits only clear, so a second record written into a used slot is the two of them anded together.
False when out is NULL or the geometry is empty; the store is otherwise always placeable, because a full store erases a sector to make room.
| recs | The record slots, sectors * per_sector of them. |
| sectors | Number of sectors. |
| per_sector | Record slots per sector. |
| out | Receives the plan: the slot to program, its sequence number and the sector to erase first, if any. Not changed when false is returned. |
out. false when out is NULL or the geometry is not usable (recs NULL, a count of 0, or a total above 255). | bool out_store_map_write_keep | ( | const out_store_rec_t * | recs, |
| uint8_t | sectors, | ||
| uint8_t | per_sector, | ||
| int | keep, | ||
| out_store_write_t * | out ) |
The same, with sector keep never erased while no record is valid: it holds the live record of the layout before this one (a one-page slot of version 7 or older, out_store_rec.h), which the store reads until its first record of the new layout is written.
The first other sector is erased instead. -1 keeps none, as out_store_map_write().
| recs | The record slots, sectors * per_sector of them. |
| sectors | Number of sectors. |
| per_sector | Record slots per sector. |
| keep | Sector to keep while no record is valid, or -1 to keep none. With no valid record and no erased slot, the erase goes to sector 1 when keep is 0 and sectors is above 1, and to sector 0 otherwise. |
| out | Receives the plan. Not changed when the call returns false. |
out, false when out is NULL or the geometry is not usable (see out_store_map_write()).
|
static |
Whether every slot of one sector is erased.
| recs | The record slots of the whole store. |
| sector | Sector index. |
| per_sector | Record slots per sector. |
sector are erased, false when any of them is not.
|
static |
A geometry this file can index: slots are addressed by uint8_t, and the caller's plan carries them as one.
| recs | The record slots, not NULL when usable. |
| sectors | Number of sectors, above 0 when usable. |
| per_sector | Record slots per sector, above 0 when usable. |