#ifdef SUPPORT_MS_EXTENSIONS #pragma bss_seg(".cfg_private.data.bss") #pragma data_seg(".cfg_private.data") #pragma const_seg(".cfg_private.text.const") #pragma code_seg(".cfg_private.text") #endif #include "system/includes.h" #include "boot.h" #include "tzflash_api.h" #include "cfg_private.h" #include "sdfile.h" #include "fs/resfile.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; void cfg_private_erase(u32 addr, u32 len); static RESFILE *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, '/'); int path_len = strlen(path); if (str) { path_len -= strlen(str); } /* r_printf(">>>[test]:file name str = %s\n", str + 1); */ part_path = (char *)zalloc(path_len + 1); ASSERT(part_path); memcpy(part_path, path, path_len); part_path[path_len] = '\0'; /* r_printf(">>>[test]:part_path = %s\n", part_path); */ RESFILE *file = resfile_open(part_path); if (!file) { r_printf(">>>[test]:no apply part!!!!!!!\n"); goto __exit; } struct resfile_attrs attrs = {0}; resfile_get_attrs(file, &attrs); attrs.sclust = sdfile_cpu_addr2flash_addr(attrs.sclust); if (attrs.sclust % align_size) { resfile_close(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); tzflash_read((void *)buf_temp, align_size, attrs.sclust); for (; i < CFG_PRIVATE_FILE_NUM; i++) { int addr = attrs.sclust + i * sizeof(SDFILE_FILE_HEAD); tzflash_read((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) { resfile_close(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)); tzflash_write((void *)buf_temp, align_size, attrs.sclust); /* put_buf(buf_temp, align_size); */ resfile_close(file); file = NULL; file = resfile_open(path); __exit: if (part_path) { free(part_path); } if (buf_temp) { free(buf_temp); } return file; } RESFILE *cfg_private_open(const char *path, const char *mode) { RESFILE *file = resfile_open(path); 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(RESFILE *file, void *buf, u32 len) { return resfile_read(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) { //擦除区域操作 tzflash_ioctl(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] != (char)(-1)) { return 0; } } return 1; } int cfg_private_write(RESFILE *file, void *buf, u32 len) { int align_size = 4096; if (boot_info.vm.align == 1) { align_size = 256; } struct resfile_attrs attrs = {0}; resfile_get_attrs(file, &attrs); /* r_printf(">>>[test]:attrs.sclust = 0x%x\n", attrs.sclust); */ attrs.sclust = sdfile_cpu_addr2flash_addr(attrs.sclust); u32 fptr = resfile_get_pos(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; } tzflash_read((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); */ tzflash_write((void *)buf_temp, align_size, align_addr); fptr += wlen; len -= wlen; } free(buf_temp); resfile_seek(file, fptr, SEEK_SET); return res; } int cfg_private_delete_file(RESFILE *file) { int align_size = 4096; if (boot_info.vm.align == 1) { align_size = 256; } struct resfile_attrs attrs = {0}; resfile_get_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; } tzflash_read((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); tzflash_write((void *)buf_temp, align_size, align_addr); fptr += wlen; len -= wlen; } free(buf_temp); resfile_close(file); return 0; } int cfg_private_close(RESFILE *file) { if (cfg_private_create_flag) { int i = 0; int align_size = 4096; if (boot_info.vm.align == 1) { align_size = 256; } u8 name[SDFILE_NAME_LEN]; resfile_get_name(file, name, SDFILE_NAME_LEN); char *buf_temp = (char *)malloc(align_size); tzflash_read((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); tzflash_read((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 = resfile_get_pos(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)); tzflash_write((void *)buf_temp, align_size, cfg_private_create_sclust); } if (buf_temp) { free(buf_temp); } } return resfile_close(file); } int cfg_private_seek(RESFILE *file, int offset, int fromwhere) { return resfile_seek(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__); RESFILE *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); resfile_close(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); resfile_close(fp); #if 0 RESFILE *file = cfg_private_open("mnt/sdfile/app/FATFSI", "w+"); if (!file) { r_printf(">>>[test]:open fail!!!!!\n"); while (1); } struct resfile_attrs attrs = {0}; resfile_get_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 }