123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- #include "spiFlashFat.h"
- #include "spiFlash.h"
- #define SFILE_VALID_MARK 0x20115028
- #define INVALID_FID 0xff
- #define SERR_SUCC 0
- #define SERR_INIT_FAIL 1
- #define SERR_ERACE_FAIL 2
- #define SERR_WRITE_FAIL 3
- #define SERR_READ_FAIL 4
- #define SERR_FILE_FULL 5
- #define SERR_SIZE_FULL 6
- static unsigned char spiFatErr=0;
- unsigned char spi_flash_get_err(void){return spiFatErr;}
- /*SPI FLASH 使用地址划分*/
- /*第一块,用于系统参数保存使用,自带备份,每个文件暂时2个sector*/
- /*第一块,用于应用创建使用*/
- #define MAX_SFILE_NUM 5 //1区最多可以创建多少个系统参数文件
- #define SFILE_BLOCK_1_START_ADDR 0 //1区起始地址
- #define SFILE_BLOCK_1_SIZE_BYTE (2*MAX_SFILE_NUM*SECTOR_SIZE_BYTE) //1区总大小
- /*第二块,用于文件暂时存储,不带备份,异常掉电可能丢失*/
- #define SFILE_BLOCK_2_START_ADDR (SFILE_BLOCK_1_START_ADDR+SFILE_BLOCK_1_SIZE_BYTE)//2区起始地址
- #define SFILE_BLOCK_2_SIZE_BYTE (SECTOR_SIZE_BYTE+SECTOR_SIZE_BYTE*128)//2区总大小
- //检测是否超出存储范围
- #define SFILE_USER_MAX (SFILE_BLOCK_1_SIZE_BYTE+SFILE_BLOCK_2_SIZE_BYTE)
- #if(SFILE_USER_MAX>SPI_FLASH_MAX_SIZE)
- #error "USER FLASH SIZE OVERFLOW"
- #endif
- /***********************************第一块文件系统实现*************************************/
- #pragma pack(push)
- #pragma pack(1)
- typedef struct{//放在sector最后
- unsigned short crc16;
- unsigned int mark;
- }SFILE_INFO_DEF;
- #pragma pack(pop)
- #define SFILE_VALID_SIZE (SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF)) //每个系统文件最多能存的用户有效数据
- /*格式化文件*/
- bool spi_flash_file_format(unsigned char fid){
- char i;
-
- SPI_PWR_LOCK;
- if(fid>=MAX_SFILE_NUM || spiFlashInit()==false){
- spiFatErr=SERR_INIT_FAIL;SPI_PWR_RELEAS;
- return INVALID_FID;
- }
- for(i=0;i<2;i++){
- if(false==spiFlashSectorErace(SFILE_BLOCK_1_START_ADDR+(fid*2+i)*SECTOR_SIZE_BYTE)){
- spiFatErr=SERR_ERACE_FAIL;SPI_PWR_RELEAS;
- return false;
- }
- }
- SPI_PWR_RELEAS;
- return true;
- }
- /*格式化区域所有文件*/
- bool spi_flash_files_format(void){
- char i;
-
- SPI_PWR_LOCK;
- for(i=0;i<MAX_SFILE_NUM;i++){
- if(false==spi_flash_file_format(i)){
- SPI_PWR_RELEAS;
- return false;
- }
- }
- SPI_PWR_RELEAS;
- return true;
- }
- /*文件读数据*/
- bool spi_flash_file_read(unsigned char fid, unsigned int addr, unsigned char *ptr, unsigned int size){
- int len=size;
- //都从使用区读,备份区只在开机时作恢复使用
- if(spiFlashInit()==false){
- spiFatErr=SERR_INIT_FAIL;
- return false;
- }
- //读取
- if(len>SFILE_VALID_SIZE) len=SFILE_VALID_SIZE;
- if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE+addr, ptr, len)){
- spiFatErr=SERR_READ_FAIL;
- return false;
- }
- return true;
- }
- /*文件写数据*/
- bool spi_flash_file_write(unsigned char fid, unsigned int addr, unsigned char *ptr, unsigned int size){
- unsigned char tmp[SECTOR_SIZE_BYTE];
- unsigned int len=size;
- SFILE_INFO_DEF *info=tmp+SFILE_VALID_SIZE;
-
- //先写备份区,再写使用区
- //1,先读使用区数据
- if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
- spiFatErr=SERR_READ_FAIL;
- return false;
- }
- //2,修改缓存数据
- if(len>SFILE_VALID_SIZE) len=SFILE_VALID_SIZE;
- memcpy(tmp+addr, ptr, len);
- info->mark=SFILE_VALID_MARK;
- info->crc16=make_crc16(tmp, SFILE_VALID_SIZE);
- info->crc16 += make_crc16(tmp+SECTOR_SIZE_BYTE-4);
- SPI_PWR_LOCK;
- //3,写到备份区
- if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE+SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
- spiFatErr=SERR_WRITE_FAIL;
- SPI_PWR_RELEAS;
- return false;
- }
- //4,写到使用区
- if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
- spiFatErr=SERR_WRITE_FAIL;
- SPI_PWR_RELEAS;
- return false;
- }
- SPI_PWR_RELEAS;
- return true;
- }
- /*检测是否需要恢复,不会出现两个sector都异常*/
- static bool spi_flash_file_check(void){
- unsigned char i;
- unsigned char tmp[SECTOR_SIZE_BYTE];
- SFILE_INFO_DEF info1,info2;
- unsigned short crc16_1,crc16_2;
-
- if(spiFlashInit()==false){
- spiFatErr=SERR_INIT_FAIL;
- return false;
- }
- for(i=0;i<MAX_SFILE_NUM;i++){
- //读取使用区,得出mark,crc16
- if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*i*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
- spiFatErr=SERR_READ_FAIL;
- return false;
- }
- memcpy((unsigned char *)&info1, tmp+SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF), sizeof(SFILE_INFO_DEF));
- //计算crc16
- crc16_1=make_crc16(tmp, SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF));
- crc16_1 += make_crc16(tmp+SECTOR_SIZE_BYTE-4,4);
- //读取备份区,得出mark,crc16
- if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+(2*i+1)*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
- spiFatErr=SERR_READ_FAIL;
- return false;
- }
- memcpy((unsigned char *)&info2, tmp+SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF), sizeof(SFILE_INFO_DEF));
- //计算crc16
- crc16_2=make_crc16(tmp, SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF));
- crc16_2 += make_crc16(tmp+SECTOR_SIZE_BYTE-4,4);
- //比较
- if(info1.mark==SFILE_VALID_MARK && info1.crc16==crc16_1) {}//使用区正常,不需要处理
- else if(info2.mark==SFILE_VALID_MARK && info2.crc16==crc16_2){//使用区不正常,备区正常,备拷贝到使用区
- if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+(2*i+1)*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
- spiFatErr=SERR_WRITE_FAIL;
- SPI_PWR_RELEAS;
- return false;
- }
- }else if(info1.mark!=0xffffffff){//未format过,fotmat之
- if(false==spi_flash_file_format(i)){
- spiFatErr=SERR_ERACE_FAIL;
- return false;
- }
- }
- }
- return true;
- }
- /***********************************第二块文件系统实现*************************************/
- #pragma pack(push)
- #pragma pack(1)
- typedef struct{
- unsigned int mark;//文件是否有效标识
- unsigned int startAddr;//文件起始地址
- unsigned int size;//文件大小
- unsigned short crc16//结构体crc16
- }SFAT_INFO_DEF;
- #define MAX_SFAT_NUM 10
- typedef struct{
- SFAT_INFO_DEF files[MAX_SFAT_NUM];
- unsigned char validFiles;//有效文件个数
- unsigned int validSize;//区域可用空间
- unsigned short crc16;//结构体crc16
- }SFAT_LIST_DEF;
- #pragma pack(pop)
- static SFAT_LIST_DEF sFat;
- /*搜索空文件*/
- static unsigned char spi_flash_fat_get_empty(void){
- int i;
-
- for(i=0;i<MAX_SFAT_NUM;i++){
- if(sFat.files[i].mark != SFILE_VALID_MARK) return i;
- }
- return INVALID_FID;
- }
- /*格式化区域*/
- bool spi_flash_fat_format(void){
- unsigned int i,addr=SFILE_BLOCK_2_START_ADDR;
-
- if(spiFlashInit()==false){
- spiFatErr=SERR_INIT_FAIL;
- return false;
- }
- //擦除整块区域
- for(i=0;i<SFILE_BLOCK_2_SIZE_BYTE;i+=SECTOR_SIZE_BYTE){
- if(false==spiFlashSectorErace(addr+i)){
- spiFatErr=SERR_ERACE_FAIL;
- return false;
- }
- }
- //初始化结构体
- memset((unsigned char *)&sFat, 0, sizeof(SFAT_LIST_DEF));
- sFat.validSize=SFILE_BLOCK_2_SIZE_BYTE-SECTOR_SIZE_BYTE;
- //更新到内存
- if(spiFlashDataWrite(addr, (unsigned char *)&sFat, sizeof(SFAT_LIST_DEF))){
- spiFatErr=SERR_WRITE_FAIL;
- return false;
- }
- return true;
- }
- /*区域中新建文件*/
- /*sectorNum:文件占用多少sector
- 返回:INVALID_FID, 失败 , else 文件ID*/
- unsigned char spi_flash_fat_create(unsigned short sectorNum){
- unsigned char fid;
- SFAT_INFO_DEF *info;
-
- if(spiFlashInit()==false){
- spiFatErr=SERR_INIT_FAIL;
- return INVALID_FID;
- }
- //查找空文件
- fid=spi_flash_fat_get_empty();
- if(fid==INVALID_FID){
- spiFatErr=SERR_FILE_FULL;
- return fid;
- }
- info=&sFat.files[fid];
- //初始化文件
- memset((unsigned char *)info, 0, sizeof(SFAT_INFO_DEF));
- info->mark=SFILE_VALID_MARK;
- if(fid==0) info->startAddr=SECTOR_SIZE_BYTE;//第一个文件放在列表sector的下sector开始
- else info->startAddr=sFat.files[fid-1].startAddr+sFat.files[fid-1].size;
- info->size=sectorNum*SECTOR_SIZE_BYTE;
- if(info->size<sFat.validSize){
- spiFatErr=SERR_SIZE_FULL;
- return INVALID_FID;
- }
- info->crc16=make_crc16((unsigned char *)info,sizeof(SFAT_INFO_DEF)-2);
- //更新剩余
- sFat.validSize -= info->size;
- sFat.validFiles++;
- sFat.crc16=make_crc16((unsigned char *)&sFat, sizeof(SFAT_LIST_DEF)-2);
- //保存
- if(spiFlashDataWrite(SFILE_BLOCK_2_START_ADDR, (unsigned char *)&sFat, sizeof(SFAT_LIST_DEF))){//恢复
-
-
- spiFatErr=SERR_WRITE_FAIL;
- return INVALID_FID;
- }
- return fid;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- /*spi文件系统初始化,读写前先调用*/
- void spiFlashInitApiInit(void){
- spi_flash_file_check();//检测是否需要备份的恢复
- }
|