This commit is contained in:
刘可亮
2024-06-04 19:00:30 +08:00
parent 990c72f5be
commit 0a13af6a1d
1668 changed files with 342810 additions and 37726 deletions

View File

@@ -106,6 +106,7 @@ static rt_size_t blk_dev_write(rt_device_t dev, rt_off_t pos, const void* buffer
log_e("This config only supports read!\n");
return size;
#else
#define FATFS_CLUSTER_SIZE AIC_USING_FS_IMAGE_TYPE_FATFS_CLUSTER_SIZE
int ret = 0;
struct fal_blk_device *part;
rt_off_t phy_pos, buf_pos;
@@ -116,16 +117,16 @@ static rt_size_t blk_dev_write(rt_device_t dev, rt_off_t pos, const void* buffer
part = (struct fal_blk_device*) dev;
assert(part != RT_NULL);
align_sector = pos - pos % 8;
align_cnt = pos % 8 + size;
align_cnt = (align_cnt + 7) / 8 * 8;
align_sector = pos - pos % FATFS_CLUSTER_SIZE;
align_cnt = pos % FATFS_CLUSTER_SIZE + size;
align_cnt = (align_cnt + FATFS_CLUSTER_SIZE - 1) / FATFS_CLUSTER_SIZE * FATFS_CLUSTER_SIZE;
log_d("pos = %ld size = %d!\n", pos, size);
log_d("align_sector = %ld align_cnt = %d!\n", align_sector, align_cnt);
phy_pos = align_sector * part->geometry.bytes_per_sector;
phy_size = align_cnt * part->geometry.bytes_per_sector;
buf_pos = pos % 8 * part->geometry.bytes_per_sector;
buf_pos = pos % FATFS_CLUSTER_SIZE * part->geometry.bytes_per_sector;
buf_size = size * part->geometry.bytes_per_sector;
memset(part->buf, 0xFF, part->length);
@@ -588,396 +589,4 @@ struct rt_device *fal_char_device_create(const char *parition_name)
return RT_DEVICE(char_dev);
}
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
#include <finsh.h>
extern int fal_init_check(void);
static void fal(uint8_t argc, char **argv) {
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
#define HEXDUMP_WIDTH 16
#define CMD_PROBE_INDEX 0
#define CMD_READ_INDEX 1
#define CMD_WRITE_INDEX 2
#define CMD_ERASE_INDEX 3
#define CMD_BENCH_INDEX 4
int result = 0;
static const struct fal_flash_dev *flash_dev = NULL;
static const struct fal_partition *part_dev = NULL;
size_t i = 0, j = 0;
const char* help_info[] =
{
[CMD_PROBE_INDEX] = "fal probe [dev_name|part_name] - probe flash device or partition by given name",
[CMD_READ_INDEX] = "fal read addr size - read 'size' bytes starting at 'addr'",
[CMD_WRITE_INDEX] = "fal write addr data1 ... dataN - write some bytes 'data' starting at 'addr'",
[CMD_ERASE_INDEX] = "fal erase addr size - erase 'size' bytes starting at 'addr'",
[CMD_BENCH_INDEX] = "fal bench <blk_size> - benchmark test with per block size",
};
if (fal_init_check() != 1)
{
rt_kprintf("\n[Warning] FAL is not initialized or failed to initialize!\n\n");
return;
}
if (argc < 2)
{
rt_kprintf("Usage:\n");
for (i = 0; i < sizeof(help_info) / sizeof(char*); i++)
{
rt_kprintf("%s\n", help_info[i]);
}
rt_kprintf("\n");
}
else
{
const char *operator = argv[1];
uint32_t addr;
uint32_t size = 0;
if (!strcmp(operator, "probe"))
{
if (argc >= 3)
{
char *dev_name = argv[2];
if ((flash_dev = fal_flash_device_find(dev_name)) != NULL)
{
part_dev = NULL;
}
else if ((part_dev = fal_partition_find(dev_name)) != NULL)
{
flash_dev = NULL;
}
else
{
rt_kprintf("Device %s NOT found. Probe failed.\n", dev_name);
flash_dev = NULL;
part_dev = NULL;
}
}
if (flash_dev)
{
rt_kprintf("Probed a flash device | %s | addr: %ld | len: %d |.\n", flash_dev->name,
flash_dev->addr, flash_dev->len);
}
else if (part_dev)
{
rt_kprintf("Probed a flash partition | %s | flash_dev: %s | offset: %ld | len: %d |.\n",
part_dev->name, part_dev->flash_name, part_dev->offset, part_dev->len);
}
else
{
rt_kprintf("No flash device or partition was probed.\n");
rt_kprintf("Usage: %s.\n", help_info[CMD_PROBE_INDEX]);
fal_show_part_table();
}
}
else
{
if (!flash_dev && !part_dev)
{
rt_kprintf("No flash device or partition was probed. Please run 'fal probe'.\n");
return;
}
if (!rt_strcmp(operator, "read"))
{
if (argc < 4)
{
rt_kprintf("Usage: %s.\n", help_info[CMD_READ_INDEX]);
return;
}
else
{
addr = strtol(argv[2], NULL, 0);
size = strtol(argv[3], NULL, 0);
uint8_t *data = rt_malloc(size);
if (data)
{
if (flash_dev)
{
result = flash_dev->ops.read(addr, data, size);
}
else if (part_dev)
{
result = fal_partition_read(part_dev, addr, data, size);
}
if (result >= 0)
{
rt_kprintf("Read data success. Start from 0x%08X, size is %ld. The data is:\n", addr,
size);
rt_kprintf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
for (i = 0; i < size; i += HEXDUMP_WIDTH)
{
rt_kprintf("[%08X] ", addr + i);
/* dump hex */
for (j = 0; j < HEXDUMP_WIDTH; j++)
{
if (i + j < size)
{
rt_kprintf("%02X ", data[i + j]);
}
else
{
rt_kprintf(" ");
}
}
/* dump char for hex */
for (j = 0; j < HEXDUMP_WIDTH; j++)
{
if (i + j < size)
{
rt_kprintf("%c", __is_print(data[i + j]) ? data[i + j] : '.');
}
}
rt_kprintf("\n");
}
rt_kprintf("\n");
}
rt_free(data);
}
else
{
rt_kprintf("Low memory!\n");
}
}
}
else if (!strcmp(operator, "write"))
{
if (argc < 4)
{
rt_kprintf("Usage: %s.\n", help_info[CMD_WRITE_INDEX]);
return;
}
else
{
addr = strtol(argv[2], NULL, 0);
size = argc - 3;
uint8_t *data = rt_malloc(size);
if (data)
{
for (i = 0; i < size; i++)
{
data[i] = strtol(argv[3 + i], NULL, 0);
}
if (flash_dev)
{
result = flash_dev->ops.write(addr, data, size);
}
else if (part_dev)
{
result = fal_partition_write(part_dev, addr, data, size);
}
if (result >= 0)
{
rt_kprintf("Write data success. Start from 0x%08X, size is %ld.\n", addr, size);
rt_kprintf("Write data: ");
for (i = 0; i < size; i++)
{
rt_kprintf("%d ", data[i]);
}
rt_kprintf(".\n");
}
rt_free(data);
}
else
{
rt_kprintf("Low memory!\n");
}
}
}
else if (!rt_strcmp(operator, "erase"))
{
if (argc < 4)
{
rt_kprintf("Usage: %s.\n", help_info[CMD_ERASE_INDEX]);
return;
}
else
{
addr = strtol(argv[2], NULL, 0);
size = strtol(argv[3], NULL, 0);
if (flash_dev)
{
result = flash_dev->ops.erase(addr, size);
}
else if (part_dev)
{
result = fal_partition_erase(part_dev, addr, size);
}
if (result >= 0)
{
rt_kprintf("Erase data success. Start from 0x%08X, size is %ld.\n", addr, size);
}
}
}
else if (!strcmp(operator, "bench"))
{
if (argc < 3)
{
rt_kprintf("Usage: %s.\n", help_info[CMD_BENCH_INDEX]);
return;
}
else if ((argc > 3 && strcmp(argv[3], "yes")) || argc < 4)
{
rt_kprintf("DANGER: It will erase full chip or partition! Please run 'fal bench %d yes'.\n", strtol(argv[2], NULL, 0));
return;
}
/* full chip benchmark test */
uint32_t start_time, time_cast;
size_t write_size = strtol(argv[2], NULL, 0), read_size = strtol(argv[2], NULL, 0), cur_op_size;
uint8_t *write_data = (uint8_t *)rt_malloc(write_size), *read_data = (uint8_t *)rt_malloc(read_size);
if (write_data && read_data)
{
for (i = 0; i < write_size; i ++) {
write_data[i] = i & 0xFF;
}
if (flash_dev)
{
size = flash_dev->len;
}
else if (part_dev)
{
size = part_dev->len;
}
/* benchmark testing */
rt_kprintf("Erasing %ld bytes data, waiting...\n", size);
start_time = rt_tick_get();
if (flash_dev)
{
result = flash_dev->ops.erase(0, size);
}
else if (part_dev)
{
result = fal_partition_erase(part_dev, 0, size);
}
if (result >= 0)
{
time_cast = rt_tick_get() - start_time;
rt_kprintf("Erase benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
}
else
{
rt_kprintf("Erase benchmark has an error. Error code: %d.\n", result);
}
/* write test */
rt_kprintf("Writing %ld bytes data, waiting...\n", size);
start_time = rt_tick_get();
for (i = 0; i < size; i += write_size)
{
if (i + write_size <= size)
{
cur_op_size = write_size;
}
else
{
cur_op_size = size - i;
}
if (flash_dev)
{
result = flash_dev->ops.write(i, write_data, cur_op_size);
}
else if (part_dev)
{
result = fal_partition_write(part_dev, i, write_data, cur_op_size);
}
if (result < 0)
{
break;
}
}
if (result >= 0)
{
time_cast = rt_tick_get() - start_time;
rt_kprintf("Write benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
}
else
{
rt_kprintf("Write benchmark has an error. Error code: %d.\n", result);
}
/* read test */
rt_kprintf("Reading %ld bytes data, waiting...\n", size);
start_time = rt_tick_get();
for (i = 0; i < size; i += read_size)
{
if (i + read_size <= size)
{
cur_op_size = read_size;
}
else
{
cur_op_size = size - i;
}
if (flash_dev)
{
result = flash_dev->ops.read(i, read_data, cur_op_size);
}
else if (part_dev)
{
result = fal_partition_read(part_dev, i, read_data, cur_op_size);
}
/* data check */
for (size_t index = 0; index < cur_op_size; index ++)
{
if (write_data[index] != read_data[index])
{
rt_kprintf("%d %d %02x %02x.\n", i, index, write_data[index], read_data[index]);
}
}
if (memcmp(write_data, read_data, cur_op_size))
{
result = -RT_ERROR;
rt_kprintf("Data check ERROR! Please check you flash by other command.\n");
}
/* has an error */
if (result < 0)
{
break;
}
}
if (result >= 0)
{
time_cast = rt_tick_get() - start_time;
rt_kprintf("Read benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
}
else
{
rt_kprintf("Read benchmark has an error. Error code: %d.\n", result);
}
}
else
{
rt_kprintf("Low memory!\n");
}
rt_free(write_data);
rt_free(read_data);
}
else
{
rt_kprintf("Usage:\n");
for (i = 0; i < sizeof(help_info) / sizeof(char*); i++)
{
rt_kprintf("%s\n", help_info[i]);
}
rt_kprintf("\n");
return;
}
if (result < 0) {
rt_kprintf("This operate has an error. Error code: %d.\n", result);
}
}
}
}
MSH_CMD_EXPORT(fal, FAL (Flash Abstraction Layer) operate);
#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */
#endif /* RT_VER_NUM */