Storage.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*****************************************************************************
  2. Flash.c
  3. *****************************************************************************/
  4. #define THIS_FILE_ID 20
  5. /* Includes ------------------------------------------------------------------*/
  6. #include "includes.h"
  7. SUT_STORAGE_FIFO sutStorageFiFo;
  8. void StorageFormat(void)
  9. {
  10. unsigned char buf[1];
  11. int addr;
  12. SlwTrace(DEBUG,"Flash Format!!\r\n");
  13. SPI_Flash_Erase_Chip();
  14. SaveDeviceConfigToFlash();
  15. sutStorageFiFo.in=0;
  16. sutStorageFiFo.out=0;
  17. sutStorageFiFo.len=0;
  18. for(addr=STORAGE_POS_START_ADDR;addr<STORAGE_POS_END_ADDR;addr+=64){
  19. SPI_Flash_Read(buf,addr,1);
  20. if(buf[0]!=0xff)break;
  21. }
  22. if(addr<STORAGE_POS_END_ADDR){
  23. SlwTrace(DEBUG,"Flash Format fail!!\r\n");
  24. }
  25. }
  26. /******************************************************************
  27. StorageInit
  28. *******************************************************************/
  29. void StorageFiFoInit(void)
  30. {
  31. unsigned char Format=0;
  32. unsigned char Flag;
  33. unsigned long addr=STORAGE_POS_START_ADDR;
  34. int i,F1,F2,N1,N2;
  35. char buf[20];
  36. //配置合法性判断
  37. if(sizeof(SUT_POSITION)!=STORAGE_POS_LEN){
  38. SlwTrace(DEBUG,"sizeof(SUT_POSITION)!=STORAGE_POS_LEN\r\n");
  39. while(1);
  40. }
  41. //printf("\r\nFIFO Size=%d\r\n",STORAGE_POS_COUNT_TOTAL);
  42. F1=-1;//第一个FF位置
  43. F2=-1;//最后一个FF位置
  44. N1=-1;//第一个非FF位置
  45. N2=-1;//最后一个非FF位置
  46. i=0;
  47. while(addr<STORAGE_POS_END_ADDR){
  48. SPI_Flash_Read(&Flag,addr,1);
  49. if(Flag==0xFF){
  50. if(F1==-1)F1=i;
  51. F2=i;
  52. }else if(Flag==STORAGE_POS_FLAG){
  53. if(N1==-1)N1=i;
  54. N2=i;
  55. }else{
  56. Format=1;
  57. }
  58. i++;
  59. addr+=sizeof(SUT_POSITION);
  60. }
  61. //
  62. if(Format){
  63. StorageFormat();
  64. return;
  65. }
  66. /*
  67. XX XX XX XX XX:F1=-1 if(F1=-1 || F2=-1)禁止出现,需要重新格式化
  68. FF FF FF FF FF:N1=-1 if(N1=-1 || N2=-1)空
  69. XX XX FF FF FF:F1=2 F2=4 N1=0 N2=1 if(F2=max && N1=0){In=F1 Out=N1 len=F1}
  70. 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}
  71. 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}
  72. 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}
  73. */
  74. int max=STORAGE_POS_COUNT_TOTAL-1;
  75. if(F1 == -1 || F2 == -1){//非法
  76. SlwTrace(DEBUG,"STORAGE is Invalid[2]!\r\n");
  77. StorageFormat();
  78. }else if(N1 == -1 || N2 == -1){//空
  79. sutStorageFiFo.in=0;
  80. sutStorageFiFo.out=0;
  81. sutStorageFiFo.len=0;
  82. }else if(F2==max && N1==0){//In=F1 Out=N1 len=F1
  83. sutStorageFiFo.in=F1;
  84. sutStorageFiFo.out=N1;
  85. sutStorageFiFo.len=F1;
  86. }else if(F1==0 && N2==max){//In=F1 Out=N1 len=max-N1
  87. sutStorageFiFo.in=F1;
  88. sutStorageFiFo.out=N1;
  89. sutStorageFiFo.len=max-N1;
  90. }else if(F1==0 && F2==max){//In=N2+1 Out=N1 len=N2-N1+1
  91. sutStorageFiFo.in=N2+1;
  92. sutStorageFiFo.out=N1;
  93. sutStorageFiFo.len=N2-N1+1;
  94. }else if(N1==0 && N2 == max){//In=F1 Out=F2+1 len=max-F2+F1
  95. sutStorageFiFo.in=F1;
  96. sutStorageFiFo.out=F2+1;
  97. sutStorageFiFo.len=max-F2+F1;
  98. }else{//不存在这种情况
  99. SlwTrace(DEBUG,"STORAGE is Invalid[3]!\r\n");
  100. StorageFormat();
  101. }
  102. //printf("F1=%d F2=%d N1=%d N2=%d\r\n",F1,F2,N1,N2);
  103. //printf("FiFo.in=%d\r\nFiFo.out=%d\r\nFiFo.len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  104. }
  105. extern u8 SPI_FLASH_BUF[];
  106. /******************************************************************
  107. 从FIFO中读取一条SUT_POSITION记录
  108. 返回值: 0--失败 记录无效 1--成功
  109. *******************************************************************/
  110. int StorageFiFoPop(SUT_POSITION *pPos)
  111. {
  112. int sector;
  113. int i;
  114. int addr;
  115. //判断是否为空
  116. if(sutStorageFiFo.out == sutStorageFiFo.in){
  117. SlwTrace(DEBUG,"FIFO is Empty!\r\n");
  118. return 0;
  119. }
  120. //非空方可读值
  121. addr=STORAGE_POS_START_ADDR+sutStorageFiFo.out*STORAGE_POS_LEN;
  122. SPI_Flash_Read((u8 *)pPos,addr,STORAGE_POS_LEN);
  123. if(pPos->flag!=STORAGE_POS_FLAG || pPos->Mark!=STORAGE_POS_MARK){
  124. //这种情况里应不存在,存在说明发生异常!
  125. //异常原因可能是Push写入时写到一半突然掉电,此时应该修正之
  126. SlwTrace(DEBUG,"StorageFiFoPOP Exception!\r\n");
  127. //printf("[%d]flag=%02X mark=%08lX\r\n",sutStorageFiFo.out,pPos->flag,pPos->Mark);
  128. memset((u8 *)pPos,0xff,STORAGE_POS_LEN);
  129. SPI_Flash_Write((u8 *)pPos,addr,STORAGE_POS_LEN);
  130. sutStorageFiFo.out=(sutStorageFiFo.out+1)%STORAGE_POS_COUNT_TOTAL;
  131. sutStorageFiFo.len--;
  132. return 0;
  133. }
  134. //移位
  135. sutStorageFiFo.out=(sutStorageFiFo.out+1)%STORAGE_POS_COUNT_TOTAL;
  136. sutStorageFiFo.len--;
  137. //如果移动到新的SECTOR,并且in不在前一区,则将前一区擦除,下次重启才会刷新out
  138. if(sutStorageFiFo.out%STORAGE_POS_COUNT_SECTOR==0){
  139. //获取out的前一区
  140. sector=sutStorageFiFo.out/STORAGE_POS_COUNT_SECTOR;
  141. if(sector>0)sector--;
  142. else sector=STORAGE_POS_COUNT_TOTAL/STORAGE_POS_COUNT_SECTOR-1;//最后一个扇区
  143. // out的前一个扇区 与 in所在扇区 不一样,才允许擦除
  144. if(sector!=(sutStorageFiFo.in/STORAGE_POS_COUNT_SECTOR)){
  145. sector+=STORAGE_POS_START_ADDR/4096;
  146. SPI_Flash_Erase_Sector(sector);
  147. // printf("Erase[%d]\r\n",sector);
  148. // SPI_Flash_Read(SPI_FLASH_BUF,sector*4096,4096);//读出整个扇区的内容
  149. // for(i=0;i<4096;i++){
  150. // if(SPI_FLASH_BUF[i]!=0xFF)break;
  151. // }
  152. // if(i<4096)printf("Erase Fail!\r\n");
  153. }
  154. }
  155. return 1;
  156. }
  157. /******************************************************************
  158. 存储Pos记录到FIFO中
  159. 如果已满,自动抛弃最早的数据
  160. *******************************************************************/
  161. int StorageFiFoPush(SUT_POSITION *pRecord)
  162. {
  163. SUT_POSITION pos;
  164. int Sector;
  165. int len;
  166. int addr;
  167. //预留64个元素,少于64则认为满,移除最早的数据,每次移除N个,N取决于当前out所在sector占用元素个数
  168. if (STORAGE_POS_COUNT_TOTAL-sutStorageFiFo.len<64){
  169. //算出当前out位置所在的Sector有len个元素,格式化这个Sector后需要将out移len位
  170. // |FF FF FF XX | XX XX XX XX |XX XX XX FF|
  171. // out=3 in=11 (11+4)%12==3
  172. // len=4-(3%4)=1
  173. // |XX FF FF FF | FF XX XX XX |XX XX XX XX|
  174. // out=5 in=1 (1+4)%12==5
  175. // len=4-(5%4)=3
  176. // |FF FF FF FF | XX XX XX XX |XX XX XX XX|
  177. // out=4 in=0 (0+4)%12==4
  178. // len=4-(4%4)=4
  179. len=STORAGE_POS_COUNT_SECTOR-(sutStorageFiFo.out%STORAGE_POS_COUNT_SECTOR); //|FF FF AA AA| AA AA...
  180. //算出当前out位置所处的Sector地址,对其格式化
  181. Sector=(STORAGE_POS_START_ADDR+sutStorageFiFo.out*STORAGE_POS_LEN)/4096;
  182. SPI_Flash_Erase_Sector(Sector);
  183. //对out进行移位
  184. sutStorageFiFo.out=(sutStorageFiFo.out+len)%STORAGE_POS_COUNT_TOTAL;
  185. sutStorageFiFo.len-=len;
  186. //printf("\r\nAutoRM[%d]\r\n",len);
  187. }
  188. //入队列
  189. //printf("Push[%d]\r\n",sutStorageFiFo.in);
  190. addr=STORAGE_POS_START_ADDR+sutStorageFiFo.in*STORAGE_POS_LEN;
  191. //SPI_Flash_Write((u8 *)pRecord,addr,STORAGE_POS_LEN);
  192. //先读出检查
  193. // SPI_Flash_Read((u8 *)&pos,addr,STORAGE_POS_LEN);
  194. // if(pos.flag!=0xff || pos.Mark != 0xffffffff){
  195. // printf("[%d]error!\r\n",sutStorageFiFo.in);
  196. // printf("flag=%X mark=%lX\r\n",pos.flag,pos.Mark);
  197. // }
  198. SPI_Flash_Write_NoCheck((u8 *)pRecord,addr,STORAGE_POS_LEN);
  199. sutStorageFiFo.in=(sutStorageFiFo.in+1)%STORAGE_POS_COUNT_TOTAL;
  200. sutStorageFiFo.len++;
  201. return 1;
  202. }
  203. /*
  204. 控制保存
  205. */
  206. void StorageCtrlSavePos(void)
  207. {
  208. char buf[20];
  209. static unsigned short SaveCt=0;
  210. SUT_POSITION pos;
  211. if(sutFotaPara.fotaStatus!=FOTA_END)return;
  212. if(!RTC_Effective()){
  213. SaveCt=sutDeviceConfig.SamplingInterval;
  214. return;
  215. }
  216. if(++SaveCt>=sutDeviceConfig.SamplingInterval){
  217. SaveCt=0;
  218. }else return;
  219. memset(&pos,0,sizeof(SUT_POSITION));
  220. pos.flag=STORAGE_POS_FLAG;
  221. pos.Mark=STORAGE_POS_MARK;
  222. RTC_Get(pos.Time);
  223. if(sutGpsInfo.isGpsValid)pos.Status.GNSS=1;
  224. else pos.Status.GNSS=0;
  225. pos.Status.ACC=1;
  226. pos.Status.BD=sutGpsInfo.isBDWork;
  227. pos.Status.GPS=sutGpsInfo.isGpsWork;
  228. pos.Status.West=sutGpsInfo.West;
  229. pos.Status.South=sutGpsInfo.South;
  230. pos.Latitude=sutGpsInfo.Latitude;//22620926;//114035268; //114.035268
  231. pos.Longitude=sutGpsInfo.Longitude; //114035268;//22620926; //22.620926
  232. pos.Speed=sutGpsInfo.Speed;//0;
  233. pos.Aspect=sutGpsInfo.Aspect;//123;
  234. pos.Altitude=sutGpsInfo.Altitude;
  235. pos.ExtraMsgId=0x3A;//水表项目固定0x3A
  236. pos.ExtraMsgLen=20;//水表项目暂时固定 20
  237. StorageFiFoPush(&pos);
  238. sprintf(buf,"SavePos %d\r\n",sutStorageFiFo.len);
  239. SlwTrace(DEBUG,buf);
  240. }
  241. /*
  242. 测试
  243. */
  244. void StorageFiFoTest(void)
  245. {
  246. #if 1
  247. int i,j;
  248. unsigned short r;
  249. SUT_POSITION pos;
  250. memset(&pos,0,sizeof(SUT_POSITION));
  251. pos.flag=STORAGE_POS_FLAG;
  252. pos.Mark=STORAGE_POS_MARK;
  253. if(StorageFiFoPop(&pos))i=pos.Latitude;
  254. else i=0;
  255. r=i;
  256. while(1){
  257. os_dly_wait(1);
  258. printf("\r\n<<[%03d] ",sutStorageFiFo.in);
  259. for(j=0;j<r%1000;j++){
  260. pos.Latitude=i++;
  261. printf("%5d ",pos.Latitude);
  262. StorageFiFoPush(&pos);
  263. }
  264. printf("\r\nlen=%d\r\n",sutStorageFiFo.len);
  265. printf("\r\n>>[%03d] ",sutStorageFiFo.out);
  266. for(j=0;j<10;j++){
  267. if(StorageFiFoPop(&pos)){
  268. printf("%5d ",pos.Latitude);
  269. }else{
  270. printf("<NULL ");
  271. }
  272. }
  273. r=r<<1;
  274. if(r&0x0001)r^=0x01;
  275. if(r&0x0020)r^=0x01;
  276. if(r&0x0080)r^=0x01;
  277. if(r&0x0400)r^=0x01;
  278. if(r&0x2000)r^=0x01;
  279. if(r&0x4000)r^=0x01;
  280. }
  281. #else
  282. int i,j;
  283. SUT_POSITION pos;
  284. memset(&pos,0,sizeof(SUT_POSITION));
  285. pos.flag=STORAGE_POS_FLAG;
  286. pos.Mark=STORAGE_POS_MARK;
  287. printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  288. printf("+65\r\n");
  289. for(i=0;i<65;i++){//+65
  290. StorageFiFoPush(&pos);
  291. }
  292. printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  293. printf("-63\r\n");
  294. for(i=0;i<63;i++){//-63
  295. StorageFiFoPop(&pos);
  296. }
  297. printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  298. printf("+30\r\n");
  299. for(i=0;i<30;i++){//+30
  300. StorageFiFoPush(&pos);
  301. }
  302. printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  303. printf("-40\r\n");
  304. for(i=0;i<40;i++){//-40
  305. StorageFiFoPop(&pos);
  306. }
  307. printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  308. printf("+90\r\n");
  309. for(i=0;i<90;i++){//+90
  310. StorageFiFoPush(&pos);
  311. }
  312. printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  313. printf("-80\r\n");
  314. for(i=0;i<80;i++){//-80
  315. StorageFiFoPop(&pos);
  316. }
  317. printf("in=%d out=%d len=%d\r\n",sutStorageFiFo.in,sutStorageFiFo.out,sutStorageFiFo.len);
  318. #endif
  319. }
  320. /*****************************************************************************/