Files
kunlun/app/smart_grid/common/flash/iot_sg_flash.c
2024-09-28 14:24:04 +08:00

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