KT24-1110_65E-HA-651B/apps/common/fat_nor/cfg_private.c
2024-11-10 18:44:17 +08:00

329 lines
10 KiB
C

#include "includes.h"
#include "boot.h"
#include "asm/sfc_norflash_api.h"
#include "cfg_private.h"
/* #include "sdfile.h" */
#define CFG_PRIVATE_FILE_NUM 5
SDFILE_FILE_HEAD head = {0};
static u8 cfg_private_create_flag = 0;
static u32 cfg_private_create_sclust = 0;
static FILE *cfg_private_create(const char *path, const char *mode)
{
int i = 0;
char *str = NULL;
char *part_path = NULL;
char *buf_temp = NULL;
int file_head_len = 0;
int align_size = 4096;
if (boot_info.vm.align == 1) {
align_size = 256;
}
str = strrchr(path, '/');
/* r_printf(">>>[test]:file name str = %s\n", str + 1); */
part_path = (char *)zalloc(strlen(path));
memcpy(part_path, path, strlen(path) - strlen(str));
/* r_printf(">>>[test]:part_path = %s\n", part_path); */
FILE *file = fopen(part_path, "r");
if (!file) {
r_printf(">>>[test]:no apply part!!!!!!!\n");
goto __exit;
}
struct vfs_attr attrs = {0};
fget_attrs(file, &attrs);
attrs.sclust = sdfile_cpu_addr2flash_addr(attrs.sclust);
if (attrs.sclust % align_size) {
fclose(file);
file = NULL;
r_printf(">>>[test]:part start addr is not alignment, sclust = %d, align_size = %d\n", attrs.sclust, align_size);
goto __exit;
}
cfg_private_create_sclust = attrs.sclust;
buf_temp = (char *)malloc(align_size);
norflash_read(NULL, (void *)buf_temp, align_size, attrs.sclust);
for (; i < CFG_PRIVATE_FILE_NUM; i++) {
int addr = attrs.sclust + i * sizeof(SDFILE_FILE_HEAD);
norflash_read(NULL, (void *)&head, sizeof(SDFILE_FILE_HEAD), addr);
if (CRC16((u8 *)&head + 2, sizeof(SDFILE_FILE_HEAD) - 2) == head.head_crc) {
file_head_len += head.len;
continue;
}
memset(&head, 0, sizeof(SDFILE_FILE_HEAD));
head.len = attrs.fsize - CFG_PRIVATE_FILE_NUM * sizeof(SDFILE_FILE_HEAD) - file_head_len;
/* y_printf(">>>[test]:file len = %d\n", head.len); */
head.addr = attrs.sclust + CFG_PRIVATE_FILE_NUM * sizeof(SDFILE_FILE_HEAD) + file_head_len;
head.addr = sdfile_flash_addr2cpu_addr(head.addr);
/* y_printf(">>>[test]:file addr = %d\n", head.addr); */
memcpy(head.name, (char *)(str + 1), strlen(str + 1));
head.attr = 0x02;
head.head_crc = CRC16((u8 *)&head + 2, sizeof(SDFILE_FILE_HEAD) - 2);
break;
}
if (i >= CFG_PRIVATE_FILE_NUM) {
fclose(file);
file = NULL;
r_printf(">>>[test]:file head is over\n");
goto __exit;
}
cfg_private_erase(attrs.sclust, align_size);
memcpy(buf_temp + i * sizeof(SDFILE_FILE_HEAD), &head, sizeof(SDFILE_FILE_HEAD));
norflash_write(NULL, (void *)buf_temp, align_size, attrs.sclust);
/* put_buf(buf_temp, align_size); */
fclose(file);
file = NULL;
file = fopen(path, mode);
__exit:
if (part_path) {
free(part_path);
}
if (buf_temp) {
free(buf_temp);
}
return file;
}
FILE *cfg_private_open(const char *path, const char *mode)
{
int res;
FILE *file = fopen(path, mode);
if (!file) {
if (mode[0] == 'w' && mode[1] == '+') {
file = cfg_private_create(path, mode);
if (file) {
cfg_private_create_flag = 1;
}
}
}
return file;
}
int cfg_private_read(FILE *file, void *buf, u32 len)
{
return fread(file, buf, len);
}
void cfg_private_erase(u32 addr, u32 len)
{
/* r_printf(">>>[test]:addr = 0x%x, len = %d\n", addr, len); */
u32 erase_total_size = len;
u32 erase_addr = addr;
u32 erase_size = 4096;
u32 erase_cmd = IOCTL_ERASE_SECTOR;
//flash不同支持的最小擦除单位不同(page/sector)
//boot_info.vm.align == 1: 最小擦除单位page;
//boot_info.vm.align != 1: 最小擦除单位sector;
if (boot_info.vm.align == 1) {
erase_size = 256;
erase_cmd = IOCTL_ERASE_PAGE;
}
while (erase_total_size) {
//擦除区域操作
norflash_ioctl(NULL, erase_cmd, erase_addr);
erase_addr += erase_size;
erase_total_size -= erase_size;
}
}
int cfg_private_check(char *buf, int len)
{
for (int i = 0; i < len; i++) {
if (buf[i] != 0xff) {
return 0;
}
}
return 1;
}
int cfg_private_write(FILE *file, void *buf, u32 len)
{
int align_size = 4096;
if (boot_info.vm.align == 1) {
align_size = 256;
}
struct vfs_attr attrs = {0};
fget_attrs(file, &attrs);
/* r_printf(">>>[test]:attrs.sclust = 0x%x\n", attrs.sclust); */
attrs.sclust = sdfile_cpu_addr2flash_addr(attrs.sclust);
u32 fptr = fpos(file);
/* r_printf(">>>[test]:addr = %d, fsize = %d, fptr = %d, w_len = %d\n", attrs.sclust, attrs.fsize, fptr, len); */
if (len + fptr > attrs.fsize) {
r_printf(">>>[test]:error, write over!!!!!!!!\n");
return -1;
}
char *buf_temp = (char *)malloc(align_size);
int res = len;
for (int wlen = 0; len > 0;) {
u32 align_addr = (attrs.sclust + fptr) / align_size * align_size;
u32 w_pos = attrs.sclust + fptr - align_addr;
wlen = align_size - w_pos;
/* y_printf(">>>[test]:wpos = %d, wlen = %d\n", w_pos, wlen); */
if (wlen > len) {
wlen = len;
}
norflash_read(NULL, (void *)buf_temp, align_size, align_addr);
if (0 == cfg_private_check(buf_temp, align_size)) {
cfg_private_erase(align_addr, align_size);
}
memcpy(buf_temp + w_pos, buf, wlen);
/* put_buf(buf_temp, align_size); */
norflash_write(NULL, (void *)buf_temp, align_size, align_addr);
fptr += wlen;
len -= wlen;
}
__exit:
free(buf_temp);
fseek(file, fptr, SEEK_SET);
return res;
}
int cfg_private_delete_file(FILE *file)
{
int align_size = 4096;
if (boot_info.vm.align == 1) {
align_size = 256;
}
struct vfs_attr attrs = {0};
fget_attrs(file, &attrs);
attrs.sclust = sdfile_cpu_addr2flash_addr(attrs.sclust);
int len = attrs.fsize;
char *buf_temp = (char *)malloc(align_size);
u32 fptr = 0;
for (int wlen = 0; len > 0;) {
u32 align_addr = (attrs.sclust + fptr) / align_size * align_size;
u32 w_pos = attrs.sclust + fptr - align_addr;
wlen = align_size - w_pos;
if (wlen > len) {
wlen = len;
}
norflash_read(NULL, (void *)buf_temp, align_size, align_addr);
if (0 == cfg_private_check(buf_temp, align_size)) {
cfg_private_erase(align_addr, align_size);
}
memset(buf_temp + w_pos, 0xff, wlen);
norflash_write(NULL, (void *)buf_temp, align_size, align_addr);
fptr += wlen;
len -= wlen;
}
free(buf_temp);
fclose(file);
return 0;
}
int cfg_private_close(FILE *file)
{
if (cfg_private_create_flag) {
int i = 0;
int align_size = 4096;
if (boot_info.vm.align == 1) {
align_size = 256;
}
char name[SDFILE_NAME_LEN];
fget_name(file, name, SDFILE_NAME_LEN);
char *buf_temp = (char *)malloc(align_size);
norflash_read(NULL, (void *)buf_temp, align_size, cfg_private_create_sclust);
for (; i < CFG_PRIVATE_FILE_NUM; i++) {
int addr = cfg_private_create_sclust + i * sizeof(SDFILE_FILE_HEAD);
norflash_read(NULL, (void *)&head, sizeof(SDFILE_FILE_HEAD), addr);
if (CRC16((u8 *)&head + 2, sizeof(SDFILE_FILE_HEAD) - 2) != head.head_crc) {
continue;
}
if (0 == memcmp(head.name, name, SDFILE_NAME_LEN)) {
head.len = fpos(file);
y_printf(">>>[test]:real file len = %d\n", head.len);
head.head_crc = CRC16((u8 *)&head + 2, sizeof(SDFILE_FILE_HEAD) - 2);
break;
}
}
cfg_private_create_flag = 0;
if (i < CFG_PRIVATE_FILE_NUM) {
cfg_private_erase(cfg_private_create_sclust, align_size);
memcpy(buf_temp + i * sizeof(SDFILE_FILE_HEAD), &head, sizeof(SDFILE_FILE_HEAD));
norflash_write(NULL, (void *)buf_temp, align_size, cfg_private_create_sclust);
}
if (buf_temp) {
free(buf_temp);
}
}
return fclose(file);
}
int cfg_private_seek(FILE *file, int offset, int fromwhere)
{
return fseek(file, offset, fromwhere);
}
void cfg_private_test_demo(void)
{
#if 0
#define N 256
char test_buf[N] = {0};
char r_buf[512] = {0};
for (int i = 0; i < N; i++) {
test_buf[i] = i & 0xff;
}
char path[64] = "mnt/sdfile/app/FATFSI/eq_cfg_hw.bin";
char path2[64] = "mnt/sdfile/app/FATFSI/cfg_tool.bin";
y_printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__);
FILE *fp = cfg_private_open(path, "w+");
if (!fp) {
r_printf(">>>[test]:open fail!!!!!\n");
while (1);
}
/* cfg_private_delete_file(fp); */
/* fp = cfg_private_open(path, "w+"); */
/* cfg_private_read(fp, r_buf, 512); */
/* put_buf(r_buf, 512); */
/* cfg_private_seek(fp, 0, SEEK_SET); */
cfg_private_write(fp, test_buf, N);
cfg_private_close(fp);
fp = cfg_private_open(path, "r");
cfg_private_read(fp, r_buf, 512);
put_buf(r_buf, 512);
fclose(fp);
y_printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__);
fp = cfg_private_open(path2, "w+");
if (!fp) {
r_printf(">>>[test]:open fail!!!!!\n");
while (1);
}
for (int i = 0; i < N; i++) {
test_buf[i] = (N - 1 - i) & 0xff;
}
cfg_private_write(fp, test_buf, N);
cfg_private_close(fp);
fp = cfg_private_open(path2, "r");
cfg_private_read(fp, r_buf, 512);
put_buf(r_buf, 512);
fclose(fp);
#if 0
FILE *file = cfg_private_open("mnt/sdfile/app/FATFSI", "w+");
if (!file) {
r_printf(">>>[test]:open fail!!!!!\n");
while (1);
}
struct vfs_attr attrs = {0};
fget_attrs(file, &attrs);
y_printf(">>>[test]:in part addr = %d, fsize = %d\n", attrs.sclust, attrs.fsize);
char *part = zalloc(attrs.fsize);
cfg_private_delete_file(file);
file = cfg_private_open("mnt/sdfile/app/FATFSI", "w+");
cfg_private_read(file, part, attrs.fsize);
put_buf(part, attrs.fsize);
free(part);
#endif
while (1);
#endif
}