ProductPara.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /********************************************************************************
  2. * File Name: ProductPara.c
  3. * Function Describe:
  4. * Explain:
  5. * Writer: ShiLiangWen
  6. * Date: 2015-7-6
  7. *******************************************************************************/
  8. #define THIS_FILE_ID 6
  9. //-----------------------------------------------------------------------------
  10. #include "includes.h"
  11. SUT_PRODUCT_PARA sutProductPara;
  12. //读取指定地址的半字(16位数据)
  13. //faddr:读地址(此地址必须为2的倍数!!)
  14. //返回值:对应数据.
  15. u16 STMFLASH_ReadHalfWord(u32 faddr)
  16. {
  17. return *(vu16*)faddr;
  18. }
  19. //从指定地址开始读出指定长度的数据
  20. //ReadAddr:起始地址
  21. //pBuffer:数据指针
  22. //NumToWrite:半字(16位)数
  23. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
  24. {
  25. u16 i;
  26. for(i=0;i<NumToRead;i++)
  27. {
  28. pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
  29. ReadAddr+=2;//偏移2个字节.
  30. }
  31. }
  32. #define USER_FLASH_BLOCK 2048
  33. /**********************************************************************************************************
  34. *写页数据,擦除整页2048字节,并写入Byte数据,数据可少于2048Btye,但必须是偶数。
  35. ************************************************************************************************************/
  36. void WritePageData(unsigned long WriteAddr,unsigned char *pData,unsigned short DataLen)
  37. {
  38. unsigned short i;
  39. unsigned short temp;
  40. unsigned short tempLen;
  41. SUTDL dl;
  42. FLASH_EraseInitTypeDef eraceDef;
  43. uint32_t pageErr=0;
  44. uint16_t errStatus;
  45. char buf[30];
  46. if(WriteAddr<FLASH_BASE || (WriteAddr>=(FLASH_BASE+1024*DEVICE_FLASH_SIZE)))return;//非法地址
  47. if(WriteAddr&0x0000003ff)return;//非页首地址
  48. if(HAL_OK != HAL_FLASH_Unlock()){ //解锁
  49. logTrace("Unlock err",1);
  50. return;
  51. }
  52. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR );
  53. eraceDef.NbPages=USER_FLASH_BLOCK/FLASH_PAGE_SIZE;//擦除多少页
  54. eraceDef.PageAddress=WriteAddr;
  55. eraceDef.TypeErase=FLASH_TYPEERASE_PAGES;//按页擦除
  56. errStatus=HAL_FLASHEx_Erase(&eraceDef, &pageErr);
  57. if(errStatus != HAL_OK){
  58. sprintf(buf, "EraceErr:%d,%08x", errStatus, pageErr);
  59. logTrace(buf,1);
  60. HAL_FLASH_Lock();
  61. return;
  62. }
  63. //写入
  64. temp = DataLen % 4;
  65. if(temp) tempLen = DataLen + (4-temp);
  66. else tempLen = DataLen;
  67. if(tempLen >= USER_FLASH_BLOCK) tempLen=USER_FLASH_BLOCK;
  68. for(i = 0; i < tempLen; i+=4){
  69. dl.Data.ucData.b1=pData[i];
  70. dl.Data.ucData.b2=pData[i+1];
  71. dl.Data.ucData.b3=pData[i+2];
  72. dl.Data.ucData.b4=pData[i+3];
  73. HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr+i,dl.Data.ulData); //TYPEPROGRAM_WORD
  74. }
  75. HAL_FLASH_Lock();//上锁
  76. }
  77. /**********************************************************************************************************
  78. ************************************************************************************************************/
  79. void ReadFlashData(unsigned long ReadAddr,unsigned char *pData,unsigned short DataLen)
  80. {
  81. int i,j;
  82. unsigned short temp;
  83. j=0;
  84. for(i=0;i<DataLen;i+=2){
  85. temp=STMFLASH_ReadHalfWord(ReadAddr+i);
  86. pData[j++]=(unsigned char)(temp&0xff);
  87. pData[j++]=(temp>>8)&0xff;
  88. }
  89. }
  90. void printfATHCODE(void)
  91. {
  92. char buf[3], buf2[50];
  93. snprintf(buf2, sizeof(buf2), "index=%d,time=%d",sutProductPara.m_GPS_TimeIndex,sutGpsInfo.GPS_UploadTime);
  94. logTrace(buf2,1);
  95. }
  96. /**********************************************************************************************************
  97. SaveProductParaToFlash
  98. ************************************************************************************************************/
  99. void SaveProductParaToFlash(char *recoreInfo)
  100. {
  101. uint32_t tick;
  102. char recBuf[60];
  103. PWR_EN_HIGH;
  104. if(sutProductPara.takeNoteFlag)
  105. {
  106. //记录保存相关信息到SPI FLASH
  107. // tick=RTC_GetCounter();
  108. //时间 位置 机型 序列号
  109. snprintf(recBuf, sizeof(recBuf), "[rec]%d,%s,%s,%08x|\r\n",tick,recoreInfo,sutProductPara.ProductName,sutProductPara.PSN);
  110. sFlash_Write(recBuf, RECORD_INFO_ADDRESS, sizeof(recBuf));
  111. logTrace(recBuf, 0);
  112. }
  113. ////////////////////////
  114. WritePageData(MAIN_CONFIG_ADDR,(unsigned char *)&sutProductPara,sizeof(SUT_PRODUCT_PARA));
  115. DelayMs(100);
  116. WritePageData(BACKUP_CONFIG_ADDR,(unsigned char *)&sutProductPara,sizeof(SUT_PRODUCT_PARA));
  117. PWR_EN_LOW;
  118. }
  119. /********************************************************************
  120. *SaveParaToFlash
  121. 将sutNetPara重要参数保存到FLASH
  122. *********************************************************************/
  123. //主参数区:127K MAIN_CONFIG_ADDR
  124. //备份参数:126K BACKUP_CONFIG_ADDR
  125. //1、使用时主要使用主参数区参数
  126. //2、每次更新主参数区时,一并更新备份参数区
  127. //3、开机后读取主参数区以及备份区
  128. //3.1、如果两者的NAME和PSN都全为FF,则认为是第一次启动,初始化所有主备参数;
  129. //3.2、非3.1的情况下,如果主区的NAME不为PRODUCT_NAME(第一次初始化时设置)时,或者主区的PSN为非法值(1000000<PSN<4200000000)时
  130. // 认为参数区异常,如果此时的备份区的NAME不为PRODUCT_NAME,或者备份区PSN为非法值时,则执行刷新操作,即初始化所有主备参数
  131. // 否则copy备份区到主区,然后使用此时主区参数运行
  132. //3.3、如果主备区都合法,但不一致,以主区为准
  133. #define MIN_PSN_NUM 1000000
  134. #define MAX_PSN_NUM 4200000000
  135. void ReadProductParaFromFlash(void)
  136. {
  137. SUT_PRODUCT_PARA backupPara;
  138. char mainLogic,backupLogic;
  139. char saveType;
  140. char buf[40];
  141. IWDG_ReloadCounter();
  142. saveType=0;//不用保存参数
  143. //1、读取主区参数
  144. ReadFlashData(MAIN_CONFIG_ADDR,(unsigned char *)&sutProductPara,sizeof(SUT_PRODUCT_PARA));
  145. //2、读取备份参数
  146. ReadFlashData(BACKUP_CONFIG_ADDR,(unsigned char *)&backupPara,sizeof(SUT_PRODUCT_PARA));
  147. //3.1、检测主区合法性
  148. mainLogic=0;//设置不合法
  149. if(0==strcmp(sutProductPara.ProductName,PRODUCT_NAME) && //产品名字相同
  150. (sutProductPara.PSN >= MIN_PSN_NUM && sutProductPara.PSN <= MAX_PSN_NUM))//PSN符合范围
  151. {
  152. mainLogic=1;//主区参数合法
  153. }
  154. //3.2、检测备份合法性
  155. backupLogic=0;//设置不合法
  156. if(0==strcmp(backupPara.ProductName,PRODUCT_NAME) && //产品名字相同
  157. (backupPara.PSN >= MIN_PSN_NUM && backupPara.PSN <= MAX_PSN_NUM)) //PSN符合范围
  158. {
  159. backupLogic=1;//备份参数合法
  160. }
  161. //3.3、如果主备都不合法,则进行刷机
  162. if(0==mainLogic && 0==backupLogic)
  163. {
  164. logTrace("[1]Rst all para!",1);
  165. memset((unsigned char *)&sutProductPara,0,sizeof(SUT_PRODUCT_PARA));
  166. sutProductPara.McuFlag =MCU_FLAG; //MCU标识
  167. sutProductPara.IapFlag =0x88; //IAP标志 0x00--无应用程序 0x55--需要空中升级 0x88--正常运行应用程序
  168. sutProductPara.ModemType =MODEM_TYPE;
  169. sutProductPara.GpsType =GPS_TYPE;
  170. sutProductPara.FoTaServerSel=0;//FOTA服务器选择 0--POC Server 1--GPS Server
  171. strcpy(sutProductPara.ProductName,PRODUCT_NAME);
  172. sutProductPara.ProductVersion=PRODUCT_VERSION;
  173. sutProductPara.PocPort =POC_SERVER_PORT;
  174. sutProductPara.GpsPort =TSGPS_SERVER_PORT;
  175. sutProductPara.PSN =MIN_PSN_NUM;//未写号情况下PSN为150000000
  176. strcpy(sutProductPara.Keysound,KEY_SOUND);
  177. sutProductPara.g_net=0; //网模自动
  178. sutProductPara.ServerSelIndex=0; /////////////////////////////////
  179. sutProductPara.SoundMode=0;
  180. strcpy(sutProductPara.domain,DOMAIN_SERVER);
  181. strcpy(sutProductPara.PIP,POC_SERVER_IP);
  182. strcpy(sutProductPara.GIP,GPS_SERVER_IP);
  183. strcpy(sutProductPara.MEID,"00000000000000"); //14位 最后一位为0
  184. strcpy(sutProductPara.APNApn, APN_APN);
  185. strcpy(sutProductPara.APNName,APN_NAME);
  186. strcpy(sutProductPara.APNPass,APN_PASSWORD);
  187. sutProductPara.m_GPS_TimeIndex = DEFAULT_GPS_SEND_TIME_INDEX;
  188. ///////////////////////////////////////////
  189. strcpy(sutProductPara.APNApn, APN_APN);
  190. sutProductPara.APNIndex=0;//默认使用资源文件中的第一个APN
  191. //然后保存参数
  192. saveType=1;//两个区都保存为:sutProductPara
  193. }
  194. //3.4、如果主合法,备非法,主copy到备
  195. else if(1==mainLogic && 0==backupLogic)
  196. {
  197. logTrace("[2]main-->backup",1);
  198. saveType=2;//仅保存:backupPara
  199. }
  200. //3.5、如果主非法,备合法,备copy到主
  201. else if(0==mainLogic && 1==backupLogic)
  202. {
  203. logTrace("[3]backup-->main",1);
  204. memcpy((unsigned char *)&sutProductPara, (unsigned char *)&backupPara, sizeof(SUT_PRODUCT_PARA));
  205. saveType=3;//仅保存:sutProductPara
  206. }
  207. //3.6、如果主备都合法,但不一致,主copy到备
  208. else if(1==mainLogic && 1==backupLogic && sutProductPara.PSN != backupPara.PSN)
  209. {
  210. logTrace("[4]main-->backup",1);
  211. saveType=2;//仅保存:backupPara
  212. }
  213. //3.7、如果主备都合法,但一致,不做任何操作
  214. else
  215. {
  216. logTrace("[5]LogicOk",1);
  217. //检测是否版本发生了变更
  218. if(sutProductPara.ProductVersion != PRODUCT_VERSION)
  219. {//版本号发生了变化
  220. sutProductPara.ServerSelIndex=0;
  221. if(sutProductPara.APNIndex>3) sutProductPara.APNIndex=0;//默认使用资源文件中的第一个APN
  222. sutProductPara.ProductVersion=PRODUCT_VERSION;
  223. strcpy(sutProductPara.domain,DOMAIN_SERVER);
  224. strcpy(sutProductPara.Keysound,KEY_SOUND);
  225. sutProductPara.SoundMode=0;
  226. //1.1 GPS upload time --> 15 seconds
  227. sutProductPara.m_GPS_TimeIndex = DEFAULT_GPS_SEND_TIME_INDEX;//恢复GPS默认上传时间
  228. //2.2 LCD back light no need to set here, it will reset in maintask init if LCD file changed
  229. //如检测集群与配置服参数是否有效,使得以前版本无此功能,然后升级版本后能生效此功能
  230. saveType=1;//两个区都保存为:sutProductPara
  231. logTrace("[6]Ver-Changed",1);
  232. }
  233. }
  234. //检测GPS上传定位参数索引是否合法
  235. if(sutProductPara.m_GPS_TimeIndex >= sizeof(GPS_TimeTable))
  236. {
  237. sutProductPara.m_GPS_TimeIndex = DEFAULT_GPS_SEND_TIME_INDEX;
  238. saveType=1;
  239. }
  240. GpsTimeUpdate();
  241. //执行参数保存
  242. switch(saveType)
  243. {
  244. case 1://两个区都保存为:sutProductPara
  245. case 2://仅保存:backupPara
  246. case 3://仅保存:sutProductPara
  247. snprintf(buf, sizeof(buf), "READ_PARA_%d",saveType);
  248. SaveProductParaToFlash(buf);
  249. break;
  250. default:break;
  251. }
  252. logTrace("ParaRead_Done",1);
  253. printf("APN_INDEX:%d\r\n",sutProductPara.APNIndex);
  254. }
  255. void GpsTimeUpdate(void)
  256. {
  257. sutGpsInfo.GPS_UploadTime = GPS_TimeTable[sutProductPara.m_GPS_TimeIndex];//20160825,这里再加载GPS时间,用户体验:在改了GPS值后,重启没放卡,去菜单看说GPS值没改到
  258. if(sutGpsInfo.GPS_UploadTime)//判断GPS是否已关,根据上传时间来算
  259. {
  260. GPS_PWREN_HIGH;
  261. g_uiGpsStat=1;
  262. }
  263. else{
  264. GPS_PWREN_LOW;
  265. g_uiGpsStat=0;
  266. //sutGpsInfo.isGpsWork=0;
  267. }
  268. }
  269. /************************************file begin*******************************/