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

854 lines
26 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 "os_utils_api.h"
#include "iot_crc_api.h"
#include "iot_errno_api.h"
#include "iot_utils_api.h"
#include "iot_bsrm_common.h"
#include "iot_bsrm_rec.h"
#include "iot_bsrm_flash.h"
/* select record crc16 type */
#define IOT_BSRM_REC_CRC16_TYPE IOT_CRC16_TYPE_X25
/* define record read buffer size */
#define IOT_BSRM_REC_READ_BUF_SIZE (1024)
/* define max info of information record */
#define IOT_BSRM_REC_INFO_BRANCH_MAX (2001)
/* define max branch event record */
#define IOT_BSRM_BRANCH_EVT_MAX (251)
/* enable/disable record information data print */
#define IOT_BSRM_REC_DEBUG 0
/* define the maximum number of events supported */
#define IOT_BSRM_EVT_SUPPORT_MAX 14
#pragma pack(push) /* save the pack status */
#pragma pack(1) /* 1 byte align */
/* record head */
typedef struct iot_bsrm_rec_head {
/* record sequence number */
uint32_t rec_seq;
/* time stamp */
uint32_t ts;
/* check crc */
uint16_t crc;
/* payload label */
uint8_t data[0];
} iot_bsrm_rec_head_t;
#pragma pack(pop)
/* record region descriptor */
typedef struct iot_bsrm_rec_region_desc {
/* record entry size, contains record headers */
uint32_t entry_size;
/* region start position */
uint32_t start;
/* region size */
uint32_t size;
/* recording depth */
uint32_t rec_depth;
/* record serial number will assigned */
uint32_t seq;
/* recording depth */
uint32_t new_idx;
uint32_t oldest_idx;
/* timestamp of the latest record */
uint32_t last_rec_ts;
} iot_bsrm_rec_region_desc_t;
#if IOT_BSRM_MODE
static iot_bsrm_rec_region_desc_t g_info_region;
static iot_bsrm_rec_region_desc_t g_evt_region;
static uint8_t *g_buf;
static inline uint32_t iot_bsrm_rec_idx_inc(iot_bsrm_rec_region_desc_t *rec_desc,
uint32_t org_idx)
{
uint32_t new_idx;
new_idx = org_idx + 1;
if (new_idx >= rec_desc->rec_depth) {
new_idx = 0;
}
return new_idx;
}
static inline uint32_t iot_bsrm_rec_idx_dec(iot_bsrm_rec_region_desc_t *rec_desc,
uint32_t org_idx)
{
uint32_t new_idx;
if (org_idx)
new_idx = org_idx - 1;
else
new_idx = rec_desc->rec_depth - 1;
return new_idx;
}
static uint32_t iot_bsrm_rec_get_cnt(iot_bsrm_rec_region_desc_t *desc)
{
if (desc->new_idx >= desc->oldest_idx)
return (desc->new_idx - desc->oldest_idx);
else
return (desc->new_idx + desc->rec_depth \
- desc->oldest_idx);
}
static uint32_t iot_bsrm_rec_get_before_cnt(
iot_bsrm_rec_region_desc_t *desc, uint32_t org_idx)
{
if (org_idx >= desc->oldest_idx)
return (org_idx - desc->oldest_idx);
else
return (org_idx + desc->rec_depth \
- desc->oldest_idx);
}
static uint32_t iot_bsrm_get_ramain_cnt(iot_bsrm_rec_region_desc_t *desc,
uint32_t idx)
{
if (desc->new_idx >= idx)
return (desc->new_idx - idx);
else
return (desc->new_idx + desc->rec_depth \
- idx);
}
static uint32_t iot_bsrm_rec_seq_inc(uint32_t seq)
{
seq++;
if ((seq & 0xffffffff) == 0) {
seq = 1;
}
return seq;
}
static inline uint32_t iot_bsrm_rec_idx_sub(iot_bsrm_rec_region_desc_t *desc,
uint32_t org_idx, uint32_t sub)
{
uint32_t new_idx;
new_idx = org_idx;
while (sub-- > 0) {
new_idx = iot_bsrm_rec_idx_dec(desc, new_idx);
}
return new_idx;
}
uint8_t iot_bsrm_rec_read(iot_bsrm_rec_region_desc_t *p_rec_desc,
uint32_t last_idx, uint32_t *ts, iot_pkt_t **pkt)
{
uint8_t reason;
uint16_t crc;
uint8_t ret;
iot_pkt_t *buf;
iot_bsrm_rec_head_t *hdr;
uint32_t real_idx, pos;
if (!last_idx || last_idx > iot_bsrm_rec_get_cnt(p_rec_desc)) {
reason = 1;
goto err;
}
real_idx = iot_bsrm_rec_idx_sub(p_rec_desc, p_rec_desc->new_idx, last_idx);
pos = p_rec_desc->start + real_idx * p_rec_desc->entry_size;
buf = iot_pkt_alloc(p_rec_desc->entry_size, IOT_BSRM_MID);
if (buf == NULL) {
reason = 2;
goto err;
}
iot_pkt_put(buf, p_rec_desc->entry_size);
ret = iot_bsrm_flash_read(pos, iot_pkt_data(buf),
p_rec_desc->entry_size);
if (ret) {
reason = 3;
goto err_1;
}
hdr = (iot_bsrm_rec_head_t *)iot_pkt_data(buf);
crc = iot_getcrc16(hdr->data,
p_rec_desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
if (hdr->crc != crc) {
reason = 4;
goto err_1;
}
iot_pkt_set_data(buf, hdr->data);
*pkt = buf;
*ts = hdr->ts;
ret = ERR_OK;
goto out;
err_1:
iot_pkt_free(buf);
err:
ret = ERR_FAIL;
iot_bsrm_printf("%s fail reason %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static void iot_bsrm_rec_cnt_clear(iot_bsrm_rec_region_desc_t *desc)
{
desc->new_idx = 0;
desc->oldest_idx = 0;
desc->last_rec_ts = 0;
}
static void iot_bsrm_rec_clear(iot_bsrm_rec_region_desc_t *desc)
{
uint8_t *clear_buf = g_buf;
uint32_t total_len, clear_len, offset;
total_len = desc->size;
offset = desc->start;
os_mem_set(clear_buf, 0, IOT_BSRM_REC_READ_BUF_SIZE);
while (total_len) {
clear_len = min(total_len, IOT_BSRM_REC_READ_BUF_SIZE);
iot_bsrm_flash_write(offset, clear_buf, clear_len);
total_len -= clear_len;
offset += clear_len;
os_delay(5);
}
}
void iot_bsrm_rec_info_clear(void)
{
uint32_t ts;
if (iot_bsrm_rec_get_cnt(&g_info_region)) {
ts = os_boot_time32();
iot_bsrm_rec_cnt_clear(&g_info_region);
iot_bsrm_rec_clear(&g_info_region);
ts = os_boot_time32() - ts;
iot_bsrm_printf("%s spend %lu ms\n", __FUNCTION__, ts);
}
}
void iot_bsrm_rec_evt_clear(void)
{
uint32_t ts;
if (iot_bsrm_rec_get_cnt(&g_evt_region)) {
ts = os_boot_time32();
iot_bsrm_rec_cnt_clear(&g_evt_region);
iot_bsrm_rec_clear(&g_evt_region);
ts = os_boot_time32() - ts;
iot_bsrm_printf("%s spend %lu ms\n", __FUNCTION__, ts);
}
}
static inline uint32_t iot_bsrm_rec_idx_add(iot_bsrm_rec_region_desc_t *desc,
uint32_t org_idx, uint32_t add)
{
uint32_t new_idx;
new_idx = org_idx;
while (add-- > 0) {
new_idx = iot_bsrm_rec_idx_inc(desc, new_idx);
}
return new_idx;
}
static uint32_t iot_bsrm_rec_mid_calc(iot_bsrm_rec_region_desc_t *rec_desc,
uint32_t left, uint32_t right)
{
uint32_t cnt = 0, mid;
if (right >= left)
cnt = right - left;
else
cnt = right + rec_desc->rec_depth - left;
mid = iot_bsrm_rec_idx_add(rec_desc, left, cnt >> 1);
return mid;
}
static uint8_t iot_bsrm_info_rec_bin_search(
iot_bsrm_rec_region_desc_t *desc, uint32_t *ts, uint32_t *idx)
{
uint8_t ret = ERR_OK, *buf = g_buf;
uint16_t crc;
uint32_t l_idx, r_idx, mid_calc, real_mid;
iot_bsrm_rec_head_t *hdr;
uint32_t pos;
int32_t near_idx = -1;
uint32_t tmp_ts = *ts;
l_idx = desc->oldest_idx;
r_idx = desc->new_idx;
while (l_idx != r_idx) {
mid_calc = iot_bsrm_rec_mid_calc(desc, l_idx, r_idx);
real_mid = mid_calc;
while (real_mid != r_idx) {
pos = desc->start + real_mid * desc->entry_size;
ret = iot_bsrm_flash_read(pos, buf, desc->entry_size);
if (ret != ERR_OK) {
real_mid = iot_bsrm_rec_idx_inc(desc, real_mid);
continue;
}
hdr = (iot_bsrm_rec_head_t *)buf;
crc = iot_getcrc16(hdr->data,
desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
if (hdr->crc != crc) {
real_mid = iot_bsrm_rec_idx_inc(desc, real_mid);
ret = ERR_FAIL;
continue;
}
break;
}
if (ret) {
r_idx = mid_calc;
continue;
}
hdr = (iot_bsrm_rec_head_t *)buf;
if (hdr->ts == *ts) {
*idx = real_mid;
return ERR_OK;
} else if (hdr->ts < *ts) {
l_idx = iot_bsrm_rec_idx_inc(desc, real_mid);
} else {
tmp_ts = hdr->ts;
near_idx = real_mid;
r_idx = real_mid;
}
}
if (near_idx != -1) {
*ts = tmp_ts;
*idx = near_idx;
return ERR_OK;
}
return ERR_FAIL;
}
int32_t iot_bsrm_branch_info_entry_assig(void *rec,
uint8_t *out_data, uint32_t len_limit)
{
iot_bsrm_branch_info_entry_t *entry;
if (len_limit < sizeof(*entry)) {
return -1;
}
entry = (iot_bsrm_branch_info_entry_t *)out_data;
if (rec == NULL) {
os_mem_set(entry, 0x00, sizeof(*entry));
} else {
os_mem_cpy(entry, rec, sizeof(*entry));
}
return (int32_t)(sizeof(*entry));
}
uint32_t iot_bsrm_info_rec_search(iot_bsrm_rec_region_desc_t *desc,
uint32_t ts, uint32_t *idx)
{
uint32_t find_idx, tmp_idx, cur_idx, pos;
uint8_t ret, i;
iot_bsrm_rec_head_t *hdr;
uint16_t crc;
uint8_t *buf;
uint32_t idx_cnt;
uint32_t rel_ts = ts;
ret = iot_bsrm_info_rec_bin_search(desc, &rel_ts, &find_idx);
if (ret != ERR_OK) {
return ret;
}
idx_cnt = iot_bsrm_rec_get_before_cnt(desc, find_idx);
idx_cnt = min(idx_cnt, 3);
tmp_idx = iot_bsrm_rec_idx_sub(desc, find_idx, idx_cnt);
cur_idx = tmp_idx;
for (i = 0; i < idx_cnt; i++) {
buf = g_buf;
pos = desc->start + cur_idx * desc->entry_size;
ret = iot_bsrm_flash_read(pos, buf, desc->entry_size);
if (ret != ERR_OK) {
return ret;
}
cur_idx = iot_bsrm_rec_idx_inc(desc, cur_idx);
hdr = (iot_bsrm_rec_head_t *)buf;
crc = iot_getcrc16(hdr->data,
desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
if (hdr->crc != crc) {
continue;
}
if (hdr->ts == rel_ts) {
break;
}
}
if (i == idx_cnt) {
*idx = find_idx;
} else {
*idx = iot_bsrm_rec_idx_add(desc, tmp_idx, i);
}
return ERR_OK;
}
uint8_t iot_bsrm_evt_read(uint32_t evt_num, uint8_t **evt)
{
uint8_t ret = ERR_OK, reason;
uint8_t *buf;
uint16_t crc;
uint32_t idx, pos;
iot_bsrm_rec_head_t *hdr;
iot_bsrm_rec_region_desc_t *desc = &g_evt_region;
if (!evt_num || iot_bsrm_rec_get_cnt(desc) < evt_num) {
ret = ERR_NOT_EXIST;
reason = 1;
goto err;
}
idx = iot_bsrm_rec_idx_sub(desc, desc->new_idx, evt_num);
pos = desc->start + idx * desc->entry_size;
buf = g_buf;
ret = iot_bsrm_flash_read(pos, buf, desc->entry_size);
if (ret != ERR_OK) {
ret = ERR_NOT_EXIST;
reason = 2;
goto err;
}
hdr = (iot_bsrm_rec_head_t *)buf;
crc = iot_getcrc16(hdr->data,
desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
if (hdr->crc != crc) {
ret = ERR_INVAL;
reason = 3;
goto err;
}
*evt = buf + sizeof(*hdr);
goto out;
err:
iot_bsrm_printf("%s fail reason %lu\n", __FUNCTION__, reason);
out:
return ret;
}
uint8_t iot_bsrm_info_rec_read(uint32_t *ts, uint16_t *total_cnt,
uint8_t *n, iot_pkt_t **pkt, uint16_t start_idx)
{
uint8_t ret;
uint8_t reason = 0;
uint32_t i, j;
uint32_t find_idx = 0, pos, entry_n;
uint32_t len_limit;
iot_pkt_t *pkt_buf = NULL;
iot_bsrm_rec_region_desc_t *desc = &g_info_region;
uint8_t fill_n = 0, valid_fill_n = 0, read_n = *n;
uint8_t *out_buf;
uint32_t re_n[2] = { 0 }, cnt = 0;
uint8_t *buf;
iot_bsrm_rec_head_t *hdr;
uint16_t crc;
int32_t temp;
if (iot_bsrm_rec_get_cnt(desc) == 0) {
reason = 1;
goto err;
}
if (*ts > desc->last_rec_ts) {
reason = 2;
goto err;
}
ret = (uint8_t)iot_bsrm_info_rec_search(desc, *ts, &find_idx);
if (ret != ERR_OK) {
reason = 3;
goto err;
}
cnt = iot_bsrm_get_ramain_cnt(desc, find_idx);
*total_cnt = (uint16_t)cnt;
if (start_idx >= cnt) {
reason = 4;
goto err;
}
read_n = (uint8_t)min(cnt - start_idx, read_n);
find_idx = iot_bsrm_rec_idx_add(desc, find_idx, start_idx);
len_limit = min(sizeof(iot_bsrm_branch_info_entry_t) * (read_n),
IOT_BSRM_REC_READ_BUF_SIZE);
pkt_buf = iot_pkt_alloc(len_limit, IOT_BSRM_MID);
if (pkt_buf == NULL) {
reason = 5;
goto err;
}
out_buf = iot_pkt_data(pkt_buf);
if (find_idx < desc->new_idx) {
re_n[0] = desc->new_idx - find_idx;
} else if (find_idx > desc->new_idx) {
re_n[0] = desc->rec_depth - find_idx;
re_n[1] = desc->new_idx;
} else {
IOT_ASSERT(0);
}
for (i = 0; i < 2; i++) {
while (re_n[i]) {
pos = desc->start + find_idx * desc->entry_size;
entry_n = IOT_BSRM_REC_READ_BUF_SIZE / desc->entry_size;
entry_n = (re_n[i] > entry_n ? entry_n : re_n[i]);
buf = g_buf;
ret = iot_bsrm_flash_read(pos, buf, entry_n * desc->entry_size);
if (ret != ERR_OK) {
goto done;
}
for (j = 0; j < entry_n; j++) {
hdr = (iot_bsrm_rec_head_t *)buf;
crc = iot_getcrc16(hdr->data,
desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
if (hdr->crc != crc) {
buf += desc->entry_size;
continue;
}
temp = iot_bsrm_branch_info_entry_assig(hdr->data, out_buf,
len_limit);
if (temp == -1) {
goto done;
} else {
buf += desc->entry_size;
fill_n++;
valid_fill_n++;
len_limit -= temp;
out_buf += temp;
iot_pkt_put(pkt_buf, (uint32_t)temp);
if (fill_n == read_n) {
goto done;
}
}
}
re_n[i] -= entry_n;
find_idx = iot_bsrm_rec_idx_add(desc, find_idx, entry_n);
}
}
goto done;
err:
iot_bsrm_printf("%s err reason %lu\n", __FUNCTION__, reason);
valid_fill_n = 0;
done:
if (valid_fill_n) {
*pkt = pkt_buf;
*n = fill_n;
} else {
ret = ERR_NOT_EXIST;
if (pkt_buf)
iot_pkt_free(pkt_buf);
}
return ret;
}
void iot_bsrm_rec_write(iot_bsrm_rec_region_desc_t *desc, uint32_t ts,
uint8_t *rec_data, uint8_t is_overlast)
{
uint32_t pos;
uint16_t crc;
iot_bsrm_rec_head_t *hdr = (iot_bsrm_rec_head_t *)rec_data;
crc = iot_getcrc16(hdr->data,
desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
hdr->crc = crc;
if (is_overlast && iot_bsrm_rec_get_cnt(desc) > 0) {
desc->new_idx =
iot_bsrm_rec_idx_dec(desc, desc->new_idx);
}
pos = desc->start + desc->new_idx * desc->entry_size;
if (iot_bsrm_flash_write(pos, rec_data, desc->entry_size) != ERR_OK) {
iot_bsrm_printf("%s fail\n", __FUNCTION__);
goto out;
}
iot_bsrm_printf("%s part_%08x, addr_region[%08x - %08x]\n",
__FUNCTION__, desc->start, pos, pos + desc->entry_size - 1);
desc->new_idx = \
iot_bsrm_rec_idx_inc(desc, desc->new_idx);
desc->last_rec_ts = ts;
if (desc->new_idx == desc->oldest_idx) {
desc->oldest_idx = \
iot_bsrm_rec_idx_inc(desc, desc->oldest_idx);
}
desc->seq = iot_bsrm_rec_seq_inc(desc->seq);
out:
return;
}
void iot_bsrm_evt_rec_write(uint8_t *evt_buf)
{
uint32_t ts;
iot_time_tm_t tm;
iot_bsrm_rec_head_t *hdr;
iot_bsrm_rec_region_desc_t *desc = &g_evt_region;
iot_rtc_get(&tm);
ts = iot_bsrm_rtctime_to_time(&tm);
hdr = (iot_bsrm_rec_head_t *)g_buf;
hdr->rec_seq = desc->seq;
hdr->ts = ts;
os_mem_cpy(hdr->data, evt_buf, sizeof(iot_bsrm_branch_evt_rec_entry_t));
iot_bsrm_rec_write(desc, ts, g_buf, 0);
}
void iot_bsrm_info_rec(uint32_t ts, uint8_t len, uint8_t *data)
{
iot_bsrm_rec_region_desc_t *desc = &g_info_region;
uint32_t pos, exist_idx;
uint8_t reason, ret;
iot_bsrm_rec_head_t *hdr;
uint16_t crc;
if (ts < desc->last_rec_ts) {
pos = desc->start + desc->oldest_idx * desc->entry_size;
ret = iot_bsrm_flash_read(pos, g_buf, desc->entry_size);
if (ret != ERR_OK) {
reason = 1;
goto err;
}
hdr = (iot_bsrm_rec_head_t *)g_buf;
crc = iot_getcrc16(hdr->data,
desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
if (hdr->crc != crc) {
reason = 2;
goto err;
}
iot_bsrm_printf("%s war, info ts %lu less last ts %lu\n",
__FUNCTION__, ts, desc->last_rec_ts);
if (ts < hdr->ts) {
/* the point to be recorded is earlier than all the historical
* records.
*/
desc->new_idx = iot_bsrm_rec_idx_dec(desc, desc->new_idx);
desc->oldest_idx = desc->new_idx;
} else {
ret = (uint8_t)iot_bsrm_info_rec_search(desc, ts, &exist_idx);
if (ret != ERR_OK) {
desc->new_idx = iot_bsrm_rec_idx_dec(desc, desc->new_idx);
desc->oldest_idx = desc->new_idx;
} else {
desc->new_idx = exist_idx;
}
}
}
hdr = (iot_bsrm_rec_head_t *)g_buf;
hdr->rec_seq = desc->seq;
hdr->ts = ts;
os_mem_cpy(hdr->data, data, len);
iot_bsrm_rec_write(desc, ts, g_buf, 0);
goto out;
err:
iot_printf("%s err, reason %lu\n", __FUNCTION__, reason);
out:
return;
}
static uint32_t iot_bsrm_get_info_entry_size(void)
{
return sizeof(iot_bsrm_rec_head_t) +
sizeof(iot_bsrm_branch_info_entry_t);
}
static uint32_t iot_bsrm_get_evt_entry_size(void)
{
return sizeof(iot_bsrm_rec_head_t) +
sizeof(iot_bsrm_branch_evt_rec_entry_t);
}
static uint8_t iot_bsrm_rec_head_valid(iot_bsrm_rec_head_t *hdr)
{
if (hdr->rec_seq == 0) {
return 0;
}
return 1;
}
void iot_bsrm_rec_load(iot_bsrm_rec_region_desc_t *rec_desc, uint8_t
is_order)
{
uint8_t ret, *data;
uint32_t last_rec_seq = 0, oldest_rec_seq = 0xffffffff;
uint32_t part_cnt[2] = { 0 };
uint32_t ts = 0;
uint32_t i, n_per, remain_n, read_n, pos, idx, temp_idx, n, old_idx;
uint32_t find_rec_n = 0, valid_rec_n = 0;
uint8_t *buf = g_buf;
uint16_t crc;
iot_time_tm_t tm;
iot_bsrm_rec_head_t *hdr;
n_per = IOT_BSRM_REC_READ_BUF_SIZE / rec_desc->entry_size;
remain_n = rec_desc->rec_depth;
for (idx = 0, pos = rec_desc->start; remain_n; ) {
read_n = (remain_n >= n_per ? n_per : remain_n);
pos = rec_desc->start + idx * rec_desc->entry_size;
ret = iot_bsrm_flash_read(pos, buf, read_n * rec_desc->entry_size);
if (ret != ERR_OK) {
break;
}
data = buf;
for (i = 0; i < read_n; i++) {
hdr = (iot_bsrm_rec_head_t *)data;
crc = iot_getcrc16(hdr->data,
rec_desc->entry_size - sizeof(*hdr), IOT_BSRM_REC_CRC16_TYPE);
/* traverse all valid records */
if (crc == hdr->crc && iot_bsrm_rec_head_valid(hdr)) {
iot_bsrm_time_to_rtctime(hdr->ts, &tm);
#if IOT_BSRM_REC_DEBUG
iot_bsrm_printf("rec_info: time %lu-%lu-%lu %lu:%lu:%lu, "
"idx %lu, rec_seq %lu\n", tm.tm_year, tm.tm_mon,
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
idx, hdr->rec_seq);
iot_bsrm_data_print("|--rec_bin", data, rec_desc->entry_size);
#endif
if (hdr->rec_seq > last_rec_seq) {
last_rec_seq = hdr->rec_seq;
rec_desc->new_idx = idx;
rec_desc->last_rec_ts = hdr->ts;
}
if (hdr->rec_seq < oldest_rec_seq) {
oldest_rec_seq = hdr->rec_seq;
rec_desc->oldest_idx = idx;
}
find_rec_n++;
}
data += rec_desc->entry_size;
idx++;
}
pos += read_n * rec_desc->entry_size;
remain_n -= read_n;
}
if (!find_rec_n) {
rec_desc->oldest_idx = 0;
rec_desc->new_idx = 0;
goto out;
}
rec_desc->new_idx = iot_bsrm_rec_idx_inc(rec_desc, \
rec_desc->new_idx);
if (rec_desc->new_idx == rec_desc->oldest_idx) {
rec_desc->oldest_idx = iot_bsrm_rec_idx_inc(rec_desc, \
rec_desc->oldest_idx);
}
out:
valid_rec_n = iot_bsrm_rec_get_cnt(rec_desc);
if (valid_rec_n <= 1 || is_order == 0) {
goto done;
}
ts = rec_desc->last_rec_ts;
idx = iot_bsrm_rec_idx_dec(rec_desc, rec_desc->new_idx);
if (idx < rec_desc->oldest_idx) {
part_cnt[0] = idx;
part_cnt[1] = rec_desc->rec_depth - rec_desc->oldest_idx;
} else {
part_cnt[0] = idx - rec_desc->oldest_idx;
}
temp_idx = idx;
old_idx = idx;
#if IOT_BSRM_REC_DEBUG
uint8_t part = 0;
if (part_cnt[1]) {
iot_bsrm_printf("part%lu: [%lu ~ %lu], cnt %lu || ", part,
rec_desc->oldest_idx, rec_desc->rec_depth - 1, part_cnt[1]);
part++;
}
if (part_cnt[0]) {
iot_bsrm_printf("part%lu: [%lu ~ %lu], cnt %lu", part,
rec_desc->oldest_idx, idx, part_cnt[0]);
part++;
}
if (part) {
iot_bsrm_printf("\n");
}
#endif
for (i = 0; i < 2; i++) {
while (part_cnt[i]) {
read_n = (part_cnt[i] >= n_per ? n_per : part_cnt[i]);
idx = iot_bsrm_rec_idx_sub(rec_desc, idx, read_n);
pos = rec_desc->start + idx * rec_desc->entry_size;
ret = iot_bsrm_flash_read(pos, buf, read_n * rec_desc->entry_size);
if (ret) {
goto done_1;
}
n = read_n;
for (data = buf + (read_n - 1) * rec_desc->entry_size; n > 0; n--) {
hdr = (iot_bsrm_rec_head_t *)data;
crc = iot_getcrc16(hdr->data,
rec_desc->entry_size - sizeof(*hdr),
IOT_BSRM_REC_CRC16_TYPE);
if (crc != hdr->crc) {
temp_idx = iot_bsrm_rec_idx_dec(rec_desc, temp_idx);
continue;
} else if (hdr->ts > ts) {
goto done_1;
}
temp_idx = iot_bsrm_rec_idx_dec(rec_desc, temp_idx);
old_idx = temp_idx;
ts = hdr->ts;
data -= rec_desc->entry_size;
}
part_cnt[i] -= read_n;
}
}
done_1:
rec_desc->oldest_idx = old_idx;
done:
rec_desc->seq = iot_bsrm_rec_seq_inc(last_rec_seq);
valid_rec_n = iot_bsrm_rec_get_cnt(rec_desc);
iot_bsrm_time_to_rtctime(rec_desc->last_rec_ts, &tm);
iot_bsrm_printf("%s - region[%08x-%08x], find_rec_n %lu, valid_rec_n "
"%lu, idx[%lu - %lu], seq %lu, last_time %lu-%lu-%lu %lu:%lu:%lu\n",
__FUNCTION__, rec_desc->start, rec_desc->start + rec_desc->size - 1,
find_rec_n, valid_rec_n, rec_desc->oldest_idx, rec_desc->new_idx,
rec_desc->seq, tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
tm.tm_min, tm.tm_sec);
return;
}
uint32_t iot_bsrm_rec_init(void)
{
uint32_t ret = ERR_OK;
uint32_t start;
g_buf = os_mem_malloc(IOT_BSRM_MID, IOT_BSRM_REC_READ_BUF_SIZE);
if (g_buf == NULL) {
ret = ERR_NOMEM;
goto out;
}
start = IOT_BSRM_INFO_REC_REGION_START;
g_info_region.start = start;
g_info_region.entry_size = iot_bsrm_get_info_entry_size();
g_info_region.size = g_info_region.entry_size *
IOT_BSRM_REC_INFO_BRANCH_MAX;
g_info_region.rec_depth = IOT_BSRM_REC_INFO_BRANCH_MAX;
start += g_info_region.size;
iot_bsrm_printf("%s - rec_region_information: [%08x - %08x], block %lu,"
" entry_size %lu\n", __FUNCTION__,
g_info_region.start, start - 1,
g_info_region.rec_depth,
g_info_region.entry_size);
iot_bsrm_rec_load(&g_info_region, 1);
if (start % 4096 != 0) {
start = (start / 4096 + 1) * 4096;
}
IOT_ASSERT(start <= IOT_BSRM_INFO_REC_REGION_END);
start = IOT_BSRM_BRANCH_EVT_REGION_START;
g_evt_region.start = start;
g_evt_region.entry_size = iot_bsrm_get_evt_entry_size();
g_evt_region.size = g_evt_region.entry_size * IOT_BSRM_BRANCH_EVT_MAX;
g_evt_region.rec_depth = IOT_BSRM_BRANCH_EVT_MAX;
start += g_evt_region.size;
iot_bsrm_printf("%s - event_region_information: [%08x - %08x], block %lu,"
" entry_size %lu\n", __FUNCTION__,
g_evt_region.start, start - 1,
g_evt_region.rec_depth,
g_evt_region.entry_size);
iot_bsrm_rec_load(&g_evt_region, 0);
if (start % 4096 != 0) {
start = (start / 4096 + 1) * 4096;
}
IOT_ASSERT(start <= IOT_BSRM_BRANCH_EVT_REGION_END);
out:
return ret;
}
#endif /* IOT_BSRM_MODE */