320 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			320 lines
		
	
	
		
			8.9 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.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
/* os shim includes */
 | 
						|
#include "os_types_api.h"
 | 
						|
#include "os_lock_api.h"
 | 
						|
 | 
						|
/* iot common header files */
 | 
						|
#include "iot_sg.h"
 | 
						|
#include "iot_sg_fr.h"
 | 
						|
#include "iot_errno_api.h"
 | 
						|
#include "iot_flash_api.h"
 | 
						|
#include "iot_ext_flash_api.h"
 | 
						|
#include "iot_oem_api.h"
 | 
						|
 | 
						|
os_mutex_h sg_flash_op_mutex = NULL;
 | 
						|
 | 
						|
typedef int32_t(*custom_dev_query_rw_size_t)();
 | 
						|
typedef int32_t(*custom_dev_open_t)();
 | 
						|
typedef int32_t(*custom_dev_seek_t)(int32_t fd, uint32_t offset,
 | 
						|
    uint8_t fromwhere);
 | 
						|
typedef int32_t(*custom_dev_close_t)(int32_t fd);
 | 
						|
typedef int32_t(*custom_dev_write_t)(int32_t fd, void*buf, size_t count);
 | 
						|
typedef int32_t(*custom_dev_read_t)(int32_t fd, void* buf, size_t count);
 | 
						|
typedef int32_t(*custom_dev_erase_t)(int32_t fd, uint32_t offset,
 | 
						|
    size_t count);
 | 
						|
typedef int32_t(*custom_dev_query_erase_once_size_t)(int32_t fd);
 | 
						|
 | 
						|
/* function of handle flash  */
 | 
						|
typedef struct _iot_sg_flash_dev_handle_t {
 | 
						|
    custom_dev_open_t dev_open_func;
 | 
						|
    custom_dev_close_t dev_close_func;
 | 
						|
    custom_dev_query_rw_size_t query_size_func;
 | 
						|
    custom_dev_seek_t dev_seek_func;
 | 
						|
    custom_dev_write_t dev_write_func;
 | 
						|
    custom_dev_read_t dev_read_func;
 | 
						|
    custom_dev_erase_t dev_erase_func;
 | 
						|
    custom_dev_query_erase_once_size_t query_erase_once_size_func;
 | 
						|
    custom_dev_write_t dev_write_func_without_erase;
 | 
						|
} iot_sg_flash_dev_handle_t;
 | 
						|
 | 
						|
const iot_sg_flash_dev_handle_t *custom_dev_hdl = NULL;
 | 
						|
 | 
						|
/* define type of flash. internal flash */
 | 
						|
#define IOT_FLASH_TYPE_INTERNAL              (0)
 | 
						|
/* define type of flash. external flash */
 | 
						|
#define IOT_FLASH_TYPE_EXTERNAL              (1)
 | 
						|
/* define type of flash max */
 | 
						|
#define IOT_FLASH_TYPE_MAX                   (2)
 | 
						|
 | 
						|
static int32_t iot_sg_custom_ext_dev_open()
 | 
						|
{
 | 
						|
    return custom_ext_dev_open(EXT_FLASH_DEV0);
 | 
						|
}
 | 
						|
 | 
						|
static int32_t iot_sg_custom_ext_dev_query_rw_size()
 | 
						|
{
 | 
						|
    int fd;
 | 
						|
    if (-1 == (fd = custom_ext_dev_open(EXT_FLASH_DEV0)))
 | 
						|
    {
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    int32_t rw_size = custom_ext_dev_query_rw_size(fd);
 | 
						|
    if (rw_size < 0) {
 | 
						|
        rw_size = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    custom_ext_dev_close(fd);
 | 
						|
 | 
						|
    return rw_size;
 | 
						|
}
 | 
						|
 | 
						|
static const iot_sg_flash_dev_handle_t flash_hdl_func_table[ \
 | 
						|
    IOT_FLASH_TYPE_MAX] = {
 | 
						|
    {
 | 
						|
        .dev_open_func = custom_dev_open,
 | 
						|
        .dev_close_func = custom_dev_close,
 | 
						|
        .query_size_func = custom_dev_query_rw_size,
 | 
						|
        .dev_seek_func = custom_dev_seek,
 | 
						|
        .dev_write_func = custom_dev_write,
 | 
						|
        .dev_read_func = custom_dev_read,
 | 
						|
        .dev_erase_func = custom_dev_erase,
 | 
						|
        .query_erase_once_size_func = custom_dev_get_size_of_erase_once,
 | 
						|
        .dev_write_func_without_erase = custom_dev_write_without_erase,
 | 
						|
    },
 | 
						|
    {
 | 
						|
        .dev_open_func = iot_sg_custom_ext_dev_open,
 | 
						|
        .query_size_func = iot_sg_custom_ext_dev_query_rw_size,
 | 
						|
        .dev_close_func = custom_ext_dev_close,
 | 
						|
        .dev_seek_func = custom_ext_dev_seek,
 | 
						|
        .dev_write_func = custom_ext_dev_write,
 | 
						|
        .dev_read_func = custom_ext_dev_read,
 | 
						|
        .dev_erase_func = custom_ext_dev_erase,
 | 
						|
        .query_erase_once_size_func = custom_ext_dev_get_size_of_erase_once,
 | 
						|
        .dev_write_func_without_erase = custom_ext_dev_write_without_erase,
 | 
						|
    },
 | 
						|
};
 | 
						|
 | 
						|
uint32_t iot_sg_flash_type_is_internal_check(void)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_FAIL;
 | 
						|
 | 
						|
    if (custom_dev_hdl == &flash_hdl_func_table[IOT_FLASH_TYPE_INTERNAL]) {
 | 
						|
        ret = ERR_OK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_sg_custom_func_init()
 | 
						|
{
 | 
						|
    int fd;
 | 
						|
    /* if open ext flash fail, need use internal flash */
 | 
						|
    if (-1 == (fd = custom_ext_dev_open(EXT_FLASH_DEV0))) {
 | 
						|
        custom_dev_hdl = &flash_hdl_func_table[IOT_FLASH_TYPE_INTERNAL];
 | 
						|
    } else {
 | 
						|
        custom_dev_hdl = &flash_hdl_func_table[IOT_FLASH_TYPE_EXTERNAL];
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_flash_init(void)
 | 
						|
{
 | 
						|
    if (sg_flash_op_mutex == NULL) {
 | 
						|
        sg_flash_op_mutex = os_create_mutex(IOT_SMART_GRID_MID);
 | 
						|
    }
 | 
						|
    if (custom_dev_hdl == NULL) {
 | 
						|
        iot_sg_custom_func_init();
 | 
						|
    }
 | 
						|
    return (uint32_t)custom_dev_hdl->query_size_func();
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_flash_size_query(void)
 | 
						|
{
 | 
						|
    return (uint32_t)custom_dev_hdl->query_size_func();
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_flash_erase_once_query(void) {
 | 
						|
    int fd;
 | 
						|
    uint32_t size = 0;
 | 
						|
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_acquire_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
    if (-1 == (fd = custom_dev_hdl->dev_open_func())) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    size = (uint32_t)custom_dev_hdl->query_erase_once_size_func(fd);
 | 
						|
    (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
out:
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_release_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
    return size;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_flash_write(uint32_t write_offset,
 | 
						|
    uint32_t write_len, uint8_t *p_write_buf)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_FAIL;
 | 
						|
    int fd, len = (int)(write_offset + write_len);
 | 
						|
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_acquire_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
 | 
						|
    if ((NULL == p_write_buf) || (len > custom_dev_hdl->query_size_func())) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == (fd = custom_dev_hdl->dev_open_func())) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == custom_dev_hdl->dev_seek_func(fd, write_offset, DEV_SEEK_SET)) {
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == custom_dev_hdl->dev_write_func(fd,
 | 
						|
        (void*)p_write_buf, write_len)) {
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
    ret = ERR_OK;
 | 
						|
out:
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_release_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* Load config from customer flash. */
 | 
						|
uint32_t iot_sg_flash_read(uint32_t read_offset,
 | 
						|
    uint32_t read_len, uint8_t *p_read_buf)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_FAIL;
 | 
						|
    int fd, len = (int)(read_offset + read_len);
 | 
						|
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_acquire_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
 | 
						|
    if ((NULL == p_read_buf) || (len > custom_dev_hdl->query_size_func())) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == (fd = custom_dev_hdl->dev_open_func())) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == custom_dev_hdl->dev_seek_func(fd, read_offset, DEV_SEEK_SET)) {
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == custom_dev_hdl->dev_read_func(fd, (void*)p_read_buf, read_len)) {
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
    ret = ERR_OK;
 | 
						|
out:
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_release_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_flash_erase(uint32_t erase_offset,
 | 
						|
    uint32_t erase_len)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_FAIL;
 | 
						|
    int fd, len = (int)(erase_offset + erase_len);
 | 
						|
 | 
						|
    if (custom_dev_hdl->dev_erase_func == NULL) {
 | 
						|
        ret = ERR_NOSUPP;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_acquire_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
 | 
						|
    if (len > custom_dev_hdl->query_size_func()) {
 | 
						|
        goto release;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == (fd = custom_dev_hdl->dev_open_func())) {
 | 
						|
        goto release;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == custom_dev_hdl->dev_erase_func(fd, erase_offset, erase_len)) {
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
        goto release;
 | 
						|
    }
 | 
						|
 | 
						|
    (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
    ret = ERR_OK;
 | 
						|
release:
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_release_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_flash_write_without_erase(uint32_t write_offset,
 | 
						|
    uint32_t write_len, uint8_t *p_write_buf)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_FAIL;
 | 
						|
    int fd, len = (int)(write_offset + write_len);
 | 
						|
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_acquire_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
 | 
						|
    if ((NULL == p_write_buf) || (len > custom_dev_hdl->query_size_func())) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == (fd = custom_dev_hdl->dev_open_func())) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == custom_dev_hdl->dev_seek_func(fd, write_offset, DEV_SEEK_SET)) {
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (-1 == custom_dev_hdl->dev_write_func_without_erase(fd,
 | 
						|
        (void*)p_write_buf, write_len)) {
 | 
						|
        (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    (void)custom_dev_hdl->dev_close_func(fd);
 | 
						|
    ret = ERR_OK;
 | 
						|
out:
 | 
						|
    if (sg_flash_op_mutex) {
 | 
						|
        os_release_mutex(sg_flash_op_mutex);
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 |