You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.6 KiB
132 lines
4.6 KiB
#ifndef _MODULE_STORAGE_h
|
|
#define _MODULE_STORAGE_h
|
|
|
|
#include "watchos_consts.h"
|
|
#include "watchos_types.h"
|
|
|
|
#include "Task.h"
|
|
|
|
// We pre-allocate a table for tracking storage allocations. This defines how
|
|
// many entries that supports.
|
|
#define MODULE_STORAGE_MAX_ENTRIES 16
|
|
|
|
struct StorageEntry;
|
|
|
|
/// <summary>
|
|
/// Module providing a coherent interface for persisting data
|
|
/// </summary>
|
|
class Module_Storage : public Task
|
|
{
|
|
/// <summary>
|
|
/// To validate that the storage we're reading is initialized, we store two bytes of magic
|
|
/// at the beginning.
|
|
/// </summary>
|
|
uint16_t m_magic;
|
|
/// <summary>
|
|
/// Storage tracks a version number to allow non-backward-compatible updates to be made
|
|
/// to the format in the future.
|
|
/// </summary>
|
|
byte m_version;
|
|
/// <summary>
|
|
/// One byte of storage is reserved to track top-level flags/options
|
|
/// </summary>
|
|
byte m_options;
|
|
|
|
/// <summary>
|
|
/// In-memory list of all storage allocations
|
|
/// </summary>
|
|
StorageEntry* m_entry[MODULE_STORAGE_MAX_ENTRIES];
|
|
|
|
/// <summary>
|
|
/// Convert a kernel well-known handle into a byte in the range 0-63
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Well known handles are used as a bitmask, so each distinct handle
|
|
/// only sets a single bit. In order to save on storage, internally we map
|
|
/// those to a single byte in the range 0-63.
|
|
/// </remarks>
|
|
/// <param name="handle">well known handle; one of the WATCHOS_MODULE_* consts</param>
|
|
/// <returns>a byte with a number in the range 0-63</returns>
|
|
byte wellKnownHandleToByte(well_known_handle_t handle);
|
|
|
|
/// <summary>
|
|
/// Get the offset of a specific module's data within storage
|
|
/// </summary>
|
|
/// <param name="module">id of the module to get offset for</param>
|
|
/// <returns>offset, in bytes, of the module's data</returns>
|
|
int getOffset(byte module);
|
|
|
|
public:
|
|
void initialize();
|
|
void start();
|
|
void suspend();
|
|
|
|
/// <summary>
|
|
/// Check whether the underlying storage contains valid and initialized storage
|
|
/// </summary>
|
|
/// <returns>true if valid; false if invalid</returns>
|
|
bool isValid();
|
|
|
|
/// <summary>
|
|
/// Load the storage allocations from persistent storage
|
|
/// </summary>
|
|
void load();
|
|
/// <summary>
|
|
/// Commit the storage allocations to persistent storage
|
|
/// </summary>
|
|
void commit();
|
|
/// <summary>
|
|
/// Reset all storage allocations and write an empty allocation
|
|
/// table to persistent storage.
|
|
/// </summary>
|
|
void reset();
|
|
|
|
/// <summary>
|
|
/// Allocate storage for a module
|
|
/// </summary>
|
|
/// <param name="module">module's handle</param>
|
|
/// <param name="size">number of bytes of storage to allocate</param>
|
|
/// <param name="options"></param>
|
|
/// <returns>true if an allocation was performed; false if an allocation already existed for the given module + size</returns>
|
|
bool allocate(well_known_handle_t module, uint16_t size, byte options = 0);
|
|
/// <summary>
|
|
/// Write data to a module's storage
|
|
/// </summary>
|
|
/// <param name="module">module to write for</param>
|
|
/// <param name="offset">offset, in bytes, within module's storage</param>
|
|
/// <param name="value">value to write at offset</param>
|
|
void write(well_known_handle_t module, uint16_t offset, byte value);
|
|
/// <summary>
|
|
/// Fetch data from a module's storage
|
|
/// </summary>
|
|
/// <param name="module">module to read for</param>
|
|
/// <param name="offset">offset, in bytes, within module's storage</param>
|
|
/// <returns>the value previously stored at that address</returns>
|
|
byte read(well_known_handle_t module, uint16_t offset);
|
|
|
|
/// <summary>
|
|
/// Allocate storage for a module
|
|
/// </summary>
|
|
/// <param name="module">module's handle</param>
|
|
/// <param name="size">number of bytes of storage to allocate</param>
|
|
/// <param name="options"></param>
|
|
/// <returns>true if an allocation was performed; false if an allocation already existed for the given module + size</returns>
|
|
bool allocate(byte module, uint16_t size, byte options = 0);
|
|
/// <summary>
|
|
/// Write data to a module's storage
|
|
/// </summary>
|
|
/// <param name="module">module to write for</param>
|
|
/// <param name="offset">offset, in bytes, within module's storage</param>
|
|
/// <param name="value">value to write at offset</param>
|
|
void write(byte module, uint16_t offset, byte value);
|
|
/// <summary>
|
|
/// Fetch data from a module's storage
|
|
/// </summary>
|
|
/// <param name="module">module to read for</param>
|
|
/// <param name="offset">offset, in bytes, within module's storage</param>
|
|
/// <returns>the value previously stored at that address</returns>
|
|
byte read(byte module, uint16_t offset);
|
|
|
|
};
|
|
|
|
#endif
|
|
|