hsk-libs-dev  270
High Speed Karlsruhe XC878 library collection
Macros | Functions
hsk_flash.h File Reference

HSK Flash Facility headers. More...

#include "../hsk_isr/hsk_isr.isr"
Include dependency graph for hsk_flash.h:
This graph shows which files directly or indirectly include this file:

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...
 

Detailed Description

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:

\[ writes = \lfloor 4096 / sizeof(struct) \rfloor * expectedcycles \]

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 $ sizeof(struct) = 22 $. Expecting that most of the µC use is within the first year, table 20 suggests that $ expectedcycles = 100000 $. In that case the expected number of possible hsk_flash_write() calls is 18.6 million.

Author
kami

Byte Order

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:

ubyte ulongMember[sizeof(ulong)];

The value can be set like this:

myStruct.ulongMember[0] = ulongValue;
myStruct.ulongMember[1] = ulongValue >> 8;
myStruct.ulongMember[2] = ulongValue >> 16;
myStruct.ulongMember[3] = ulongValue >> 24;

Reading works similarly:

ulongValue = (ubyte)myStruct.ulongMember[0];
ulongValue |= (uword)myStruct.ulongMember[1] << 8;
ulongValue |= (ulong)myStruct.ulongMember[2] << 16;
ulongValue |= (ulong)myStruct.ulongMember[3] << 24;

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.

Macro Definition Documentation

§ FLASH_PWR_FIRST

#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:

  • No valid data has yet been written to the D-Flash
  • The latest flash data is corrupted, may happen in case of power down during write

§ FLASH_PWR_ON

#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:

  • Data could not be recovered from xdata memory
  • Valid data was recovered from the D-Flash

§ FLASH_PWR_RESET

#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.

§ FLASH_STRUCT_FACTORY

#define FLASH_STRUCT_FACTORY (   members)
Value:
/**
This struct is a template for data that can be written to the D-Flash.
It is created by invoking the \ref FLASH_STRUCT_FACTORY macro.
*/\
volatile struct hsk_flash_struct {\
/**
For data integrity/compatibilty detection.
@private
*/\
\
members\
\
/**
For data integrity detection.
@private
*/\
} xdata
ubyte hsk_flash_chksum
For data integrity detection.
Definition: main.c:71
ubyte hsk_flash_prefix
For data integrity/compatibilty detection.
Definition: main.c:71
This struct is a template for data that can be written to the D-Flash.
Definition: main.c:71

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:

ubyte storableByte;
uword storableWord;
) storableData;
Parameters
membersStruct member definitions

§ XC878_16FF

#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.

Function Documentation

§ hsk_flash_init()

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.

Parameters
versionVersion number of the persisted data structure, used to prevent initilization with incompatible data
ptrA pointer to the xdata struct/array to persist
sizeThe size of the data structure to persist
Return values
FLASH_PWR_FIRSTNo valid data was recovered
FLASH_PWR_RESETContinue operation after a reset
FLASH_PWR_ONData restore from the D-Flash succeeded
Here is the call graph for this function:

§ hsk_flash_write()

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.

Return values
1The D-Flash write is on the way
0Not enough free D-Flash space to write, try again later