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;
|
|
}
|