hsk-libs-dev
270
High Speed Karlsruhe XC878 library collection
|
HSK Flash Facility headers. More...
#include "../hsk_isr/hsk_isr.isr"
Go to the source code of this file.
Macros | |
#define | XC878_16FF |
Ensure that a flash memory layout is defined. More... | |
#define | FLASH_STRUCT_FACTORY(members) |
Used to create a struct that can be used with the hsk_flash_init() function. More... | |
#define | FLASH_PWR_FIRST 0 |
Returned by hsk_flash_init() when the µC boots for the first time. More... | |
#define | FLASH_PWR_RESET 1 |
Returned by hsk_flash_init() after booting from a reset without power loss. More... | |
#define | FLASH_PWR_ON 2 |
Returned by hsk_flash_init() during power on, if valid data was recovered from the D-Flash. More... | |
Functions | |
ubyte | hsk_flash_init (void *const ptr, const uword size, const ubyte version) |
Recovers a struct from a previous session and sets everything up for storage of changes. More... | |
bool | hsk_flash_write (void) |
Writes the current data to the D-Flash. More... | |
HSK Flash Facility headers.
This file contains function prototypes to menage information that survives a reset and allow storage within the D-Flash.
It provides the FLASH_STRUCT_FACTORY to create a struct with data that can be stored with hsk_flash_write() and recovered with hsk_flash_init().
The D-Flash is used as a ring buffer, this distributes writes over the entire flash to gain the maximum achievable lifetime. The lifetime expectancy depends on your usage scenario and the size of the struct.
Refer to section 3.3 table 20 and table 21 of the XC87x data sheet for D-Flash life times.
Complete coverage of the D-Flash counts as a single D-Flash cycle. Thus the formula for the expected number of write calls is:
expectedcycles
sizeof(struct)
floor()
E.g. to store 20 bytes of configuration data, the struct factory adds 2 bytes overhead to be able to check the consistency of written data, so . Expecting that most of the µC use is within the first year, table 20 suggests that . In that case the expected number of possible hsk_flash_write() calls is 18.6 million.
C51 stores multiple byte variables in big endian order, whereas the DPTR register, several SFRs and SDCC use little endian.
If the data struct contains multibyte members such as int/uword or long/ulong, this can lead to data corruption, when switching compilers.
Both the checksum and identifier are single byte values and thus will still match after a compiler switch, causing multibyte values to be restored from the flash with the wrong byte order.
A byte order change can be detected with a byte order word in the struct. A BOW initialized with 0x1234 would read 0x3412 after a an order change.
The suggested solution is to only create struct members with byte wise access. E.g. a ulong member may be defined in the following way:
The value can be set like this:
Reading works similarly:
Another alternative is to use a single ubyte[] array and store/read all data with the hsk_can_data_setSignal()/hsk_can_data_getSignal() functions. Due to the bit addressing of CAN message data the maximum length of such an array would be 32 bytes (256bits).
An advantage would be that less memory is required, because data no longer needs to be byte aligned.
#define FLASH_PWR_FIRST 0 |
Returned by hsk_flash_init() when the µC boots for the first time.
This statements holds true as far as can be told. I.e. a first boot is diagnosed when all attempts to recover data have failed.
Two scenarios may cause this:
#define FLASH_PWR_ON 2 |
Returned by hsk_flash_init() during power on, if valid data was recovered from the D-Flash.
A power on is detected when two criteria are met:
xdata
memory#define FLASH_PWR_RESET 1 |
Returned by hsk_flash_init() after booting from a reset without power loss.
The typical mark of a reset is that xdata
memory still holds data from the previous session. If such data is found it will just be picked up.
For performance reasons access to the struct is not guarded, which means that there can be no protection against data corruption, such as might be caused by a software bug like an overflow.
#define FLASH_STRUCT_FACTORY | ( | members | ) |
Used to create a struct that can be used with the hsk_flash_init() function.
The hsk_flash_init() function expects certain fields to exist, in the struct, which are used to ensure the consistency of data in the flash.
The following example shows how to create a struct named storableData:
members | Struct member definitions |
#define XC878_16FF |
Ensure that a flash memory layout is defined.
Either XC878_16FF (64k flash) or XC878_13FF(52k flash) are supported. XC878_16FF is the default.
ubyte hsk_flash_init | ( | void *const | ptr, |
const uword | size, | ||
const ubyte | version | ||
) |
Recovers a struct from a previous session and sets everything up for storage of changes.
There are two modes of recovery. After a fresh boot the data can be recovered from flash, if previously stored there. After a simple reset the data can still be found in XRAM and recovery can be sped up.
If recovery fails entirely all members of the struct will be set to 0.
version | Version number of the persisted data structure, used to prevent initilization with incompatible data |
ptr | A pointer to the xdata struct/array to persist |
size | The size of the data structure to persist |
FLASH_PWR_FIRST | No valid data was recovered |
FLASH_PWR_RESET | Continue operation after a reset |
FLASH_PWR_ON | Data restore from the D-Flash succeeded |
bool hsk_flash_write | ( | void | ) |
Writes the current data to the D-Flash.
Ongoing writes are interrupted. Ongoing deletes are interrupted unless there is insufficient space left to write the data.
1 | The D-Flash write is on the way |
0 | Not enough free D-Flash space to write, try again later |