236 lines
7.4 KiB
C
236 lines
7.4 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#include "iot_pkt_api.h"
|
|
#include "iot_io_api.h"
|
|
#include "iot_errno_api.h"
|
|
#include "iot_module_api.h"
|
|
#include "iot_crc_api.h"
|
|
#include "iot_utils_api.h"
|
|
|
|
#include "iot_bsrm_flash.h"
|
|
#include "iot_bsrm_nv.h"
|
|
#include "iot_bsrm_common.h"
|
|
|
|
#if IOT_BSRM_MODE
|
|
|
|
/*----------------------------------------
|
|
* nv region layout shows like below
|
|
*----------------------------------------
|
|
* |---------------------------|
|
|
* | |
|
|
* | param | 512 bytes
|
|
* | |
|
|
* |---------------------------|
|
|
* | |
|
|
* | non-volatile info info | 512 bytes
|
|
* | |
|
|
* |---------------------------|
|
|
* | |
|
|
* | reserved | 3k bytes
|
|
* | |
|
|
* |---------------------------|
|
|
*/
|
|
|
|
/* parameter section */
|
|
#define IOT_BSRM_NV_PARAM_SEC_START IOT_BSRM_NV_REGION_START
|
|
#define IOT_BSRM_NV_PARAM_SEC_SIZE 512
|
|
#define IOT_BSRM_NV_PARAM_SEC_END \
|
|
(IOT_BSRM_NV_PARAM_SEC_START + IOT_BSRM_NV_PARAM_SEC_SIZE)
|
|
|
|
/* non-volatile info section */
|
|
#define IOT_BSRM_NV_INFO_SEC_START IOT_BSRM_NV_PARAM_SEC_END
|
|
#define IOT_BSRM_NV_INFO_SEC_SIZE 512
|
|
#define IOT_BSRM_NV_INFO_SEC_END \
|
|
(IOT_BSRM_NV_INFO_SEC_START + IOT_BSRM_NV_INFO_SEC_SIZE)
|
|
|
|
/* reserved section */
|
|
#define IOT_BSRM_NV_RESERV_SEC_START IOT_BSRM_NV_INFO_SEC_END
|
|
#define IOT_BSRM_NV_RESERV_SEC_SIZE (IOT_BSRM_NV_REGION_SIZE -\
|
|
IOT_BSRM_NV_PARAM_SEC_SIZE - IOT_BSRM_NV_INFO_SEC_SIZE)
|
|
#define IOT_BSRM_NV_RESERV_SEC_END \
|
|
(IOT_BSRM_NV_RESERV_SEC_START + IOT_BSRM_NV_RESERV_SEC_SIZE)
|
|
|
|
#pragma pack(push) /* save the pack status */
|
|
#pragma pack(1) /* 1 byte align */
|
|
|
|
/* param layout */
|
|
typedef struct _iot_bsrm_nv_param_sec {
|
|
/* crc value, used to check the validity of the section */
|
|
uint8_t crc;
|
|
/* content */
|
|
iot_bsrm_nv_param_t param;
|
|
} iot_bsrm_nv_param_sec_t;
|
|
|
|
/* non-volatile information layout */
|
|
typedef struct _iot_bsrm_nv_info_sec {
|
|
/* crc value, used to check the validity of the section */
|
|
uint8_t crc;
|
|
/* not used. */
|
|
uint8_t rsvd[3];
|
|
/* record number */
|
|
uint32_t rec_sn;
|
|
/* content */
|
|
iot_bsrm_nv_info_t info;
|
|
} iot_bsrm_nv_info_sec_t;
|
|
|
|
#pragma pack(pop)
|
|
|
|
static iot_bsrm_nv_param_sec_t *g_param_sec = NULL;
|
|
static iot_bsrm_nv_info_sec_t *g_info_sec = NULL;
|
|
|
|
static uint32_t cur_info_pos = 0;
|
|
static uint32_t last_info_sn = 0;
|
|
|
|
uint32_t iot_bsrm_nv_init(void)
|
|
{
|
|
uint32_t ret, last_sn, pos;
|
|
uint8_t crc, info_data_valid = 0;
|
|
|
|
BUILD_BUG_ON(IOT_BSRM_NV_PARAM_SEC_END <= IOT_BSRM_NV_RESERV_SEC_START);
|
|
BUILD_BUG_ON(sizeof(*g_param_sec) == IOT_BSRM_NV_PARAM_SEC_SIZE);
|
|
g_param_sec = (iot_bsrm_nv_param_sec_t *)os_mem_malloc( \
|
|
IOT_BSRM_MID, sizeof(*g_param_sec));
|
|
if (NULL == g_param_sec) {
|
|
ret = ERR_NOMEM;
|
|
goto out;
|
|
}
|
|
ret = iot_bsrm_flash_read(IOT_BSRM_NV_PARAM_SEC_START,
|
|
(uint8_t*)g_param_sec, sizeof(*g_param_sec));
|
|
if (ret ||
|
|
g_param_sec->crc != iot_getcrc8( \
|
|
(uint8_t *)&g_param_sec->param, \
|
|
sizeof(g_param_sec->param))) {
|
|
iot_bsrm_printf("%s param section empty\n", __FUNCTION__);
|
|
os_mem_set(g_param_sec, 0x0, sizeof(*g_param_sec));
|
|
}
|
|
|
|
/* recovery of information data */
|
|
BUILD_BUG_ON(sizeof(*g_info_sec) == 256);
|
|
last_sn = 0;
|
|
g_info_sec = (iot_bsrm_nv_info_sec_t *)os_mem_malloc(IOT_BRM_MID, \
|
|
sizeof(*g_info_sec));
|
|
if (g_info_sec == NULL) {
|
|
ret = ERR_NOMEM;
|
|
goto info_data_fail;
|
|
}
|
|
for (pos = IOT_BSRM_NV_INFO_SEC_START;
|
|
pos < IOT_BSRM_NV_INFO_SEC_END;) {
|
|
ret = iot_bsrm_flash_read(pos, (uint8_t*)g_info_sec,
|
|
sizeof(*g_info_sec));
|
|
if (ret == ERR_OK) {
|
|
crc = iot_getcrc8((uint8_t *)&g_info_sec->info,
|
|
sizeof(g_info_sec->info));
|
|
if (crc == g_info_sec->crc) {
|
|
if (g_info_sec->rec_sn > last_sn) {
|
|
cur_info_pos = pos;
|
|
last_sn = g_info_sec->rec_sn;
|
|
info_data_valid = 1;
|
|
}
|
|
}
|
|
}
|
|
pos += sizeof(*g_info_sec);
|
|
if (pos + sizeof(*g_info_sec) > IOT_BSRM_NV_INFO_SEC_END) {
|
|
break;
|
|
}
|
|
}
|
|
if (info_data_valid) {
|
|
ret = iot_bsrm_flash_read(cur_info_pos, (uint8_t*)g_info_sec,
|
|
sizeof(*g_info_sec));
|
|
if (ret) {
|
|
goto fail_1;
|
|
}
|
|
last_info_sn = last_sn;
|
|
} else {
|
|
fail_1:
|
|
iot_bsrm_printf("%s info_data_section empty\n", __FUNCTION__);
|
|
os_mem_set(g_info_sec, 0x0, sizeof(*g_info_sec));
|
|
cur_info_pos = 0;
|
|
}
|
|
iot_bsrm_printf("%s susses\n", __FUNCTION__);
|
|
goto out;
|
|
|
|
info_data_fail:
|
|
os_mem_free(g_param_sec);
|
|
g_param_sec = NULL;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
void *iot_bsrm_nv_get_section(iot_bsrm_nv_id_t id)
|
|
{
|
|
switch (id) {
|
|
case iot_bsrm_nv_id_param:
|
|
return &g_param_sec->param;
|
|
case iot_bsrm_nv_id_info:
|
|
return &g_info_sec->info;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void iot_bsrm_nv_update_section(iot_bsrm_nv_id_t id)
|
|
{
|
|
uint8_t *w_buf;
|
|
uint8_t ret;
|
|
uint32_t pos = 0x0, size;
|
|
|
|
switch (id) {
|
|
case iot_bsrm_nv_id_param:
|
|
{
|
|
g_param_sec->crc =
|
|
iot_getcrc8((uint8_t*)&g_param_sec->param,\
|
|
sizeof(g_param_sec->param));
|
|
pos = IOT_BSRM_NV_PARAM_SEC_START;
|
|
size = sizeof(*g_param_sec);
|
|
w_buf = (uint8_t *)g_param_sec;
|
|
break;
|
|
}
|
|
case iot_bsrm_nv_id_info:
|
|
{
|
|
g_info_sec->rec_sn = ++last_info_sn;
|
|
os_mem_set(g_info_sec->rsvd, 0, sizeof(g_info_sec->rsvd));
|
|
g_info_sec->crc = iot_getcrc8((uint8_t *)&g_info_sec->info,
|
|
sizeof(g_info_sec->info));
|
|
if (cur_info_pos < IOT_BSRM_NV_INFO_SEC_START ||
|
|
cur_info_pos >= IOT_BSRM_NV_INFO_SEC_END) {
|
|
cur_info_pos = IOT_BSRM_NV_INFO_SEC_START;
|
|
} else {
|
|
cur_info_pos += sizeof(*g_info_sec);
|
|
if (cur_info_pos + sizeof(*g_info_sec) >
|
|
IOT_BSRM_NV_INFO_SEC_END) {
|
|
cur_info_pos = IOT_BSRM_NV_INFO_SEC_START;
|
|
}
|
|
}
|
|
pos = cur_info_pos;
|
|
size = sizeof(*g_info_sec);
|
|
w_buf = (uint8_t *)g_info_sec;
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
ret = iot_bsrm_flash_write(pos, w_buf, size);
|
|
if (ret) {
|
|
iot_bsrm_printf("%s id %lu error\n", __FUNCTION__, id);
|
|
} else {
|
|
iot_bsrm_printf("%s id %lu success\n", __FUNCTION__, id);
|
|
}
|
|
}
|
|
|
|
#endif /* IOT_BSRM_MODE */
|