初始版本
This commit is contained in:
365
external/tile/tile_shim/tile_storage/tile_storage.c
vendored
Normal file
365
external/tile/tile_shim/tile_storage/tile_storage.c
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
/**
|
||||
* NOTICE
|
||||
*
|
||||
* Copyright 2019 Tile Inc. All Rights Reserved.
|
||||
* All code or other information included in the accompanying files ("Tile Source Material")
|
||||
* is PROPRIETARY information of Tile Inc. ("Tile") and access and use of the Tile Source Material
|
||||
* is subject to these terms. The Tile Source Material may only be used for demonstration purposes,
|
||||
* and may not be otherwise distributed or made available to others, including for commercial purposes.
|
||||
* Without limiting the foregoing , you understand and agree that no production use
|
||||
* of the Tile Source Material is allowed without a Tile ID properly obtained under a separate
|
||||
* agreement with Tile.
|
||||
* You also understand and agree that Tile may terminate the limited rights granted under these terms
|
||||
* at any time in its discretion.
|
||||
* All Tile Source Material is provided AS-IS without warranty of any kind.
|
||||
* Tile does not warrant that the Tile Source Material will be error-free or fit for your purposes.
|
||||
* Tile will not be liable for any damages resulting from your use of or inability to use
|
||||
* the Tile Source Material.
|
||||
*
|
||||
* Support: firmware_support@tile.com
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file tile_storage.c
|
||||
* @brief Tile storage system
|
||||
*/
|
||||
#include "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(TILE_SUPPORT)
|
||||
|
||||
#include "tile_storage.h"
|
||||
|
||||
#include "tile_lib.h"
|
||||
#include "tile_config.h"
|
||||
#include "modules/tile_tmd_module.h"
|
||||
|
||||
#include "crc16.h"
|
||||
#include "nrf_fstorage.h"
|
||||
#include "nrf_soc.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "app_error.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Global variables
|
||||
******************************************************************************/
|
||||
|
||||
struct tile_persist_tag tile_persist __attribute__( (section("NoInit")) );
|
||||
|
||||
struct tile_checked_tag * const tile_checked = &tile_persist.checked.s;
|
||||
struct tile_unchecked_tag * const tile_unchecked = &tile_persist.unchecked.s;
|
||||
|
||||
struct tile_env_tag tile_env;
|
||||
|
||||
/*******************************************************************************
|
||||
* Local variables
|
||||
******************************************************************************/
|
||||
|
||||
static volatile bool write_in_progress = false;
|
||||
static volatile bool write_one_more_time = false;
|
||||
|
||||
const uint8_t interim_tile_id[8] = INTERIM_TILE_ID;
|
||||
const uint8_t interim_tile_key[16] = INTERIM_AUTH_KEY;
|
||||
/*******************************************************************************
|
||||
* Forward declarations
|
||||
******************************************************************************/
|
||||
uint16_t tile_get_adv_uuid(void);
|
||||
static void tile_app_on_flash_evt(nrf_fstorage_evt_t * evt);
|
||||
static int compare_versions(uint8_t v1, uint8_t v2);
|
||||
static struct tile_persist_tag * active_app_data_bank(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Flash region configuration
|
||||
******************************************************************************/
|
||||
|
||||
NRF_FSTORAGE_DEF(nrf_fstorage_t app_data_bank0) = {
|
||||
.start_addr = APP_DATA_BANK0_ADDRESS,
|
||||
.end_addr = (APP_DATA_BANK0_ADDRESS + APP_DATA_NUM_PAGES * PAGE_SIZE),
|
||||
.evt_handler = tile_app_on_flash_evt,
|
||||
};
|
||||
|
||||
NRF_FSTORAGE_DEF(nrf_fstorage_t app_data_bank1) = {
|
||||
.start_addr = APP_DATA_BANK1_ADDRESS,
|
||||
.end_addr = (APP_DATA_BANK1_ADDRESS + APP_DATA_NUM_PAGES * PAGE_SIZE),
|
||||
.evt_handler = tile_app_on_flash_evt,
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Global functions
|
||||
******************************************************************************/
|
||||
|
||||
/**@brief Sleep until an event is received. */
|
||||
static void power_manage(void)
|
||||
{
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
(void) sd_app_evt_wait();
|
||||
#else
|
||||
__WFE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
|
||||
{
|
||||
/* While fstorage is busy, sleep and wait for an event. */
|
||||
while (nrf_fstorage_is_busy(p_fstorage))
|
||||
{
|
||||
power_manage();
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**@brief Helper function to obtain the last address on the last page of the on-chip flash that
|
||||
* can be used to write user data.
|
||||
*/
|
||||
static uint32_t nrf5_flash_end_addr_get()
|
||||
{
|
||||
uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
|
||||
uint32_t const page_sz = NRF_FICR->CODEPAGESIZE;
|
||||
uint32_t const code_sz = NRF_FICR->CODESIZE;
|
||||
|
||||
return (bootloader_addr != 0xFFFFFFFF ?
|
||||
bootloader_addr : (code_sz * page_sz));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**@brief This function initializes two banks to be used in ping-pong manner in the Flash memory for usage by Tile Service.
|
||||
* Purpose of two banks is to provide a back-up in case memory storage fails at some point in time
|
||||
* This function checks for RAM and flash memory validity.
|
||||
* a) If RAM data is valid, it stores the data in the newer bank in flash.
|
||||
* b) If neither RAM nor flash is valid, it initializes the data to default values and stores in flash.
|
||||
* This should happen only at very first boot
|
||||
* c) If RAM data is not valid, but flash is, it gets latest data from flash, copies it to RAM, and updates newer flash bank
|
||||
*/
|
||||
void tile_storage_init(void)
|
||||
{
|
||||
ret_code_t ret;
|
||||
|
||||
ret = nrf_fstorage_init(&app_data_bank0, &nrf_fstorage_sd, NULL);
|
||||
APP_ERROR_CHECK(ret);
|
||||
ret = nrf_fstorage_init(&app_data_bank1, &nrf_fstorage_sd, NULL);
|
||||
APP_ERROR_CHECK(ret);
|
||||
|
||||
/* Check if RAM is still okay. Read from flash if not. */
|
||||
if(PERSIST_SIGNATURE == tile_persist.signature
|
||||
&& tile_persist.crc == crc16_compute(tile_persist.checked.d, sizeof(tile_persist.checked.d), NULL))
|
||||
{
|
||||
/* RAM checks out. No need to load from flash. */
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine current tile_persist bank
|
||||
struct tile_persist_tag *p = active_app_data_bank();
|
||||
|
||||
if(NULL == p)
|
||||
{
|
||||
// Initialize to sane values
|
||||
memset(&tile_persist, 0, sizeof(tile_persist));
|
||||
tile_checked->mode = TILE_MODE_SHIPPING;
|
||||
tile_checked->tdt_configuration = DEFAULT_TDT_CONFIG;
|
||||
memcpy(tile_checked->model_number, tile_model_number, TILE_MODEL_NUMBER_LEN);
|
||||
memcpy(tile_checked->hardware_version, tile_hw_version, TILE_HARDWARE_VERSION_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&tile_persist, p, sizeof(tile_persist));
|
||||
}
|
||||
}
|
||||
|
||||
tile_unchecked->reset_count++;
|
||||
|
||||
tile_store_app_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Save tile_persist to flash
|
||||
*/
|
||||
void tile_store_app_data(void)
|
||||
{
|
||||
ret_code_t ret;
|
||||
/* Compute CRC, to ensure most up-to-date version remains in RAM */
|
||||
tile_persist.crc = crc16_compute(tile_persist.checked.d, sizeof(tile_persist.checked.d), NULL);
|
||||
|
||||
if(write_in_progress)
|
||||
{
|
||||
write_one_more_time = true;
|
||||
return;
|
||||
}
|
||||
|
||||
write_in_progress = true;
|
||||
write_one_more_time = false;
|
||||
/* Update bank and ID */
|
||||
tile_checked->bank = !tile_checked->bank;
|
||||
tile_checked->id++;
|
||||
tile_checked->version = CHECKED_STRUCTURE_VERSION;
|
||||
tile_persist.signature = PERSIST_SIGNATURE;
|
||||
/* Recompute CRC, to account for bank switch */
|
||||
tile_persist.crc = crc16_compute(tile_persist.checked.d, sizeof(tile_persist.checked.d), NULL);
|
||||
|
||||
/* Save */
|
||||
if(0 == tile_checked->bank)
|
||||
{
|
||||
ret = nrf_fstorage_erase(&app_data_bank0, app_data_bank0.start_addr, APP_DATA_NUM_PAGES, NULL);
|
||||
APP_ERROR_CHECK(ret);
|
||||
ret = nrf_fstorage_write(&app_data_bank0, app_data_bank0.start_addr, &tile_persist, sizeof(tile_persist), NULL);
|
||||
APP_ERROR_CHECK(ret);
|
||||
|
||||
//wait_for_flash_ready(&app_data_bank1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = nrf_fstorage_erase(&app_data_bank1, app_data_bank1.start_addr, APP_DATA_NUM_PAGES, NULL);
|
||||
APP_ERROR_CHECK(ret);
|
||||
ret = nrf_fstorage_write(&app_data_bank1, app_data_bank1.start_addr, &tile_persist, sizeof(tile_persist), NULL);
|
||||
APP_ERROR_CHECK(ret);
|
||||
|
||||
//wait_for_flash_ready(&app_data_bank1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Fstorage callbacks
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Callback for flash activity not initiated by Tile Lib.
|
||||
*/
|
||||
static void tile_app_on_flash_evt(nrf_fstorage_evt_t * evt)
|
||||
{
|
||||
if (evt->result != NRF_SUCCESS)
|
||||
{
|
||||
NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");
|
||||
return;
|
||||
}
|
||||
if(NRF_FSTORAGE_EVT_WRITE_RESULT == evt->id)
|
||||
{
|
||||
NRF_LOG_DEBUG("Fstorage Write Event Callback\n");
|
||||
|
||||
write_in_progress = false;
|
||||
if(write_one_more_time)
|
||||
{
|
||||
tile_store_app_data();
|
||||
}
|
||||
}
|
||||
else if (NRF_FSTORAGE_EVT_ERASE_RESULT == evt->id)
|
||||
{
|
||||
NRF_LOG_DEBUG("Fstorage Erase Event Callback\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Local functions
|
||||
******************************************************************************/
|
||||
/**
|
||||
* @brief Compare 1-byte cyclic version counters
|
||||
*
|
||||
* We will define v1 < v2 if the difference (v2 - v1) mod 0x100
|
||||
* is less than 0x80 (this is equivalent to having v2 - v1 come out
|
||||
* positive in signed, 8-bit, 2's-complement arithmetic).
|
||||
*
|
||||
* @return 1 if v1 > v2, 0 if v1 = v2, and -1 if v1 < v2
|
||||
*/
|
||||
static int compare_versions(uint8_t v1, uint8_t v2)
|
||||
{
|
||||
/*
|
||||
* This returns (v1 > v2) - (v1 < v2), i.e.
|
||||
* 1 if v1 > v2, 0 if v1 = v2, and -1 if v1 < v2
|
||||
*/
|
||||
return (((v2 - v1) & 0xFF) > 0x80) - (((v2 - v1) & 0xFF) < 0x80);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decide which bank is active, based on the validity of the banks and their IDs
|
||||
*
|
||||
* @param[in] valid0 True if bank 0 is valid.
|
||||
* @param[in] valid1 True if bank 1 is valid.
|
||||
* @param[in] id0 ID of bank 0.
|
||||
* @param[in] id1 ID of bank 1.
|
||||
*
|
||||
* @return 0 if bank 0 is the active bank, 1 if bank 1 is the active bank, and
|
||||
* -1 if neither bank is valid.
|
||||
*/
|
||||
static int active_bank(bool valid0, bool valid1, uint8_t id0, uint8_t id1)
|
||||
{
|
||||
if(valid0 && valid1)
|
||||
{
|
||||
if(compare_versions(id0, id1) >= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if(valid0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(valid1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the active tile_checked bank.
|
||||
*
|
||||
* @return A pointer to the active tile_checked structure in flash, or NULL if
|
||||
* there is no active bank.
|
||||
*/
|
||||
static struct tile_persist_tag * active_app_data_bank(void)
|
||||
{
|
||||
struct tile_persist_tag *p0 = (void*)APP_DATA_BANK0_ADDRESS;
|
||||
struct tile_persist_tag *p1 = (void*)APP_DATA_BANK1_ADDRESS;
|
||||
|
||||
bool p0_valid = false;
|
||||
bool p1_valid = false;
|
||||
|
||||
if(PERSIST_SIGNATURE == p0->signature
|
||||
&& 0 == p0->checked.s.bank
|
||||
&& p0->crc == crc16_compute(p0->checked.d, sizeof(p0->checked.d), NULL))
|
||||
{
|
||||
p0_valid = true;
|
||||
}
|
||||
|
||||
if(PERSIST_SIGNATURE == p1->signature
|
||||
&& 1 == p1->checked.s.bank
|
||||
&& p1->crc == crc16_compute(p1->checked.d, sizeof(p1->checked.d), NULL))
|
||||
{
|
||||
p1_valid = true;
|
||||
}
|
||||
|
||||
int bank = active_bank(p0_valid, p1_valid, p0->checked.s.id, p1->checked.s.id);
|
||||
|
||||
if(bank < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if(0 == bank)
|
||||
{
|
||||
return p0;
|
||||
}
|
||||
else if(1 == bank)
|
||||
{
|
||||
return p1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assert! We don't expect any other value to be returned. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(TILE_SUPPORT)
|
||||
168
external/tile/tile_shim/tile_storage/tile_storage.h
vendored
Normal file
168
external/tile/tile_shim/tile_storage/tile_storage.h
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* NOTICE
|
||||
*
|
||||
* Copyright 2016 Tile Inc. All Rights Reserved.
|
||||
* All code or other information included in the accompanying files ("Tile Source Material")
|
||||
* is PROPRIETARY information of Tile Inc. ("Tile") and access and use of the Tile Source Material
|
||||
* is subject to these terms. The Tile Source Material may only be used for demonstration purposes,
|
||||
* and may not be otherwise distributed or made available to others, including for commercial purposes.
|
||||
* Without limiting the foregoing , you understand and agree that no production use
|
||||
* of the Tile Source Material is allowed without a Tile ID properly obtained under a separate
|
||||
* agreement with Tile.
|
||||
* You also understand and agree that Tile may terminate the limited rights granted under these terms
|
||||
* at any time in its discretion.
|
||||
* All Tile Source Material is provided AS-IS without warranty of any kind.
|
||||
* Tile does not warrant that the Tile Source Material will be error-free or fit for your purposes.
|
||||
* Tile will not be liable for any damages resulting from your use of or inability to use
|
||||
* the Tile Source Material.
|
||||
*
|
||||
* Support: firmware_support@tile.com
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file tile_storage.h
|
||||
* @brief Tile storage system
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TILE_STORAGE_H_
|
||||
#define TILE_STORAGE_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tile_lib.h"
|
||||
#include "nrf_fstorage_sd.h"
|
||||
#include "tile_tdt_module.h"
|
||||
#include "ble_gap.h"
|
||||
|
||||
|
||||
/*****************************************/
|
||||
/* Copied from nordic14, TO DO: find correct definitions for Nordic 15.2 */
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
/* These addresses should be the two pages directly before the default bootloader location */
|
||||
#define APP_DATA_BANK0_ADDRESS 0x76000
|
||||
#define APP_DATA_BANK1_ADDRESS 0x77000
|
||||
|
||||
|
||||
#define APP_DATA_NUM_PAGES 1
|
||||
/****************************************/
|
||||
|
||||
#define DEFAULT_ADVERTISING_INTERVAL 160
|
||||
|
||||
|
||||
#define PERSIST_SIGNATURE 0xA5A5
|
||||
#define CHECKED_SIZE 128
|
||||
#define UNCHECKED_SIZE 256
|
||||
|
||||
#define CHECKED_STRUCTURE_VERSION_1 1
|
||||
#define CHECKED_STRUCTURE_VERSION_2 2
|
||||
#define CHECKED_STRUCTURE_VERSION_3 3
|
||||
#define CHECKED_STRUCTURE_VERSION_4 4
|
||||
#define CHECKED_STRUCTURE_VERSION CHECKED_STRUCTURE_VERSION_1
|
||||
|
||||
extern nrf_fstorage_t app_data_bank0;
|
||||
extern nrf_fstorage_t app_data_bank1;
|
||||
|
||||
extern uint8_t bdaddr[BLE_GAP_ADDR_LEN];
|
||||
extern const uint8_t interim_tile_id[];
|
||||
extern const uint8_t interim_tile_key[];
|
||||
extern const char tile_model_number[];
|
||||
extern const char tile_hw_version[];
|
||||
|
||||
struct tile_checked_tag
|
||||
{
|
||||
/**************************************************************************************************/
|
||||
/*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ****/
|
||||
/*** THIS STRUCTURE IS SAVED TO FLASH AND RETRIEVED AFTER TOFU ****/
|
||||
/*** THIS MEANS STUFF SHOULD NOT BE MODIFIED BUT ONLY AT THE END TO MAINTAIN COMPATIBILITY ****/
|
||||
/**************************************************************************************************/
|
||||
uint16_t version;
|
||||
uint8_t id;
|
||||
uint8_t bank;
|
||||
uint8_t mode;
|
||||
uint16_t adv_int;
|
||||
tdt_config_t tdt_configuration;
|
||||
uint8_t tile_id[TILE_ID_LEN];
|
||||
uint8_t tile_auth_key[TILE_AUTH_KEY_LEN];
|
||||
char model_number[TILE_MODEL_NUMBER_LEN];
|
||||
char hardware_version[TILE_HARDWARE_VERSION_LEN];
|
||||
uint8_t bdaddr[TILE_BDADDR_LEN];
|
||||
uint8_t tileIDkey[TILEID_KEY_LEN];
|
||||
};
|
||||
|
||||
struct tile_unchecked_tag
|
||||
{
|
||||
/**************************************************************************************************/
|
||||
/*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ****/
|
||||
/*** THIS STRUCTURE IS SAVED TO FLASH AND RETRIEVED AFTER TOFU ****/
|
||||
/*** THIS MEANS STUFF SHOULD NOT BE MODIFIED BUT ONLY AT THE END TO MAINTAIN COMPATIBILITY ****/
|
||||
/**************************************************************************************************/
|
||||
|
||||
// Activity tracking
|
||||
uint32_t connection_count; /**< number of connections */
|
||||
uint32_t disconnect_count; /**< Number of disconnections */
|
||||
uint8_t auth_fail_count; /**< authentication failures count */
|
||||
uint8_t micFailures; /**< mic failures */
|
||||
uint8_t reset_count; /**< Reset Count */
|
||||
uint32_t piezoMs; /**< time for which piezo was active in '10 ms' units */
|
||||
|
||||
// TOA Activity monitoring
|
||||
uint32_t toa_channel_open_count; /**< Number of successfull TOA Channel Open (with a successfull authentication) */
|
||||
uint32_t toa_authenticate_count; /**< number of TOA Authenticate Commands received */
|
||||
uint16_t tka_closed_channel_count; /**< number of TOA Channel close triggered by TKA */
|
||||
uint16_t auth_disconnect_count; /**< number of disconnections triggered by Auth Timer */
|
||||
|
||||
//Counter for private ID
|
||||
uint16_t tileIDcounter; /**< Counter used for PrivateID */
|
||||
};
|
||||
|
||||
struct tile_persist_tag
|
||||
{
|
||||
uint16_t crc;
|
||||
uint16_t signature;
|
||||
union
|
||||
{
|
||||
struct tile_checked_tag s;
|
||||
uint8_t d[CHECKED_SIZE-4]; /* -4 for CRC + signature */
|
||||
} checked __attribute__ ((aligned (4)));
|
||||
union
|
||||
{
|
||||
struct tile_unchecked_tag s;
|
||||
uint8_t d[UNCHECKED_SIZE];
|
||||
} unchecked __attribute__ ((aligned (4)));
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Persistent structure, which is saved to flash. Does not need to be
|
||||
* accessed directly. Access elements with tile_checked and tile_unchecked.
|
||||
*/
|
||||
extern struct tile_persist_tag tile_persist;
|
||||
|
||||
/**
|
||||
* @brief CRC checked portion of persistent data.
|
||||
*/
|
||||
extern struct tile_checked_tag * const tile_checked;
|
||||
|
||||
/**
|
||||
* @brief Non-CRC portion of persistent data. This get reinitialized when
|
||||
* the CRC of the checked portion fails.
|
||||
*/
|
||||
extern struct tile_unchecked_tag * const tile_unchecked;
|
||||
|
||||
/**
|
||||
* @brief Tile environment data. Lost at reboot.
|
||||
*/
|
||||
struct tile_env_tag
|
||||
{
|
||||
uint16_t last_reset_reason; ///> Contains the reason for the last reset
|
||||
uint8_t authorized;
|
||||
uint8_t hashedTileID[TILE_HASHED_TILEID_LEN];
|
||||
};
|
||||
|
||||
extern struct tile_env_tag tile_env;
|
||||
|
||||
void tile_storage_init(void);
|
||||
void tile_store_app_data(void);
|
||||
#endif
|
||||
Reference in New Issue
Block a user