Bluenet  5.7.0
Bluenet, firmware for nRF52 smart home devices
Loading...
Searching...
No Matches
State Class Reference

Stores state values in RAM and/or FLASH. More...

#include <cs_State.h>

Inheritance diagram for State:
Collaboration diagram for State:

Public Member Functions

virtual ~State ()
 
void init (boards_config_t *boardsConfig)
 Initialize the State object with the board configuration. More...
 
cs_ret_code_t get (cs_state_data_t &data, const PersistenceMode mode=PersistenceMode::STRATEGY1)
 Get copy of a state value. More...
 
cs_ret_code_t get (const CS_TYPE type, void *value, size16_t size)
 Convenience function for get() with id 0. More...
 
bool isTrue (CS_TYPE type, const PersistenceMode mode=PersistenceMode::STRATEGY1)
 Shorthand for get() for boolean data types, and id 0. More...
 
cs_ret_code_t getIds (CS_TYPE type, std::vector< cs_state_id_t > *&ids)
 Get a list of IDs for given type. More...
 
cs_ret_code_t set (const cs_state_data_t &data, PersistenceMode mode=PersistenceMode::STRATEGY1)
 Set state to new value, via copy. More...
 
cs_ret_code_t set (const CS_TYPE type, void *value, size16_t size)
 Convenience function for set(). More...
 
cs_ret_code_t setDelayed (const cs_state_data_t &data, uint8_t delay)
 Set the state to a new value, but delay the write to flash. More...
 
cs_ret_code_t setThrottled (const cs_state_data_t &data, uint32_t period)
 Write variable to flash in a throttled mode. More...
 
cs_ret_code_t verifySizeForGet (const cs_state_data_t &data)
 Verify size of user data for getting a state. More...
 
cs_ret_code_t verifySizeForSet (const cs_state_data_t &data)
 Verify size of user data for setting a state. More...
 
cs_ret_code_t remove (const CS_TYPE &type, cs_state_id_t id, const PersistenceMode mode=PersistenceMode::STRATEGY1)
 Remove a state variable. More...
 
void factoryReset ()
 Erase all used persistent storage. More...
 
cs_ret_code_t cleanUp ()
 Clean up persistent storage. More...
 
cs_ret_code_t getViaPointer (cs_state_data_t &data, const PersistenceMode mode=PersistenceMode::STRATEGY1)
 Get pointer to state value. More...
 
cs_ret_code_t setViaPointer (CS_TYPE type)
 Update state value. More...
 
void startWritesToFlash ()
 After calling this, state is allowed to write to flash. More...
 
void handleStorageError (cs_storage_operation_t operation, CS_TYPE type, cs_state_id_t id)
 Internal usage. More...
 
void handleEvent (event_t &event)
 Handle (crownstone) events. More...
 
- Public Member Functions inherited from BaseClass< N >
 BaseClass ()
 
bool isInitialized (uint8_t i=0)
 
void setInitialized (uint8_t i=0)
 
void setUninitialized (uint8_t i=0)
 

Static Public Member Functions

static StategetInstance ()
 Get a reference to the State object. More...
 

Protected Member Functions

cs_ret_code_t findInRam (const CS_TYPE &type, cs_state_id_t id, size16_t &index_in_ram)
 Find given type in ram. More...
 
cs_ret_code_t storeInRam (const cs_state_data_t &data, size16_t &index_in_ram)
 Stores state variable in ram. More...
 
cs_ret_code_t storeInRam (const cs_state_data_t &data)
 Convenience function, in case you're not interested in index in ram. More...
 
cs_ret_code_t loadFromRam (cs_state_data_t &data)
 Copies from ram to target buffer. More...
 
cs_state_data_taddToRam (const CS_TYPE &type, cs_state_id_t id, size16_t size)
 Adds a new state_data struct to ram. More...
 
cs_ret_code_t removeFromRam (const CS_TYPE &type, cs_state_id_t id)
 Removed a state variable from ram. More...
 
cs_ret_code_t compareWithRam (const cs_state_data_t &data, uint32_t &cmp_result)
 Check a particular value with the value currently in ram. More...
 
cs_ret_code_t storeInFlash (size16_t &index_in_ram)
 Writes state variable in ram to flash. More...
 
cs_ret_code_t removeFromFlash (const CS_TYPE &type, const cs_state_id_t id)
 Remove given id of given type from flash. More...
 
cs_ret_code_t addToQueue (StateQueueOp operation, const CS_TYPE &type, cs_state_id_t id, uint32_t delayMs, const StateQueueMode mode)
 Add an operation to queue. More...
 
cs_ret_code_t allocate (cs_state_data_t &data)
 
void delayedStoreTick ()
 

Protected Attributes

Storage_storage
 
boards_config_t_boardsConfig
 
std::vector< cs_state_data_t_ram_data_register
 Stores state data structs with pointers to state data. More...
 
std::vector< cs_id_list_t_idsCache
 Stores list of existing ids for certain types. More...
 
std::vector< cs_state_store_queue_t_store_queue
 Stores the queue of flash operations. More...
 
bool _startedWritingToFlash = false
 
bool _performingFactoryReset = false
 

Private Member Functions

 State ()
 State constructor, singleton, thus made private. More...
 
 State (State const &)
 State copy constructor, singleton, thus made private. More...
 
void operator= (State const &)
 Assignment operator, singleton, thus made private. More...
 
cs_ret_code_t setInternal (const cs_state_data_t &data, PersistenceMode mode)
 
cs_ret_code_t removeInternal (const CS_TYPE &type, cs_state_id_t id, const PersistenceMode mode)
 
bool handleFactoryResetResult (cs_ret_code_t retCode)
 Handle factory reset result. More...
 
cs_ret_code_t getDefaultValue (cs_state_data_t &data)
 
cs_ret_code_t getIdsFromFlash (const CS_TYPE &type, std::vector< cs_state_id_t > *&ids)
 Get and cache all IDs with given type from flash. More...
 
cs_ret_code_t addId (const CS_TYPE &type, cs_state_id_t id)
 Add ID to list of cached IDs. More...
 
cs_ret_code_t remId (const CS_TYPE &type, cs_state_id_t id)
 Remove ID from list of cached IDs. More...
 
- Private Member Functions inherited from EventListener
 EventListener ()
 
virtual ~EventListener ()
 unregisters the listener. More...
 
virtual void handleEvent (event_t &event)=0
 Handle events. More...
 
void listen ()
 Registers this with the EventDispatcher. More...
 

Detailed Description

Stores state values in RAM and/or FLASH.

Each state type always has a FIRMWARE_DEFAULT value. Values that are set, always take precedence over the FIRMWARE_DEFAULT.

Values like chip temperature, that don't have to be stored over reboots should be stored in and read from RAM.

Values like CONFIG_BOOT_DELAY should be known over reboots of the device. Moreover, they should also persist over firmware updates. These values are stored in FLASH. If the values are not changed, they should NOT be stored to FLASH. They can then immediately be read from the FIRMWARE_DEFAULT. If these values are stored in FLASH, they always take precedence over FIRMWARE_DEFAULT values. Values that are stored in FLASH will be cached in RAM, to prevent having to read from FLASH every time. This complete persistence strategy is called STRATEGY1.

If a new firmware has a new FIRMWARE_DEFAULT that should be enforced, we need to explicitly remove the value from FLASH before updating the firmware. For example, a new CONFIG_BOOT_DELAY may have to be enforced, or else it might go into an infinite reboot loop.

For each state type it is defined whether it should be stored in RAM or FLASH.

All values that are stored to flash should also be stored in RAM. This is required, because storing to flash is asynchronous, the value must remain in RAM at least until the write is done.

Storing to flash can also fail, in which case it can be retried later. The state type will be put in a queue and retried after about STATE_RETRY_STORE_DELAY_MS ms.

Get procedure:

  1. Read RAM
    • if present, return RAM value.
  2. Get location (FLASH or RAM) 3a. If RAM
    • get default value.
    • store default value in RAM. 3b. If FLASH
    • read FLASH
    • if present, copy FLASH value to RAM.
    • if not present, get default value, store default value in RAM.
  3. Copy RAM value to return value.

Set procedure:

  1. Copy value to RAM.
  2. Get location (FLASH or RAM)
    • If RAM, return.
  3. Write to storage.
    • If success, return.
    • If busy, add state type to queue, return.

Constructor & Destructor Documentation

◆ ~State()

virtual State::~State ( )
virtual

◆ State() [1/2]

State::State ( )
private

State constructor, singleton, thus made private.

◆ State() [2/2]

State::State ( State const &  )
private

State copy constructor, singleton, thus made private.

Member Function Documentation

◆ addId()

cs_ret_code_t State::addId ( const CS_TYPE type,
cs_state_id_t  id 
)
private

Add ID to list of cached IDs.

Will NOT create a new list if no list for this type exists.

◆ addToQueue()

cs_ret_code_t State::addToQueue ( StateQueueOp  operation,
const CS_TYPE type,
cs_state_id_t  id,
uint32_t  delayMs,
const StateQueueMode  mode 
)
protected

Add an operation to queue.

Entries with the same type and operation will be overwritten. Write and remove of the same type will also overwrite each other.

Parameters
[in]operationType of operation.
[in]fileIdFlash file ID of the entry.
[in]typeState type.
[in]delayMsDelay in ms.
Returns
Return code.

◆ addToRam()

cs_state_data_t & State::addToRam ( const CS_TYPE type,
cs_state_id_t  id,
size16_t  size 
)
protected

Adds a new state_data struct to ram.

Allocates the struct and the data pointer.

Parameters
[in]typeState type.
[in]sizeState variable size.
Returns
Struct with allocated data pointer.

◆ allocate()

cs_ret_code_t State::allocate ( cs_state_data_t data)
protected

◆ cleanUp()

cs_ret_code_t State::cleanUp ( )

Clean up persistent storage.

Permanently deletes removed state variables, and defragments the persistent storage.

Returns
Success when cleaning up will be started.

◆ compareWithRam()

cs_ret_code_t State::compareWithRam ( const cs_state_data_t data,
uint32_t &  cmp_result 
)
protected

Check a particular value with the value currently in ram.

Parameters
[in]dataData with type, id, value, and size.
[out]cmp_resultValue that indicates comparison (equality indicated by 0).
Returns
Return code (e.g. ERR_SUCCESS, ERR_NOT_FOUND, etc.)

◆ delayedStoreTick()

void State::delayedStoreTick ( )
protected

◆ factoryReset()

void State::factoryReset ( )

Erase all used persistent storage.

◆ findInRam()

cs_ret_code_t State::findInRam ( const CS_TYPE type,
cs_state_id_t  id,
size16_t index_in_ram 
)
protected

Find given type in ram.

Parameters
[in]Typeto search for.
[in]Idto search for.
[out]Indexin ram register where the type was found.
Returns
ERR_SUCCESS when type was found.
ERR_NOT_FOUND when type was not found.

◆ get() [1/2]

cs_ret_code_t State::get ( const CS_TYPE  type,
void *  value,
size16_t  size 
)

Convenience function for get() with id 0.

Avoids having to create a temp every time you want to get a state variable.

◆ get() [2/2]

cs_ret_code_t State::get ( cs_state_data_t data,
const PersistenceMode  mode = PersistenceMode::STRATEGY1 
)

Get copy of a state value.

Parameters
[in,out]dataData struct with state type, id, data, and size. See cs_state_data_t.
[in]modeIndicates whether to get data from RAM, FLASH, FIRMWARE_DEFAULT, or a combination of this.
Returns
Return code.

◆ getDefaultValue()

cs_ret_code_t State::getDefaultValue ( cs_state_data_t data)
private

◆ getIds()

cs_ret_code_t State::getIds ( CS_TYPE  type,
std::vector< cs_state_id_t > *&  ids 
)

Get a list of IDs for given type.

Example usage: std::vector<cs_state_id_t>* ids = nullptr; retCode = State::getInstance().getIds(CS_TYPE::STATE_EXAMPLE, ids); if (retCode == ERR_SUCCESS) { for (auto id: *ids) {

Parameters
[in]typeState type.
[out]idsPointer to list of ids. This is not a copy, so make sure not to modify this list.
Returns
Return code.

◆ getIdsFromFlash()

cs_ret_code_t State::getIdsFromFlash ( const CS_TYPE type,
std::vector< cs_state_id_t > *&  ids 
)
private

Get and cache all IDs with given type from flash.

Parameters
[in]typeState type.
[out]idsList of ids.
Returns
Return code.

◆ getInstance()

static State & State::getInstance ( )
inlinestatic

Get a reference to the State object.

◆ getViaPointer()

cs_ret_code_t State::getViaPointer ( cs_state_data_t data,
const PersistenceMode  mode = PersistenceMode::STRATEGY1 
)

Get pointer to state value.

TODO: implement You can use this to avoid copying large state values of fixed length. However, you have to make sure to call setViaPointer() immediately after any change made in the data.

Parameters
[in,out]dataData struct with state type and size.

◆ handleEvent()

void State::handleEvent ( event_t event)
virtual

Handle (crownstone) events.

Implements EventListener.

◆ handleFactoryResetResult()

bool State::handleFactoryResetResult ( cs_ret_code_t  retCode)
private

Handle factory reset result.

@retrun False when factory reset needs to be retried.

◆ handleStorageError()

void State::handleStorageError ( cs_storage_operation_t  operation,
CS_TYPE  type,
cs_state_id_t  id 
)

Internal usage.

◆ init()

void State::init ( boards_config_t boardsConfig)

Initialize the State object with the board configuration.

Parameters
[in]boardsConfigBoard configuration (pin layout, etc.).

◆ isTrue()

bool State::isTrue ( CS_TYPE  type,
const PersistenceMode  mode = PersistenceMode::STRATEGY1 
)

Shorthand for get() for boolean data types, and id 0.

Parameters
[in]typeState type.
[in]modeIndicates whether to get data from RAM, FLASH, FIRMWARE_DEFAULT, or a combination of this.
Returns
True when state type is true.

◆ loadFromRam()

cs_ret_code_t State::loadFromRam ( cs_state_data_t data)
protected

Copies from ram to target buffer.

Does not check if target buffer has a large enough size.

Parameters
[in]data.typeType of data.
[in]data.idIdentifier of the data (to get a particular instance of a type).
[out]data.sizeThe size of the data retrieved.
[out]data.valueThe data itself.
Returns
Return value (i.e. ERR_SUCCESS or other).

◆ operator=()

void State::operator= ( State const &  )
private

Assignment operator, singleton, thus made private.

◆ remId()

cs_ret_code_t State::remId ( const CS_TYPE type,
cs_state_id_t  id 
)
private

Remove ID from list of cached IDs.

◆ remove()

cs_ret_code_t State::remove ( const CS_TYPE type,
cs_state_id_t  id,
const PersistenceMode  mode = PersistenceMode::STRATEGY1 
)

Remove a state variable.

Parameters
[in]typeThe state type to be removed.
[in]modeIndicates whether to remove data from RAM, FLASH, or a combination of this.
Returns
Return code.

◆ removeFromFlash()

cs_ret_code_t State::removeFromFlash ( const CS_TYPE type,
const cs_state_id_t  id 
)
protected

Remove given id of given type from flash.

Can return ERR_BUSY, in which case you have to retry again later.

Parameters
[in]typeState type.
[in]idState value id.
Returns
Return code.

◆ removeFromRam()

cs_ret_code_t State::removeFromRam ( const CS_TYPE type,
cs_state_id_t  id 
)
protected

Removed a state variable from ram.

Frees the data pointer and struct.

Parameters
[in]typeState type.
Returns
Return code.

◆ removeInternal()

cs_ret_code_t State::removeInternal ( const CS_TYPE type,
cs_state_id_t  id,
const PersistenceMode  mode 
)
private

◆ set() [1/2]

cs_ret_code_t State::set ( const cs_state_data_t data,
PersistenceMode  mode = PersistenceMode::STRATEGY1 
)

Set state to new value, via copy.

Parameters
[in]dataData struct with state type, optional id, data, and size.
[in]modeIndicates whether to set data in RAM, FLASH, or a combination of this.
Returns
ERR_SUCCESS The data has been set, and (depending on mode) will be written to flash. There will be an event EVT_STORAGE_WRITE_DONE once it's actually written to flash.
ERR_SUCCESS_NO_CHANGE The data did not change, and thus will NOT be written to flash. There will be NO event EVT_STORAGE_WRITE_DONE. Warning: when setDelayed() was used before set(), it can happen that this code is returned, while the data is not written to flash yet.
Other codes for errors.

◆ set() [2/2]

cs_ret_code_t State::set ( const CS_TYPE  type,
void *  value,
size16_t  size 
)

Convenience function for set().

Avoids having to create a temp every time you want to set a state variable.

◆ setDelayed()

cs_ret_code_t State::setDelayed ( const cs_state_data_t data,
uint8_t  delay 
)

Set the state to a new value, but delay the write to flash.

Assumes persistence mode STRATEGY1. Use this when you know a lot of sets of the same type may be done in a short time period. Each time this function is called, the timeout is reset.

Parameters
[in]dataData struct with state type, data, and size.
[in]delayHow long the delay should be, in seconds.
Returns
Return code.

◆ setInternal()

cs_ret_code_t State::setInternal ( const cs_state_data_t data,
PersistenceMode  mode 
)
private

◆ setThrottled()

cs_ret_code_t State::setThrottled ( const cs_state_data_t data,
uint32_t  period 
)

Write variable to flash in a throttled mode.

This function setThrottled will immediately write a value to flash, except when this has happened in the last period (indicated by a parameter). If this function is called during this period, the value will be updated in ram. Only after this period this value will then be written to flash. Also after this time, this will lead to a period in which throttling happens. For example, when the period parameter is set to 60000, all calls to setThrottled will result to calls to flash at a maximum rate of once per minute (for given data type).

Parameters
[in]dataData to store.
[in]periodPeriod in seconds that throttling will be in effect. Must be smaller than CS_STATE_QUEUE_DELAY_SECONDS_MAX.
Returns
Return code (e.g. ERR_SUCCES, ERR_WRONG_PARAMETER).

◆ setViaPointer()

cs_ret_code_t State::setViaPointer ( CS_TYPE  type)

Update state value.

TODO: implement Call this function after data has been changed via pointer. This makes sure the update will be propagated correctly.

Parameters
[in]typeThe state type that has been changed.

◆ startWritesToFlash()

void State::startWritesToFlash ( )

After calling this, state is allowed to write to flash.

Should be called once all reads are finished.

This is a quickfix to prevent failing flash reads during garbage collection. To properly fix this, read should be blocking. This can be done by handling FDS events in the interrupt, instead of via the app_scheduler. In those events, the busy state can be cleared, while cs events can be dispatched via the app_scheduler. Then, the read function can just wait with nrf_delay() until no longer busy.

◆ storeInFlash()

cs_ret_code_t State::storeInFlash ( size16_t index_in_ram)
protected

Writes state variable in ram to flash.

Can return ERR_BUSY, in which case you have to retry again later.

Parameters
[in]indexIndex in ram with the data to be written.
Returns
Return code.

◆ storeInRam() [1/2]

cs_ret_code_t State::storeInRam ( const cs_state_data_t data)
protected

Convenience function, in case you're not interested in index in ram.

◆ storeInRam() [2/2]

cs_ret_code_t State::storeInRam ( const cs_state_data_t data,
size16_t index_in_ram 
)
protected

Stores state variable in ram.

Allocates memory when not in ram yet, or when size changed.

Parameters
[in]dataData to be stored.
[out]index_in_ramIndex where the data is stored.
Returns
Return code.

◆ verifySizeForGet()

cs_ret_code_t State::verifySizeForGet ( const cs_state_data_t data)

Verify size of user data for getting a state.

Parameters
[in]dataData struct with state type, target, and size.
Returns
Return code.

◆ verifySizeForSet()

cs_ret_code_t State::verifySizeForSet ( const cs_state_data_t data)

Verify size of user data for setting a state.

Parameters
[in]dataData struct with state type, data, and size.
Returns
Return code.

Member Data Documentation

◆ _boardsConfig

boards_config_t* State::_boardsConfig
protected

◆ _idsCache

std::vector<cs_id_list_t> State::_idsCache
protected

Stores list of existing ids for certain types.

◆ _performingFactoryReset

bool State::_performingFactoryReset = false
protected

◆ _ram_data_register

std::vector<cs_state_data_t> State::_ram_data_register
protected

Stores state data structs with pointers to state data.

◆ _startedWritingToFlash

bool State::_startedWritingToFlash = false
protected

◆ _storage

Storage* State::_storage
protected

◆ _store_queue

std::vector<cs_state_store_queue_t> State::_store_queue
protected

Stores the queue of flash operations.


The documentation for this class was generated from the following file: