Reverse Engineering Microcontroller R5F562TABDFF EEPROM: The Store Is a Log, Not a Table
A flash block on this family is erased as a unit and programmed in units. Neither operation is a byte write. So any design that needs to change a parameter at runtime has to solve the same problem, and the standard solution is the same everywhere: stop trying to modify the store and start appending to it.
Once a settings area is an append-only log rather than a fixed table, every property that a recovery depends on changes. Offset-based extraction stops working, because parameters move. “Read the block and decode it” stops working, because most of the block is history. And the value at any given offset means nothing without the sequence that produced it.
R5F562TABDFF#V1 is one of the larger-memory order codes in the RX62T group, with the QFP-type package code and a version suffix that identifies a shipping configuration rather than different silicon. The motor-control peripheral set is what usually justifies this group, and motor control is exactly the kind of application with a persistent parameter store: current limits, offsets, calibration constants, fault counters.
What a record contains
| field | typical content | role in recovery |
|---|---|---|
| header | a signature word or a key | distinguishes a record from erased space |
| sequence | a monotonic counter | decides which record is newer |
| key | which parameter this is | maps the payload to meaning |
| payload | the value, often scaled | the data the customer wants |
| check | a checksum or a duplicated key | rejects a torn write |
The sequence and the check are the two fields that do the work, and they are the two that a naive extraction skips.
Sequence exists because the block can be erased and the counter can restart. A consumer that compares sequence numbers alone will accept an old record after a rollover, which is why serious implementations write the sequence in the header and the inverse of the sequence in the trailer, so that a valid record is self-evidently valid rather than merely plausible.
The check exists because power can be lost between the first byte and the last. A record whose header is written and whose payload is not is not a record, and the only way to know that is to check something that spans the whole record.
Torn writes, and why they are the interesting case
A device that was switched off mid-append leaves a partially written record at the write pointer. Its header is valid, its payload is half old and half new, and its check fails.
Three outcomes are possible depending on where the power failed, and all three occur in the field.
A record with a valid header and an invalid check is a torn write: discard it and use the previous record for that key. This is the common case and it is also the case that a naive extractor gets wrong, because it takes the last header it finds and reports the value next to it.
A record with an invalid header is a write that never started: the space after it may still be erased, and the log ends there rather than at the end of the block.
A record that is valid but whose sequence number is lower than an earlier one is either a rollover or a reconstruction error, and distinguishing them requires reading all the way back rather than stopping at the first plausible entry.
Deciding which block is live
Two blocks alternate. At any moment one is active and being appended, and the other holds either the previous generation or nothing.
The rule that decides it is not “the newer one”, because after an erase the newer one is empty. The rule is that the live block is the one whose last valid record has the highest sequence, and if one block is empty, the live block is the other one regardless of sequence.
Getting this wrong produces a plausible but outdated answer, which is worse than an error: a customer comparing a recovered parameter set against a machine’s actual behaviour will find a mismatch in exactly the values that changed most recently, and the natural conclusion is that the recovery failed rather than that the wrong block was chosen.
The write pointer is a wear meter
The boundary between the last valid record and the first erased byte is the write pointer. Its position, relative to the block size, is a fraction of the erase cycle consumed.
For a single unit that number is trivial. For a fleet it is the most valuable number in the delivery, because emulated EEPROM has a finite erase endurance and a design that appends one record per power cycle consumes it at a rate that can be calculated from the position of the pointer and the age of the product.
Reporting it costs one line and it turns a recovery engagement into an engineering one.
A delivery that is a timeline
The output that serves a failure investigation is not a table of current values. It is a table of values over time: each parameter, its current value, and the sequence numbers at which it last changed.
That form answers the questions people actually ask — did the offset drift before the fault, was the limit changed during commissioning, how many fault records accumulated — and it is derivable from the log without any extra work beyond keeping the sequence numbers instead of discarding them.
For the decision about whether the store is a log at all, R5F562TAEDFF EEPROM covers the three possible arrangements. For the configuration bytes that sit in the same flash, R5F562TABDFF program deals with the option area. And for a Renesas device where the persistent data was restored from a flash image rather than a log, R8C R5F211A2SP data restore is the comparison.
FAQ
Why not just overwrite the parameter in place? Because flash cannot. A write can only clear bits, so a change that needs a bit set requires erasing the containing block, which would destroy every other parameter in it.
Does the log ever get compacted? Usually at block switch, when the live values are copied to the freshly erased block. That copy is the moment a power loss does the most damage, and it is why two blocks exist rather than one.
Can the sequence number be trusted after an erase? Only if the implementation protects it, typically by writing the sequence and its inverse. A bare counter that restarts at zero cannot be trusted across a block switch.
The short version
An append-only store is a log, and a log has to be read in order with its checks honoured. Keep the sequence numbers, discard torn records rather than reporting them, choose the live block by last valid sequence rather than by emptiness, and report the write pointer as wear. Then deliver a timeline instead of a table, because the timeline is what the customer’s question actually was.