/***************************************************************************** Flash.c *****************************************************************************/ #define THIS_FILE_ID 20 /* Includes ------------------------------------------------------------------*/ #include "includes.h" SUT_SYSTEM_INFO g_sutSystemInfo; SUT_BFR sutBFR; SUT_FMR sutFMR; SUT_FTR sutFTR; int StorageCalBFRCount(void); int StorageCalFTRCount(void); int StorageCalFMRCount(void); /****************************************************************** 存储SystemInfo信息 *******************************************************************/ void StorageSaveSysInfo(void) { //保存1区 SPI_Flash_Unprotect_Sector(STORAGE_SYSINF1_ADDR); SPI_Flash_Write((u8 *)&g_sutSystemInfo,STORAGE_SYSINF1_ADDR,sizeof(SUT_SYSTEM_INFO)); SPI_Flash_Protect_Sector(STORAGE_SYSINF1_ADDR); //保存2区 SPI_Flash_Unprotect_Sector(STORAGE_SYSINF2_ADDR); SPI_Flash_Write((u8 *)&g_sutSystemInfo,STORAGE_SYSINF2_ADDR,sizeof(SUT_SYSTEM_INFO)); SPI_Flash_Protect_Sector(STORAGE_SYSINF2_ADDR); } /****************************************************************** StorageInit 1、检查是否需要格式化,如需要,则格式化之 2、如果不需要格式化,则读系统信息到sutSystemInfo中 3、sutSystemInfo中的 BFRecordCt、FLRecordCt需要重新计算获取 *******************************************************************/ void StorageInit(void) { unsigned short BootCt; //先读1区,如果非法在读2区 SPI_Flash_Read((u8 *)&g_sutSystemInfo,STORAGE_SYSINF1_ADDR,sizeof(SUT_SYSTEM_INFO)); if(g_sutSystemInfo.Mark!=STORAGE_MARK){//1 区非法 printf("STORAGE_SYSINF1_ADDR invalid!\r\n"); SPI_Flash_Read((u8 *)&g_sutSystemInfo,STORAGE_SYSINF2_ADDR,sizeof(SUT_SYSTEM_INFO)); if(g_sutSystemInfo.Mark!=STORAGE_MARK){//2区非法 //两个区都非法,说明首次启动,需要格式化 //如果是手动格式化,需要保存上一个BootCt,使新得BootCt是再旧得基础上递增 if(g_sutSystemInfo.Mark==STORAGE_FORMAT_MARK){ BootCt=g_sutSystemInfo.BootCt+1; if(BootCt==0)BootCt=1; }else BootCt=1; printf("STORAGE_SYSINF2_ADDR invalid!\r\n"); printf("Format sFlash...\r\n"); SPI_Flash_Global_Unprotect(); SPI_Flash_Erase_Chip(); printf("Format sFlash ok!\r\n"); printf("Reset Stoage system!\r\n"); memset(&g_sutSystemInfo,0,sizeof(SUT_SYSTEM_INFO)); g_sutSystemInfo.Mark=STORAGE_MARK; g_sutSystemInfo.BootCt=BootCt; StorageSaveSysInfo(); //再读1次校验,如果仍非法说明FLASH可能坏了! SPI_Flash_Read((u8 *)&g_sutSystemInfo,STORAGE_SYSINF1_ADDR,sizeof(SUT_SYSTEM_INFO)); if(g_sutSystemInfo.Mark!=STORAGE_MARK){ printf("sFlash is error! reboot now!\r\n"); while(1); } return; }else{//2区合法,1区非法 printf("Recover Stoage_Sys_Inf_1\r\n"); g_sutSystemInfo.BootCt++; StorageSaveSysInfo(); } }else{//1 区合法,也要读下2区 SUT_SYSTEM_INFO sutSystemInfoBak; SPI_Flash_Read((u8 *)&sutSystemInfoBak,STORAGE_SYSINF2_ADDR,sizeof(SUT_SYSTEM_INFO)); if(sutSystemInfoBak.Mark!=STORAGE_MARK){//2区非法,重置2区 printf("STORAGE_SYSINF2_ADDR invalid!\r\n"); printf("Recover Stoage_Sys_Inf_2\r\n"); g_sutSystemInfo.BootCt++; StorageSaveSysInfo(); }else{//1区 2区都合法 BootCt加1后保存 g_sutSystemInfo.BootCt++; StorageSaveSysInfo(); } } // printf("StorageReadSystemInfo OK!\r\n"); printf("Status=%d\r\nBootCt=%d\r\n",g_sutSystemInfo.Status,g_sutSystemInfo.BootCt); //重新计算 BFRecordCt 和 FLRecordCt g_sutSystemInfo.BFRCt=StorageCalBFRCount(); g_sutSystemInfo.FTRCt=StorageCalFTRCount(); g_sutSystemInfo.FMRCt=StorageCalFMRCount(); printf("BFRCt=%lu FTRCt=%lu FMRCt=%lu\r\n",g_sutSystemInfo.BFRCt,g_sutSystemInfo.FTRCt,g_sutSystemInfo.FMRCt); // BFRCt=StorageCallBFRCount1(); // printf("BFRCt=%d\r\n",BFRCt); // FTRCt=StorageCallFTRCount1(); // printf("FTRCt=%d\r\n",FTRCt); // FMRCt=StorageCallFMRCount1(); // printf("FMRCt=%d\r\n",FMRCt); // // if(BFRCt!=g_sutSystemInfo.BFRCt){ // printf("BFRCt err=%d\r\n",BFRCt-(int)g_sutSystemInfo.BFRCt); // } // if(FTRCt!=g_sutSystemInfo.FTRCt){ // printf("FTRCt err=%d\r\n",FTRCt-(int)g_sutSystemInfo.FTRCt); // } // if(FMRCt!=g_sutSystemInfo.FMRCt){ // printf("FMRCt err=%d\r\n",FMRCt-(int)g_sutSystemInfo.FMRCt); // } } /****************************************************************** 读取一条BFR记录 入口:index --记录索引 从0开始 出口: pBFR --记录内容 返回值: 0--失败 记录无效 1--成功 *******************************************************************/ int StorageReadBFR(SUT_BFR *pBFR,u32 index) { u16 i,len; u32 addr; u8 *pBuf; len=sizeof(SUT_BFR); pBuf=(u8 *)pBFR; addr=STORAGE_BFR_ADDR+index*len; tsk_lock(); SPI_Flash_Read(pBuf,addr,len); tsk_unlock(); if(pBFR->Status>2)return 0; else return 1; } /****************************************************************** 读取一条FTR记录 入口:index --记录索引 从0开始 出口: pFTR --记录内容 返回值: 0--失败 记录无效 1--成功 *******************************************************************/ int StorageReadFTR(SUT_FTR *pFTR,u32 index) { u16 i,len; u32 addr; u8 *pBuf; len=sizeof(SUT_FTR); pBuf=(u8 *)pFTR; addr=STORAGE_FTR_ADDR+index*len; tsk_lock(); SPI_Flash_Read(pBuf,addr,len); tsk_unlock(); if(pFTR->Status>2)return 0; else return 1; } /****************************************************************** 读取一条FMR记录 入口:index --记录索引 从0开始 出口: pFMR --记录内容 返回值: 0--失败 记录无效 1--成功 *******************************************************************/ int StorageReadFMR(SUT_FMR *pFMR,u32 index) { u16 i,len; u32 addr; u8 *pBuf; len=sizeof(SUT_FMR); pBuf=(u8 *)pFMR; addr=STORAGE_FMR_ADDR+index*len; tsk_lock(); SPI_Flash_Read(pBuf,addr,len); tsk_unlock(); if(pFMR->Status>2)return 0; else return 1; } /****************************************************************** 存储BFR记录 *******************************************************************/ void StorageSaveBFR(SUT_BFR *pRecord) { u16 len; u32 addr; u32 Dst_Addr; u8 *pBuf; if(g_sutSystemInfo.BFRCt>=STORAGE_BFR_COUNT_MAX){ printf("BFRCt>STORAGE_BFR_COUNT_MAX\r\n"); return; } len=sizeof(SUT_BFR); pBuf=(u8 *)pRecord; addr=STORAGE_BFR_ADDR+g_sutSystemInfo.BFRCt*len; Dst_Addr=addr/4096; tsk_lock(); SPI_Flash_Unprotect_Sector(Dst_Addr); SPI_Flash_Write_NoCheck(pBuf,addr,len); SPI_Flash_Protect_Sector(Dst_Addr); g_sutSystemInfo.BFRCt++; tsk_unlock(); } /****************************************************************** 存储FTR记录 0--满 1-成功 *******************************************************************/ int StorageSaveFTR(SUT_FTR *pRecord) { u16 len; u32 addr; u32 Dst_Addr; u8 *pBuf; if(g_sutSystemInfo.FTRCt>=STORAGE_FTR_COUNT_MAX)return 0; len=sizeof(SUT_FTR); pBuf=(u8 *)pRecord; addr=STORAGE_FTR_ADDR+g_sutSystemInfo.FTRCt*len; Dst_Addr=addr/4096; tsk_lock(); SPI_Flash_Unprotect_Sector(Dst_Addr); SPI_Flash_Write_NoCheck(pBuf,addr,len); SPI_Flash_Protect_Sector(Dst_Addr); g_sutSystemInfo.FTRCt++; tsk_unlock(); return 1; } /****************************************************************** 存储FMR记录 0--满 1-成功 *******************************************************************/ int StorageSaveFMR(SUT_FMR *pRecord) { u16 len; u32 addr; u32 Dst_Addr; u8 *pBuf; if(g_sutSystemInfo.FMRCt>=STORAGE_FMR_COUNT_MAX)return 0; len=sizeof(SUT_FMR); pBuf=(u8 *)pRecord; addr=STORAGE_FMR_ADDR+g_sutSystemInfo.FMRCt*len; Dst_Addr=addr/4096; tsk_lock(); SPI_Flash_Unprotect_Sector(Dst_Addr); SPI_Flash_Write_NoCheck(pBuf,addr,len); SPI_Flash_Protect_Sector(Dst_Addr); g_sutSystemInfo.FMRCt++; tsk_unlock(); return 1; } /******************************************************************* *StorageCalBFRCount *计算 BFR 已存储的记录个数 *为了提高速度,采用二分法 ********************************************************************/ int StorageCalBFRCount(void) { int flag=0; u8 status; u32 addr; u32 m=STORAGE_BFR_COUNT_MAX; u32 n,n1,n2; n1=1;n2=m; n=(n2-n1)/2; while(n12){//此记录为空 //需要继续往前找 n2=n; n=n1+(n-n1)/2; }else{//此记录非空 //需要继续往后找 flag=1; n1=n; n=n1+(n2-n)/2; } } if(n1==1){ if(flag==1)return 1; else return 0; } return n1; } /******************************************************************* *StorageCalFTRCount *计算FTR已存储的记录个数 *为了提高速度,采用二分法 ********************************************************************/ int StorageCalFTRCount(void) { int flag=0; u8 status; u32 addr; u32 m=STORAGE_FTR_COUNT_MAX; u32 n,n1,n2; n1=1;n2=m; n=(n2-n1)/2; while(n12){//此记录为空 //需要继续往前找 n2=n; n=n1+(n-n1)/2; }else{//此记录非空 //需要继续往后找 flag=1; n1=n; n=n1+(n2-n)/2; } } if(n1==1){ if(flag==1)return 1; else return 0; } return n1; } //从头到尾检索法,统计FMR记录数,速度比较慢 int StorageCallFMRCount1(void) { int j=0; u8 status; u32 i=0; u32 addr; for(i=0;i2){//此记录为空 //需要继续往前找 n2=n; n=n1+(n-n1)/2; }else{//此记录非空 //需要继续往后找 flag=1; n1=n; n=n1+(n2-n)/2; } } if(n1==1){ if(flag==1)return 1; else return 0; } return n1; } /*****************************************************************************/