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