123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- /*****************************************************************************
- Flash.c
- *****************************************************************************/
- #define THIS_FILE_ID 20
- /* Includes ------------------------------------------------------------------*/
- #include "includes.h"
- SUT_STORAGE_FIFO sutStorageFiFo;
- void StorageFormat(void)
- {
- unsigned char buf[1];
- int addr;
- SlwTrace(DEBUG,"Flash Format!!\r\n");
- SPI_Flash_Erase_Chip();
- SaveDeviceConfigToFlash();
- sutStorageFiFo.in=0;
- sutStorageFiFo.out=0;
- sutStorageFiFo.len=0;
- for(addr=STORAGE_POS_START_ADDR;addr<STORAGE_POS_END_ADDR;addr+=64){
- SPI_Flash_Read(buf,addr,1);
- if(buf[0]!=0xff)break;
- }
- if(addr<STORAGE_POS_END_ADDR){
- SlwTrace(DEBUG,"Flash Format fail!!\r\n");
- }
- }
- /******************************************************************
- StorageInit
- *******************************************************************/
- void StorageFiFoInit(void)
- {
- unsigned char Format=0;
- unsigned char Flag;
- unsigned long addr=STORAGE_POS_START_ADDR;
- int i,F1,F2,N1,N2;
- char buf[20];
- //配置合法性判断
- if(sizeof(SUT_POSITION)!=STORAGE_POS_LEN){
- SlwTrace(DEBUG,"sizeof(SUT_POSITION)!=STORAGE_POS_LEN\r\n");
- while(1);
- }
-
- //printf("\r\nFIFO Size=%d\r\n",STORAGE_POS_COUNT_TOTAL);
-
- F1=-1;//第一个FF位置
- F2=-1;//最后一个FF位置
- N1=-1;//第一个非FF位置
- N2=-1;//最后一个非FF位置
- i=0;
- while(addr<STORAGE_POS_END_ADDR){
- SPI_Flash_Read(&Flag,addr,1);
- if(Flag==0xFF){
- if(F1==-1)F1=i;
- F2=i;
- }else if(Flag==STORAGE_POS_FLAG){
- if(N1==-1)N1=i;
- N2=i;
- }else{
- Format=1;
- }
- i++;
- addr+=sizeof(SUT_POSITION);
- }
- //
- if(Format){
- StorageFormat();
- return;
- }
- /*
- XX XX XX XX XX:F1=-1 if(F1=-1 || F2=-1)禁止出现,需要重新格式化
- FF FF FF FF FF:N1=-1 if(N1=-1 || N2=-1)空
- XX XX FF FF FF:F1=2 F2=4 N1=0 N2=1 if(F2=max && N1=0){In=F1 Out=N1 len=F1}
- FF FF XX XX XX:F1=0 F2=1 N1=2 N2=4 if(F1=0 && N2=max){In=F1 Out=N1 len=max-N1}
- FF XX XX FF FF:F1=0 F2=4 N1=1 N2=2 if(F1=0 && F2=max){In=N2+1 Out=N1 len=N2-N1+1}
- XX FF FF XX XX:F1=1 F2=2 N1=0 N2=4 if(N1=0 && N2=max){In=F1 Out=F2+1 len=max-F2+F1}
- */
- int max=STORAGE_POS_COUNT_TOTAL-1;
- if(F1 == -1 || F2 == -1){//非法
- SlwTrace(DEBUG,"STORAGE is Invalid[2]!\r\n");
- StorageFormat();
- }else if(N1 == -1 || N2 == -1){//空
- sutStorageFiFo.in=0;
- sutStorageFiFo.out=0;
- sutStorageFiFo.len=0;
- }else if(F2==max && N1==0){//In=F1 Out=N1 len=F1
- sutStorageFiFo.in=F1;
- sutStorageFiFo.out=N1;
- sutStorageFiFo.len=F1;
- }else if(F1==0 && N2==max){//In=F1 Out=N1 len=max-N1
- sutStorageFiFo.in=F1;
- sutStorageFiFo.out=N1;
- sutStorageFiFo.len=max-N1;
- }else if(F1==0 && F2==max){//In=N2+1 Out=N1 len=N2-N1+1
- sutStorageFiFo.in=N2+1;
- sutStorageFiFo.out=N1;
- sutStorageFiFo.len=N2-N1+1;
- }else if(N1==0 && N2 == max){//In=F1 Out=F2+1 len=max-F2+F1
- sutStorageFiFo.in=F1;
- sutStorageFiFo.out=F2+1;
- sutStorageFiFo.len=max-F2+F1;
- }else{//不存在这种情况
- SlwTrace(DEBUG,"STORAGE is Invalid[3]!\r\n");
- StorageFormat();
- }
- //printf("F1=%d F2=%d N1=%d N2=%d\r\n",F1,F2,N1,N2);
- //printf("FiFo.in=%d\r\nFiFo.out=%d\r\nFiFo.len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
- }
- extern u8 SPI_FLASH_BUF[];
- /******************************************************************
- 从FIFO中读取一条SUT_POSITION记录
- 返回值: 0--失败 记录无效 1--成功
- *******************************************************************/
- int StorageFiFoPop(SUT_POSITION *pPos)
- {
- int sector;
- int i;
- int addr;
- //判断是否为空
- if(sutStorageFiFo.out == sutStorageFiFo.in){
- SlwTrace(DEBUG,"FIFO is Empty!\r\n");
- return 0;
- }
- //非空方可读值
- addr=STORAGE_POS_START_ADDR+sutStorageFiFo.out*STORAGE_POS_LEN;
- SPI_Flash_Read((u8 *)pPos,addr,STORAGE_POS_LEN);
- if(pPos->flag!=STORAGE_POS_FLAG || pPos->Mark!=STORAGE_POS_MARK){
- //这种情况里应不存在,存在说明发生异常!
- //异常原因可能是Push写入时写到一半突然掉电,此时应该修正之
- SlwTrace(DEBUG,"StorageFiFoPOP Exception!\r\n");
- //printf("[%d]flag=%02X mark=%08lX\r\n",sutStorageFiFo.out,pPos->flag,pPos->Mark);
- memset((u8 *)pPos,0xff,STORAGE_POS_LEN);
- SPI_Flash_Write((u8 *)pPos,addr,STORAGE_POS_LEN);
- sutStorageFiFo.out=(sutStorageFiFo.out+1)%STORAGE_POS_COUNT_TOTAL;
- sutStorageFiFo.len--;
- return 0;
- }
- //移位
- sutStorageFiFo.out=(sutStorageFiFo.out+1)%STORAGE_POS_COUNT_TOTAL;
- sutStorageFiFo.len--;
- //如果移动到新的SECTOR,并且in不在前一区,则将前一区擦除,下次重启才会刷新out
- if(sutStorageFiFo.out%STORAGE_POS_COUNT_SECTOR==0){
- //获取out的前一区
- sector=sutStorageFiFo.out/STORAGE_POS_COUNT_SECTOR;
- if(sector>0)sector--;
- else sector=STORAGE_POS_COUNT_TOTAL/STORAGE_POS_COUNT_SECTOR-1;//最后一个扇区
- // out的前一个扇区 与 in所在扇区 不一样,才允许擦除
- if(sector!=(sutStorageFiFo.in/STORAGE_POS_COUNT_SECTOR)){
- sector+=STORAGE_POS_START_ADDR/4096;
- SPI_Flash_Erase_Sector(sector);
- // printf("Erase[%d]\r\n",sector);
- // SPI_Flash_Read(SPI_FLASH_BUF,sector*4096,4096);//读出整个扇区的内容
- // for(i=0;i<4096;i++){
- // if(SPI_FLASH_BUF[i]!=0xFF)break;
- // }
- // if(i<4096)printf("Erase Fail!\r\n");
- }
- }
- return 1;
- }
- /******************************************************************
- 存储Pos记录到FIFO中
- 如果已满,自动抛弃最早的数据
- *******************************************************************/
- int StorageFiFoPush(SUT_POSITION *pRecord)
- {
- SUT_POSITION pos;
- int Sector;
- int len;
- int addr;
- //预留64个元素,少于64则认为满,移除最早的数据,每次移除N个,N取决于当前out所在sector占用元素个数
- if (STORAGE_POS_COUNT_TOTAL-sutStorageFiFo.len<64){
- //算出当前out位置所在的Sector有len个元素,格式化这个Sector后需要将out移len位
- // |FF FF FF XX | XX XX XX XX |XX XX XX FF|
- // out=3 in=11 (11+4)%12==3
- // len=4-(3%4)=1
-
- // |XX FF FF FF | FF XX XX XX |XX XX XX XX|
- // out=5 in=1 (1+4)%12==5
- // len=4-(5%4)=3
-
- // |FF FF FF FF | XX XX XX XX |XX XX XX XX|
- // out=4 in=0 (0+4)%12==4
- // len=4-(4%4)=4
-
- len=STORAGE_POS_COUNT_SECTOR-(sutStorageFiFo.out%STORAGE_POS_COUNT_SECTOR); //|FF FF AA AA| AA AA...
- //算出当前out位置所处的Sector地址,对其格式化
- Sector=(STORAGE_POS_START_ADDR+sutStorageFiFo.out*STORAGE_POS_LEN)/4096;
- SPI_Flash_Erase_Sector(Sector);
- //对out进行移位
- sutStorageFiFo.out=(sutStorageFiFo.out+len)%STORAGE_POS_COUNT_TOTAL;
- sutStorageFiFo.len-=len;
- //printf("\r\nAutoRM[%d]\r\n",len);
- }
- //入队列
- //printf("Push[%d]\r\n",sutStorageFiFo.in);
- addr=STORAGE_POS_START_ADDR+sutStorageFiFo.in*STORAGE_POS_LEN;
- //SPI_Flash_Write((u8 *)pRecord,addr,STORAGE_POS_LEN);
- //先读出检查
- // SPI_Flash_Read((u8 *)&pos,addr,STORAGE_POS_LEN);
- // if(pos.flag!=0xff || pos.Mark != 0xffffffff){
- // printf("[%d]error!\r\n",sutStorageFiFo.in);
- // printf("flag=%X mark=%lX\r\n",pos.flag,pos.Mark);
- // }
- SPI_Flash_Write_NoCheck((u8 *)pRecord,addr,STORAGE_POS_LEN);
- sutStorageFiFo.in=(sutStorageFiFo.in+1)%STORAGE_POS_COUNT_TOTAL;
- sutStorageFiFo.len++;
- return 1;
- }
- /*
- 控制保存
- */
- void StorageCtrlSavePos(void)
- {
- char buf[20];
- static unsigned short SaveCt=0;
- SUT_POSITION pos;
- if(sutFotaPara.fotaStatus!=FOTA_END)return;
- if(!RTC_Effective()){
- SaveCt=sutDeviceConfig.SamplingInterval;
- return;
- }
- if(++SaveCt>=sutDeviceConfig.SamplingInterval){
- SaveCt=0;
- }else return;
- memset(&pos,0,sizeof(SUT_POSITION));
- pos.flag=STORAGE_POS_FLAG;
- pos.Mark=STORAGE_POS_MARK;
- RTC_Get(pos.Time);
- if(sutGpsInfo.isGpsValid)pos.Status.GNSS=1;
- else pos.Status.GNSS=0;
- pos.Status.ACC=1;
- pos.Status.BD=sutGpsInfo.isBDWork;
- pos.Status.GPS=sutGpsInfo.isGpsWork;
- pos.Status.West=sutGpsInfo.West;
- pos.Status.South=sutGpsInfo.South;
- pos.Latitude=sutGpsInfo.Latitude;//22620926;//114035268; //114.035268
- pos.Longitude=sutGpsInfo.Longitude; //114035268;//22620926; //22.620926
- pos.Speed=sutGpsInfo.Speed;//0;
- pos.Aspect=sutGpsInfo.Aspect;//123;
- pos.Altitude=sutGpsInfo.Altitude;
- pos.ExtraMsgId=0x3A;//水表项目固定0x3A
- pos.ExtraMsgLen=20;//水表项目暂时固定 20
-
- StorageFiFoPush(&pos);
- sprintf(buf,"SavePos %d\r\n",sutStorageFiFo.len);
- SlwTrace(DEBUG,buf);
- }
- /*
- 测试
- */
- void StorageFiFoTest(void)
- {
- #if 1
- int i,j;
- unsigned short r;
- SUT_POSITION pos;
- memset(&pos,0,sizeof(SUT_POSITION));
- pos.flag=STORAGE_POS_FLAG;
- pos.Mark=STORAGE_POS_MARK;
- if(StorageFiFoPop(&pos))i=pos.Latitude;
- else i=0;
- r=i;
- while(1){
- os_dly_wait(1);
- printf("\r\n<<[%03d] ",sutStorageFiFo.in);
- for(j=0;j<r%1000;j++){
- pos.Latitude=i++;
- printf("%5d ",pos.Latitude);
- StorageFiFoPush(&pos);
- }
- printf("\r\nlen=%d\r\n",sutStorageFiFo.len);
- printf("\r\n>>[%03d] ",sutStorageFiFo.out);
- for(j=0;j<10;j++){
- if(StorageFiFoPop(&pos)){
- printf("%5d ",pos.Latitude);
- }else{
- printf("<NULL ");
- }
- }
- r=r<<1;
- if(r&0x0001)r^=0x01;
- if(r&0x0020)r^=0x01;
- if(r&0x0080)r^=0x01;
- if(r&0x0400)r^=0x01;
- if(r&0x2000)r^=0x01;
- if(r&0x4000)r^=0x01;
- }
-
- #else
- int i,j;
- SUT_POSITION pos;
- memset(&pos,0,sizeof(SUT_POSITION));
- pos.flag=STORAGE_POS_FLAG;
- pos.Mark=STORAGE_POS_MARK;
- printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
- printf("+65\r\n");
- for(i=0;i<65;i++){//+65
- StorageFiFoPush(&pos);
- }
- printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
- printf("-63\r\n");
- for(i=0;i<63;i++){//-63
- StorageFiFoPop(&pos);
- }
- printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
- printf("+30\r\n");
- for(i=0;i<30;i++){//+30
- StorageFiFoPush(&pos);
- }
- printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
- printf("-40\r\n");
- for(i=0;i<40;i++){//-40
- StorageFiFoPop(&pos);
- }
- printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
- printf("+90\r\n");
- for(i=0;i<90;i++){//+90
- StorageFiFoPush(&pos);
- }
- printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
- printf("-80\r\n");
- for(i=0;i<80;i++){//-80
- StorageFiFoPop(&pos);
- }
- printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
-
- #endif
- }
- /*****************************************************************************/
|