mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-22 02:45:56 +08:00
更新硬件SDK
This commit is contained in:
76
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal.c
vendored
Normal file
76
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal.c
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* File : fal.c
|
||||
* This file is part of FAL (Flash Abstraction Layer) package
|
||||
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-05-17 armink the first version
|
||||
*/
|
||||
|
||||
#include <fal.h>
|
||||
|
||||
static uint8_t init_ok = 0;
|
||||
|
||||
/**
|
||||
* FAL (Flash Abstraction Layer) initialization.
|
||||
* It will initialize all flash device and all flash partition.
|
||||
*
|
||||
* @return >= 0: partitions total number
|
||||
*/
|
||||
int fal_init(void)
|
||||
{
|
||||
extern int fal_flash_init(void);
|
||||
extern int fal_partition_init(void);
|
||||
|
||||
int result;
|
||||
|
||||
/* initialize all flash device on FAL flash table */
|
||||
result = fal_flash_init();
|
||||
|
||||
if (result < 0) {
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* initialize all flash partition on FAL partition table */
|
||||
result = fal_partition_init();
|
||||
|
||||
__exit:
|
||||
|
||||
if ((result > 0) && (!init_ok))
|
||||
{
|
||||
init_ok = 1;
|
||||
log_i("Flash Abstraction Layer (V%s) initialize success.", FAL_SW_VERSION);
|
||||
}
|
||||
else if(result <= 0)
|
||||
{
|
||||
init_ok = 0;
|
||||
log_e("Flash Abstraction Layer (V%s) initialize failed.", FAL_SW_VERSION);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the FAL is initialized successfully
|
||||
*
|
||||
* @return 0: not init or init failed; 1: init success
|
||||
*/
|
||||
int fal_init_check(void)
|
||||
{
|
||||
return init_ok;
|
||||
}
|
||||
136
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal_ec618.c
vendored
Normal file
136
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal_ec618.c
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
#include "common_api.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "lfs_port.h"
|
||||
#include "rng.h"
|
||||
#include "lfs_util.h"
|
||||
#include "flash_rt.h"
|
||||
|
||||
#include "mem_map.h"
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#include "osasys.h"
|
||||
#include "plat_config.h"
|
||||
|
||||
#include "fal.h"
|
||||
|
||||
#define BLOCK_SIZE (4096)
|
||||
#define TOTOL_SIZE (64*1024)
|
||||
|
||||
#define MEM_MODE 0
|
||||
|
||||
#if MEM_MODE
|
||||
static uint8_t vbuff[TOTOL_SIZE];
|
||||
static int (onchip_flash_init)(void) {
|
||||
memset(vbuff, 0, TOTOL_SIZE);
|
||||
return 0;
|
||||
}
|
||||
static int (onchip_flash_read)(long offset, uint8_t *buf, size_t size) {
|
||||
if (size == 0)
|
||||
return 0;
|
||||
memcpy(buf, vbuff + offset, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static int (onchip_flash_write)(long offset, const uint8_t *buf, size_t size) {
|
||||
if (size == 0)
|
||||
return 0;
|
||||
memcpy(vbuff + offset, buf, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static int (onchip_flash_erase)(long offset, size_t size) {
|
||||
memset(vbuff + offset, 0, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // MEM_MODE == 0
|
||||
|
||||
// static void mem_diff(const char* tag) {
|
||||
// int ret = 0;
|
||||
// uint8_t *tmp = malloc(BLOCK_SIZE);
|
||||
// for (size_t offset = 0; offset < TOTOL_SIZE; offset+=BLOCK_SIZE)
|
||||
// {
|
||||
// ret = BSP_QSPI_Read_Safe((uint8_t *)tmp, (FLASH_FDB_REGION_START + offset), BLOCK_SIZE);
|
||||
// if (ret != 0) {
|
||||
// DBG("%s BSP_QSPI_Read_Safe ret %d %04X", tag, ret, offset);
|
||||
// break;
|
||||
// }
|
||||
// if (memcmp(tmp, vbuff + offset, BLOCK_SIZE)) {
|
||||
// DBG("%s Data NOT Match %04X", tag, offset);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// free(tmp);
|
||||
// }
|
||||
|
||||
// extern uint8_t* QSPI_FLASH_ReadUUID(void);
|
||||
|
||||
static int (onchip_flash_init)(void) {
|
||||
return 0;
|
||||
}
|
||||
static int (onchip_flash_read)(long offset, uint8_t *buf, size_t size) {
|
||||
int ret = 0;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
ret = BSP_QSPI_Read_Safe((uint8_t *)buf, (FLASH_FDB_REGION_START + offset), size);
|
||||
return ret == 0 ? size : -1; // 特别注意, 成功的时候, 要读取到的大小!!!
|
||||
}
|
||||
|
||||
static int (onchip_flash_write)(long offset, const uint8_t *buf, size_t size) {
|
||||
int ret = 0;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
// 注意, BSP_QSPI_Write_Safe 的buf不能是flash上的常量数据
|
||||
// 写入flash时XIP会关闭, 导致buf值肯定读不到
|
||||
// 下面的各种判断, 就是把常量数据拷贝到ram, 然后写入
|
||||
uint8_t tmp_small[128];
|
||||
uint8_t *tmp = NULL;
|
||||
uint32_t addr = (uint32_t)buf;
|
||||
if (size <= 128) {
|
||||
// 对于较小的数据, 直接在栈内存里拷贝即可,不必判断
|
||||
memcpy(tmp_small, buf, size);
|
||||
ret = BSP_QSPI_Write_Safe((uint8_t *)tmp_small, (FLASH_FDB_REGION_START + offset), size);
|
||||
}
|
||||
else if (addr >= 0x00400000 && addr <= 0x00500000) {
|
||||
// 数据已经处于ram, 可以直接写入
|
||||
ret = BSP_QSPI_Write_Safe((uint8_t *)buf, (FLASH_FDB_REGION_START + offset), size);
|
||||
}
|
||||
else {
|
||||
// 超过128字节的常量数据, 应该是不存在的吧, 下面的逻辑主要是防御代码.
|
||||
tmp = malloc(size);
|
||||
if (tmp == NULL) {
|
||||
DBG("out of memory when malloc flash write buff");
|
||||
return -1;
|
||||
}
|
||||
memcpy(tmp, buf, size);
|
||||
ret = BSP_QSPI_Write_Safe((uint8_t *)tmp, (FLASH_FDB_REGION_START + offset), size);
|
||||
free(tmp);
|
||||
}
|
||||
return ret == 0 ? size : -1; // 特别注意, 成功的时候, 要写入的大小!!!
|
||||
}
|
||||
|
||||
static int (onchip_flash_erase)(long offset, size_t size) {
|
||||
int ret = 0;
|
||||
ret = BSP_QSPI_Erase_Safe((FLASH_FDB_REGION_START + offset), size);
|
||||
return ret == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif // end of MEM_MODE
|
||||
|
||||
const struct fal_flash_dev onchip_flash = {
|
||||
.name = "onchip_flash",
|
||||
.len = TOTOL_SIZE,
|
||||
.blk_size = BLOCK_SIZE,
|
||||
.addr = 0,
|
||||
.write_gran = 32,
|
||||
.ops = {
|
||||
.init = onchip_flash_init,
|
||||
.read = onchip_flash_read,
|
||||
.write = onchip_flash_write,
|
||||
.erase = onchip_flash_erase
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
99
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal_flash_.c
vendored
Normal file
99
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal_flash_.c
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* File : fal_flash.c
|
||||
* This file is part of FAL (Flash Abstraction Layer) package
|
||||
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-05-17 armink the first version
|
||||
*/
|
||||
|
||||
#include <fal.h>
|
||||
#include <string.h>
|
||||
|
||||
/* flash device table, must defined by user */
|
||||
#if !defined(FAL_FLASH_DEV_TABLE)
|
||||
#error "You must defined flash device table (FAL_FLASH_DEV_TABLE) on 'fal_cfg.h'"
|
||||
#endif
|
||||
|
||||
static const struct fal_flash_dev * const device_table[] = FAL_FLASH_DEV_TABLE;
|
||||
static const size_t device_table_len = sizeof(device_table) / sizeof(device_table[0]);
|
||||
static uint8_t init_ok = 0;
|
||||
|
||||
/**
|
||||
* Initialize all flash device on FAL flash table
|
||||
*
|
||||
* @return result
|
||||
*/
|
||||
int fal_flash_init(void)
|
||||
{
|
||||
size_t i;
|
||||
#if FAL_DEBUG
|
||||
const struct fal_flash_dev *dev;
|
||||
#endif
|
||||
|
||||
if (init_ok)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < device_table_len; i++)
|
||||
{
|
||||
assert(device_table[i]->ops.read);
|
||||
assert(device_table[i]->ops.write);
|
||||
assert(device_table[i]->ops.erase);
|
||||
/* init flash device on flash table */
|
||||
if (device_table[i]->ops.init)
|
||||
{
|
||||
device_table[i]->ops.init();
|
||||
}
|
||||
#if FAL_DEBUG
|
||||
dev = device_table[i];
|
||||
log_d("Flash device | %*.*s | addr: 0x%08lx | len: 0x%08x | blk_size: 0x%08x |initialized finish.",
|
||||
FAL_DEV_NAME_MAX, FAL_DEV_NAME_MAX, dev->name, dev->addr, dev->len,
|
||||
dev->blk_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
init_ok = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* find flash device by name
|
||||
*
|
||||
* @param name flash device name
|
||||
*
|
||||
* @return != NULL: flash device
|
||||
* NULL: not found
|
||||
*/
|
||||
const struct fal_flash_dev *fal_flash_device_find(const char *name)
|
||||
{
|
||||
assert(init_ok);
|
||||
assert(name);
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < device_table_len; i++)
|
||||
{
|
||||
if (!strncmp(name, device_table[i]->name, FAL_DEV_NAME_MAX)) {
|
||||
return device_table[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
497
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal_partition.c
vendored
Normal file
497
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/fal/src/fal_partition.c
vendored
Normal file
@@ -0,0 +1,497 @@
|
||||
/*
|
||||
* File : fal_partition.c
|
||||
* This file is part of FAL (Flash Abstraction Layer) package
|
||||
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-05-17 armink the first version
|
||||
*/
|
||||
|
||||
#include <fal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* partition magic word */
|
||||
#define FAL_PART_MAGIC_WORD 0x45503130
|
||||
#define FAL_PART_MAGIC_WORD_H 0x4550L
|
||||
#define FAL_PART_MAGIC_WORD_L 0x3130L
|
||||
#define FAL_PART_MAGIC_WROD 0x45503130
|
||||
|
||||
/**
|
||||
* FAL partition table config has defined on 'fal_cfg.h'.
|
||||
* When this option is disable, it will auto find the partition table on a specified location in flash partition.
|
||||
*/
|
||||
#ifdef FAL_PART_HAS_TABLE_CFG
|
||||
|
||||
/* check partition table definition */
|
||||
#if !defined(FAL_PART_TABLE)
|
||||
#error "You must defined FAL_PART_TABLE on 'fal_cfg.h'"
|
||||
#endif
|
||||
|
||||
#ifdef __CC_ARM /* ARM Compiler */
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#define USED __attribute__((used))
|
||||
#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */
|
||||
#define SECTION(x) @ x
|
||||
#define USED __root
|
||||
#elif defined (__GNUC__) /* GNU GCC Compiler */
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#define USED __attribute__((used))
|
||||
#else
|
||||
#error not supported tool chain
|
||||
#endif /* __CC_ARM */
|
||||
//USED static const struct fal_partition partition_table_def[] SECTION("FalPartTable") = FAL_PART_TABLE;
|
||||
static const struct fal_partition partition_table_def[] = FAL_PART_TABLE;
|
||||
static const struct fal_partition *partition_table = NULL;
|
||||
|
||||
#else /* FAL_PART_HAS_TABLE_CFG */
|
||||
|
||||
#if !defined(FAL_PART_TABLE_FLASH_DEV_NAME)
|
||||
#error "You must defined FAL_PART_TABLE_FLASH_DEV_NAME on 'fal_cfg.h'"
|
||||
#endif
|
||||
|
||||
/* check partition table end offset address definition */
|
||||
#if !defined(FAL_PART_TABLE_END_OFFSET)
|
||||
#error "You must defined FAL_PART_TABLE_END_OFFSET on 'fal_cfg.h'"
|
||||
#endif
|
||||
|
||||
static struct fal_partition *partition_table = NULL;
|
||||
#endif /* FAL_PART_HAS_TABLE_CFG */
|
||||
|
||||
static uint8_t init_ok = 0;
|
||||
static size_t partition_table_len = 0;
|
||||
|
||||
/**
|
||||
* print the partition table
|
||||
*/
|
||||
void fal_show_part_table(void)
|
||||
{
|
||||
char *item1 = "name", *item2 = "flash_dev";
|
||||
size_t i, part_name_max = strlen(item1), flash_dev_name_max = strlen(item2);
|
||||
const struct fal_partition *part;
|
||||
|
||||
if (partition_table_len)
|
||||
{
|
||||
for (i = 0; i < partition_table_len; i++)
|
||||
{
|
||||
part = &partition_table[i];
|
||||
if (strlen(part->name) > part_name_max)
|
||||
{
|
||||
part_name_max = strlen(part->name);
|
||||
}
|
||||
if (strlen(part->flash_name) > flash_dev_name_max)
|
||||
{
|
||||
flash_dev_name_max = strlen(part->flash_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
log_i("==================== FAL partition table ====================");
|
||||
log_i("| %-*.*s | %-*.*s | offset | length |", part_name_max, FAL_DEV_NAME_MAX, item1, flash_dev_name_max,
|
||||
FAL_DEV_NAME_MAX, item2);
|
||||
log_i("-------------------------------------------------------------");
|
||||
for (i = 0; i < partition_table_len; i++)
|
||||
{
|
||||
|
||||
#ifdef FAL_PART_HAS_TABLE_CFG
|
||||
part = &partition_table[i];
|
||||
#else
|
||||
part = &partition_table[partition_table_len - i - 1];
|
||||
#endif
|
||||
|
||||
log_i("| %-*.*s | %-*.*s | 0x%08lx | 0x%08x |", part_name_max, FAL_DEV_NAME_MAX, part->name, flash_dev_name_max,
|
||||
FAL_DEV_NAME_MAX, part->flash_name, part->offset, part->len);
|
||||
}
|
||||
log_i("=============================================================");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all flash partition on FAL partition table
|
||||
*
|
||||
* @return partitions total number
|
||||
*/
|
||||
int fal_partition_init(void)
|
||||
{
|
||||
size_t i;
|
||||
const struct fal_flash_dev *flash_dev = NULL;
|
||||
|
||||
if (init_ok)
|
||||
{
|
||||
return partition_table_len;
|
||||
}
|
||||
|
||||
#ifdef FAL_PART_HAS_TABLE_CFG
|
||||
partition_table = &partition_table_def[0];
|
||||
partition_table_len = sizeof(partition_table_def) / sizeof(partition_table_def[0]);
|
||||
#else
|
||||
/* load partition table from the end address FAL_PART_TABLE_END_OFFSET, error return 0 */
|
||||
long part_table_offset = FAL_PART_TABLE_END_OFFSET;
|
||||
size_t table_num = 0, table_item_size = 0;
|
||||
uint8_t part_table_find_ok = 0;
|
||||
uint32_t read_magic_word;
|
||||
fal_partition_t new_part = NULL;
|
||||
|
||||
flash_dev = fal_flash_device_find(FAL_PART_TABLE_FLASH_DEV_NAME);
|
||||
if (flash_dev == NULL)
|
||||
{
|
||||
log_e("Initialize failed! Flash device (%s) NOT found.", FAL_PART_TABLE_FLASH_DEV_NAME);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* check partition table offset address */
|
||||
if (part_table_offset < 0 || part_table_offset >= (long) flash_dev->len)
|
||||
{
|
||||
log_e("Setting partition table end offset address(%ld) out of flash bound(<%d).", part_table_offset, flash_dev->len);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
table_item_size = sizeof(struct fal_partition);
|
||||
new_part = (fal_partition_t)FAL_MALLOC(table_item_size);
|
||||
if (new_part == NULL)
|
||||
{
|
||||
log_e("Initialize failed! No memory for table buffer.");
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* find partition table location */
|
||||
{
|
||||
uint8_t read_buf[64];
|
||||
|
||||
part_table_offset -= sizeof(read_buf);
|
||||
while (part_table_offset >= 0)
|
||||
{
|
||||
if (flash_dev->ops.read(part_table_offset, read_buf, sizeof(read_buf)) > 0)
|
||||
{
|
||||
/* find magic word in read buf */
|
||||
for (i = 0; i < sizeof(read_buf) - sizeof(read_magic_word) + 1; i++)
|
||||
{
|
||||
read_magic_word = read_buf[0 + i] + (read_buf[1 + i] << 8) + (read_buf[2 + i] << 16) + (read_buf[3 + i] << 24);
|
||||
if (read_magic_word == ((FAL_PART_MAGIC_WORD_H << 16) + FAL_PART_MAGIC_WORD_L))
|
||||
{
|
||||
part_table_find_ok = 1;
|
||||
part_table_offset += i;
|
||||
log_d("Find the partition table on '%s' offset @0x%08lx.", FAL_PART_TABLE_FLASH_DEV_NAME,
|
||||
part_table_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read failed */
|
||||
break;
|
||||
}
|
||||
|
||||
if (part_table_find_ok)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* calculate next read buf position */
|
||||
if (part_table_offset >= (long)sizeof(read_buf))
|
||||
{
|
||||
part_table_offset -= sizeof(read_buf);
|
||||
part_table_offset += (sizeof(read_magic_word) - 1);
|
||||
}
|
||||
else if (part_table_offset != 0)
|
||||
{
|
||||
part_table_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* find failed */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* load partition table */
|
||||
while (part_table_find_ok)
|
||||
{
|
||||
memset(new_part, 0x00, table_num);
|
||||
if (flash_dev->ops.read(part_table_offset - table_item_size * (table_num), (uint8_t *) new_part,
|
||||
table_item_size) < 0)
|
||||
{
|
||||
log_e("Initialize failed! Flash device (%s) read error!", flash_dev->name);
|
||||
table_num = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (new_part->magic_word != ((FAL_PART_MAGIC_WORD_H << 16) + FAL_PART_MAGIC_WORD_L))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
partition_table = (fal_partition_t) FAL_REALLOC(partition_table, table_item_size * (table_num + 1));
|
||||
if (partition_table == NULL)
|
||||
{
|
||||
log_e("Initialize failed! No memory for partition table");
|
||||
table_num = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(partition_table + table_num, new_part, table_item_size);
|
||||
|
||||
table_num++;
|
||||
};
|
||||
|
||||
if (table_num == 0)
|
||||
{
|
||||
log_e("Partition table NOT found on flash: %s (len: %d) from offset: 0x%08x.", FAL_PART_TABLE_FLASH_DEV_NAME,
|
||||
FAL_DEV_NAME_MAX, FAL_PART_TABLE_END_OFFSET);
|
||||
goto _exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
partition_table_len = table_num;
|
||||
}
|
||||
#endif /* FAL_PART_HAS_TABLE_CFG */
|
||||
|
||||
/* check the partition table device exists */
|
||||
|
||||
for (i = 0; i < partition_table_len; i++)
|
||||
{
|
||||
flash_dev = fal_flash_device_find(partition_table[i].flash_name);
|
||||
if (flash_dev == NULL)
|
||||
{
|
||||
log_d("Warning: Do NOT found the flash device(%s).", partition_table[i].flash_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (partition_table[i].offset >= (long)flash_dev->len)
|
||||
{
|
||||
log_e("Initialize failed! Partition(%s) offset address(%ld) out of flash bound(<%d).",
|
||||
partition_table[i].name, partition_table[i].offset, flash_dev->len);
|
||||
partition_table_len = 0;
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
|
||||
init_ok = 1;
|
||||
|
||||
_exit:
|
||||
|
||||
#if FAL_DEBUG
|
||||
fal_show_part_table();
|
||||
#endif
|
||||
|
||||
#ifndef FAL_PART_HAS_TABLE_CFG
|
||||
if (new_part)
|
||||
{
|
||||
FAL_FREE(new_part);
|
||||
}
|
||||
#endif /* !FAL_PART_HAS_TABLE_CFG */
|
||||
|
||||
return partition_table_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* find the partition by name
|
||||
*
|
||||
* @param name partition name
|
||||
*
|
||||
* @return != NULL: partition
|
||||
* NULL: not found
|
||||
*/
|
||||
const struct fal_partition *fal_partition_find(const char *name)
|
||||
{
|
||||
assert(init_ok);
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < partition_table_len; i++)
|
||||
{
|
||||
if (!strcmp(name, partition_table[i].name))
|
||||
{
|
||||
return &partition_table[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the partition table
|
||||
*
|
||||
* @param len return the partition table length
|
||||
*
|
||||
* @return partition table
|
||||
*/
|
||||
const struct fal_partition *fal_get_partition_table(size_t *len)
|
||||
{
|
||||
assert(init_ok);
|
||||
assert(len);
|
||||
|
||||
*len = partition_table_len;
|
||||
|
||||
return partition_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* set partition table temporarily
|
||||
* This setting will modify the partition table temporarily, the setting will be lost after restart.
|
||||
*
|
||||
* @param table partition table
|
||||
* @param len partition table length
|
||||
*/
|
||||
void fal_set_partition_table_temp(struct fal_partition *table, size_t len)
|
||||
{
|
||||
assert(init_ok);
|
||||
assert(table);
|
||||
|
||||
partition_table_len = len;
|
||||
partition_table = table;
|
||||
}
|
||||
|
||||
/**
|
||||
* read data from partition
|
||||
*
|
||||
* @param part partition
|
||||
* @param addr relative address for partition
|
||||
* @param buf read buffer
|
||||
* @param size read size
|
||||
*
|
||||
* @return >= 0: successful read data size
|
||||
* -1: error
|
||||
*/
|
||||
int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct fal_flash_dev *flash_dev = NULL;
|
||||
|
||||
assert(part);
|
||||
assert(buf);
|
||||
|
||||
if (addr + size > part->len)
|
||||
{
|
||||
log_e("Partition read error! Partition address out of bound.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
flash_dev = fal_flash_device_find(part->flash_name);
|
||||
if (flash_dev == NULL)
|
||||
{
|
||||
log_e("Partition read error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = flash_dev->ops.read(part->offset + addr, buf, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
log_e("Partition read error! Flash device(%s) read error!", part->flash_name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* write data to partition
|
||||
*
|
||||
* @param part partition
|
||||
* @param addr relative address for partition
|
||||
* @param buf write buffer
|
||||
* @param size write size
|
||||
*
|
||||
* @return >= 0: successful write data size
|
||||
* -1: error
|
||||
*/
|
||||
int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct fal_flash_dev *flash_dev = NULL;
|
||||
|
||||
assert(part);
|
||||
assert(buf);
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
if (addr + size > part->len)
|
||||
{
|
||||
log_e("Partition write error! Partition address out of bound. %08X %04X", addr, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
flash_dev = fal_flash_device_find(part->flash_name);
|
||||
if (flash_dev == NULL)
|
||||
{
|
||||
log_e("Partition write error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = flash_dev->ops.write(part->offset + addr, buf, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
log_e("Partition write error! Flash device(%s) write error! %08X %04X ret %d", part->flash_name, addr, size, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* erase partition data
|
||||
*
|
||||
* @param part partition
|
||||
* @param addr relative address for partition
|
||||
* @param size erase size
|
||||
*
|
||||
* @return >= 0: successful erased data size
|
||||
* -1: error
|
||||
*/
|
||||
int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct fal_flash_dev *flash_dev = NULL;
|
||||
|
||||
assert(part);
|
||||
|
||||
if (addr + size > part->len)
|
||||
{
|
||||
log_e("Partition erase error! Partition address out of bound.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
flash_dev = fal_flash_device_find(part->flash_name);
|
||||
if (flash_dev == NULL)
|
||||
{
|
||||
log_e("Partition erase error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = flash_dev->ops.erase(part->offset + addr, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
log_e("Partition erase error! Flash device(%s) erase error!", part->flash_name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* erase partition all data
|
||||
*
|
||||
* @param part partition
|
||||
*
|
||||
* @return >= 0: successful erased data size
|
||||
* -1: error
|
||||
*/
|
||||
int fal_partition_erase_all(const struct fal_partition *part)
|
||||
{
|
||||
return fal_partition_erase(part, 0, part->len);
|
||||
}
|
||||
Reference in New Issue
Block a user