Files
kunlun/app/bsrm/iot_bsrm_nv.c
2024-09-28 14:24:04 +08:00

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 */