DownFiles.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*****************************************************************************
  2. DownFiles.C
  3. *****************************************************************************/
  4. #include "includes.h"
  5. #include "DownFiles.h"
  6. #include <stm32f10x.h>
  7. #include "IAP.h"
  8. //static SUT_FILE_LIST sutFileList;//临时文件列表 只用于传输文件用,注意不要与FileSys.c定义的g_sutFilesList混淆!
  9. static uint16_t sFileIndex; //当前传输的文件在文件列表中的索引位置
  10. static uint32_t sFileDataOffset; //当前传输的文件偏移
  11. static uint32_t sFileDataLength; //当前传输的文件长度
  12. /*****************************************************************************************
  13. MakePCTFlistReq
  14. 生成请求文件列表数据
  15. ******************************************************************************************/
  16. int MakePctflistReq(char *txbuf)
  17. {
  18. SUT_DF_LIST_REQ *pDFListReq;
  19. pDFListReq=(SUT_DF_LIST_REQ *)txbuf;
  20. memset(pDFListReq,0,sizeof(SUT_DF_LIST_REQ));
  21. pDFListReq->Head.magic=PCTA_MAGIC;
  22. pDFListReq->Head.protocol=UPDATE_PROTOCOL_RFILE;
  23. pDFListReq->Head.code=DOWNLOAD_FILE_LIST_REQ;
  24. pDFListReq->Head.tid=0;
  25. pDFListReq->Head.count=sizeof(SUT_DF_LIST_REQ)-sizeof(SUT_DF_HEAD);
  26. pDFListReq->FileCountMax=FILE_COUNT_MAX;
  27. pDFListReq->FileNameLenMax=FILE_NAME_LEN_MAX;
  28. pDFListReq->FileAllDataLenMax=FILE_ALL_DATA_LEN_MAX;
  29. return sizeof(SUT_DF_LIST_REQ);
  30. }
  31. /*****************************************************************************************
  32. DFGetFileList
  33. 请求文件列表
  34. ******************************************************************************************/
  35. void DFGetFileList(void)
  36. {
  37. int len;
  38. len=MakePctflistReq((char *)TxBuffer1);
  39. Uart1Send((char *)TxBuffer1,len);
  40. }
  41. /*****************************************************************************************
  42. MakePCTFlistReq
  43. 生成请求文件列表数据
  44. ******************************************************************************************/
  45. int MakePctfFileDataReq(char *txbuf,uint16_t FileIndex,uint32_t offset,uint32_t length)
  46. {
  47. SUT_DF_DATA_REQ *pFileDataReq;
  48. pFileDataReq=(SUT_DF_DATA_REQ *)txbuf;
  49. memset(pFileDataReq,0,sizeof(SUT_DF_DATA_REQ));
  50. pFileDataReq->Head.magic=PCTA_MAGIC;
  51. pFileDataReq->Head.protocol=UPDATE_PROTOCOL_RFILE;
  52. pFileDataReq->Head.code=DOWNLOAD_FILE_DATA_REQ;
  53. pFileDataReq->Head.tid=0;
  54. pFileDataReq->Head.count=sizeof(SUT_DF_DATA_REQ)-sizeof(SUT_DF_HEAD);
  55. pFileDataReq->FileIndex=FileIndex;
  56. memcpy(&pFileDataReq->FileInfo,&g_sutFilesList.FileInfo[FileIndex],sizeof(SUT_FILE_INFO));
  57. pFileDataReq->length=length;
  58. pFileDataReq->offset=offset;
  59. return sizeof(SUT_DF_DATA_REQ);
  60. }
  61. /*****************************************************************************************
  62. DFGetFileData
  63. 请求文件数据
  64. ******************************************************************************************/
  65. void DFGetFileData(uint16_t FileIndex,uint32_t offset,uint32_t length)
  66. {
  67. int len;
  68. len=MakePctfFileDataReq((char *)TxBuffer1,FileIndex,offset,length);
  69. Uart1Send((char *)TxBuffer1,len);
  70. }
  71. /************************************************************************************
  72. *找出第一个不同的文件索引
  73. *************************************************************************************/
  74. int FindFirstDiffIndex(SUT_FILE_LIST *FileList)
  75. {
  76. int i;
  77. int j;
  78. for(i=0;i<g_sutFilesList.FileCount;i++){
  79. if(g_sutFilesList.FileInfo[i].FileLen!=FileList->FileInfo[i].FileLen)break;
  80. for(j=0;j<16;j++){
  81. if(g_sutFilesList.FileInfo[i].FileMD5[j]!=FileList->FileInfo[i].FileMD5[j])break;
  82. }
  83. if(j!=16)break;
  84. if(0!=strcmp(g_sutFilesList.FileInfo[i].FileName,FileList->FileInfo[i].FileName))break;
  85. }
  86. return i;
  87. }
  88. /************************************************************************************
  89. IapRecvMsgHandle
  90. 处理接收到的数据
  91. *************************************************************************************/
  92. int DFRecvMsgHandle(unsigned char *pData, unsigned short DataLen)
  93. {
  94. int i;
  95. unsigned short crc,CRC16;
  96. unsigned short ReadBuf[4];
  97. char buf[200];
  98. uint32_t addr,len,offset;
  99. unsigned char code;
  100. unsigned short count;
  101. SUT_DF_HEAD *pHeader;
  102. SUT_DF_LIST_RSP *pListRsp;
  103. SUT_DF_DATA_RSP *pDataRsp;
  104. pHeader=(SUT_DF_HEAD *)pData;
  105. if(pHeader->magic != PCTA_MAGIC)return -1;
  106. if(pHeader->protocol != UPDATE_PROTOCOL_RFILE )return -2;
  107. code= pHeader->code;
  108. count= pHeader->count;
  109. if(code==DOWNLOAD_FILE_LIST_REQ){//PC响应文件列表
  110. if(count!=(sizeof(SUT_DF_LIST_RSP)-sizeof(SUT_DF_HEAD)))return -4;
  111. pListRsp= (SUT_DF_LIST_RSP *)pData;
  112. CRC16=pListRsp->FileListCRC;
  113. crc=crc16_calc(0,(uint8_t *)&pListRsp->FileList,sizeof(SUT_FILE_LIST));
  114. if(crc!=CRC16)return -5;
  115. if(pListRsp->FileList.FileCount==0)return 0;//文件个数为0,不用更新,直接完成
  116. #ifdef DOWNLOAD_DIFFERENT_FILE_ONLY //跳过前面相同的文件,只从第一个不相同的文件开始更新
  117. sFileIndex=FindFirstDiffIndex(&pListRsp->FileList);//即将更新文件的索引
  118. if(sFileIndex >= pListRsp->FileList.FileCount){//没有需要更新的,结束
  119. g_sutFilesList.FileCount=pListRsp->FileList.FileCount;
  120. g_sutFilesList.Mark=STORAGE_MARK;
  121. FileSysSaveIndex();//保存索引
  122. return 0;
  123. }
  124. g_sutFilesList.FileCount=pListRsp->FileList.FileCount;
  125. memcpy(&g_sutFilesList.FileInfo[sFileIndex],&pListRsp->FileList.FileInfo[sFileIndex],(pListRsp->FileList.FileCount-sFileIndex)*sizeof(SUT_FILE_INFO));
  126. #else //不判断是否文件相同都更新
  127. sFileIndex=0;
  128. memcpy(&g_sutFilesList,&pListRsp->FileList,sizeof(SUT_FILE_LIST));
  129. #endif
  130. sFileDataOffset=0;//即将更新文件数据的位置
  131. sprintf(buf,"RFile Count=%lu\r\n",g_sutFilesList.FileCount);
  132. IapTrace(buf);
  133. sprintf(buf,"RFile[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
  134. IapTrace(buf);
  135. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  136. return 1;
  137. }else if(code == DOWNLOAD_FILE_DATA_REQ){//PC响应文件数据申请
  138. pDataRsp = (SUT_DF_DATA_RSP*)pData;
  139. if(pDataRsp->FileInfo.FileLen!=g_sutFilesList.FileInfo[pDataRsp->FileIndex].FileLen \
  140. || pDataRsp->offset != sFileDataOffset || sFileIndex!=pDataRsp->FileIndex){//文件长度or 索引 or 偏移 不对?重新更新
  141. IapTrace("File Length or Offset error!ReDO!\r\n");
  142. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  143. return -6;
  144. }
  145. len=pDataRsp->length;
  146. len-=2;//实际数据长度应去掉2字节的CRC
  147. //CRC校验
  148. CRC16=crc16_calc(0,pDataRsp->data,len);
  149. crc=((unsigned short)pDataRsp->data[len+1]&0xff)<<8;
  150. crc+=(unsigned short)pDataRsp->data[len]&0xff;
  151. if(crc!=CRC16){
  152. //校验错误,申请重新下载
  153. IapTrace("Check CRC error!ReDO!\r\n");
  154. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  155. return -8;
  156. }
  157. //==CRC校验成功,更新FLASH ===
  158. sFlash_Write(pDataRsp->data,g_sutFilesList.FileInfo[sFileIndex].FileAddr+sFileDataOffset,len);
  159. if((len+sFileDataOffset)>=pDataRsp->FileInfo.FileLen){//完成当前文件下载
  160. if(sFileIndex==(g_sutFilesList.FileCount-1)){//判断所有文件是否下载完毕?
  161. //所有文件下载完毕,结束
  162. g_sutFilesList.Mark=STORAGE_MARK;
  163. FileSysSaveIndex();//保存索引
  164. return 0;
  165. }else{
  166. //校验本文件的MD5码,看是否正确,如不正确则重新下载本文件,如正确则切换下一文件
  167. if(0==FileCheckMD5(sFileIndex)){//MD5错误
  168. //重新下载
  169. sFileDataOffset=0;//即将更新文件数据的位置
  170. sprintf(buf,"RFile[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
  171. IapTrace(buf);
  172. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  173. }else{//MD5正确
  174. //启动下一文件传输
  175. sFileIndex++;
  176. //下一个文件地址为上一个文件地址加上一个文件的长度
  177. g_sutFilesList.FileInfo[sFileIndex].FileAddr=g_sutFilesList.FileInfo[sFileIndex-1].FileAddr+g_sutFilesList.FileInfo[sFileIndex-1].FileLen;
  178. sFileDataOffset=0;//即将更新文件数据的位置
  179. sprintf(buf,"RFile[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
  180. IapTrace(buf);
  181. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  182. }
  183. }
  184. }else{
  185. //本文件传输未结束,启动下一包下载
  186. sFileDataOffset+=len;
  187. sprintf(buf,"offset=%d\r\n",sFileDataOffset);
  188. IapTrace(buf);
  189. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  190. }
  191. return 2;
  192. }
  193. }