MainTask.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. /****************************************************************************
  2. *
  3. * Copy right: Qx.
  4. * File name: MainTask.c
  5. * Description: APP任务调取和异常处理
  6. * History: 2021-03-05
  7. * PS:主线程里面关闭了网络为了测试睡眠和唤醒
  8. ****************************************************************************/
  9. #include "bsp.h"
  10. #include "bsp_custom.h"
  11. #include "osasys.h"
  12. #include "ostask.h"
  13. #include "queue.h"
  14. #include "ps_event_callback.h"
  15. #include "cmisim.h"
  16. #include "cmimm.h"
  17. #include "cmips.h"
  18. #include "sockets.h"
  19. #include "psifevent.h"
  20. #include "ps_lib_api.h"
  21. #include "lwip/netdb.h"
  22. //#include <cis_def.h>
  23. #include "debug_log.h"
  24. #include "slpman_ec616.h"
  25. #include "plat_config.h"
  26. #include "ec_tcpip_api.h"
  27. #include "hal_module_adapter.h"
  28. #include "timers.h"
  29. #include "app.h"
  30. #include "MainTask.h"
  31. #include "TcpTask.h"
  32. #include "Fota.h"
  33. #include "UartTask.h"
  34. #include "sensor.h"
  35. #include "Signal.h"
  36. extern UINT8 UDSSwitch;
  37. extern volatile bool NB_Fota_update_flag;
  38. extern volatile bool BMS_Fota_update_flag;
  39. CHAR defaultBattSN[BATT_SN_LEN] = "RLTEST00000000001";//未进行下线检测的默认SN
  40. //全局变量
  41. UINT32 Timer_count;//每100ms加1
  42. volatile BOOL Sleep_flag = false;//睡眠标志位
  43. extern UINT32 TcpService;
  44. extern UINT8 BattChrgEndFlag;
  45. extern UINT8 Aoi1Event;
  46. extern UINT8 Aoi2Event;
  47. AppConfigHeader AppConfigHr; //4 bytes
  48. AppNVMDataType AppNVMData;
  49. AppDataHeader AppDataHr;
  50. AppDataBody AppDataInfo;
  51. //主线程堆栈声明区
  52. static StaticTask_t gProcess_Main_Task_t;
  53. static UINT8 gProcess_Main_TaskStack[PROC_MAIN_TASK_STACK_SIZE];
  54. static osThreadId_t MainTaskId = NULL;
  55. uint8_t MainSlpHandler = 0xff;//主线程睡眠句柄
  56. uint8_t deepslpTimerID = DEEPSLP_TIMER_ID7;//睡眠定时器ID
  57. static volatile bool Work_timer_end = false;
  58. static process_Main gProcess_Main_Task;
  59. #define PROC_MAIN_STATE_SWITCH(a) (gProcess_Main_Task = a)
  60. extern void GsensorInit(void);
  61. extern void GsensorI2CHandler(ARM_I2C_SignalEvent_t cb_event);
  62. extern void GsensorI2CCallback(UINT32 event);
  63. //函数声明区
  64. static void appBeforeHib(void *pdata, slpManLpState state);
  65. static void appAfterHib(void *pdata, slpManLpState state);
  66. static void appBeforeSlp1(void *pdata, slpManLpState state);
  67. static void appAfterSlp1(void *pdata, slpManLpState state);
  68. static void appBeforeSlp2(void *pdata, slpManLpState state);
  69. static void appAfterSlp2(void *pdata, slpManLpState state);
  70. void montior_timer_callback(TimerHandle_t xTimer);
  71. void work_timer_callback(TimerHandle_t xTimer);
  72. void BattWorkStateDelayFunc(UINT8 battWorkCurrentState);
  73. INT8 rentalEndDetectFunc(void);
  74. void BattLockFunc(void);
  75. static void setDefaultAppDataValue(void);
  76. void appLoadConfig(void);
  77. void appSaveConfig(void);
  78. static void appGetNVMSavedData(void);
  79. void appSaveNVMData(void);
  80. void RecoveyTheData(void);
  81. static void setDefaultAppDataInfo(void);
  82. static void LoadAppDataInfo(void);
  83. static void appSaveDataInfo(void);
  84. //主线程任务区
  85. static void MainTask(void* arg)
  86. {
  87. if(Error_Mutex == NULL)
  88. {
  89. Error_Mutex = osMutexNew(NULL);
  90. }
  91. GsensorI2CHandler(GsensorI2CCallback);
  92. GsensorInit();
  93. int32_t inParam = 0xAABBCCDD;
  94. UINT32 param;
  95. UINT32 adcValue;
  96. UINT8 Adcindex=0;
  97. slpManSetPmuSleepMode(true,SLP_HIB_STATE,false);
  98. slpManApplyPlatVoteHandle("MainSlp",&MainSlpHandler);
  99. slpManPlatVoteDisableSleep(MainSlpHandler, SLP_SLP1_STATE);
  100. slpManRegisterUsrdefinedBackupCb(appBeforeHib,&inParam,SLPMAN_HIBERNATE_STATE);
  101. slpManRegisterUsrdefinedRestoreCb(appAfterHib,NULL,SLPMAN_HIBERNATE_STATE);
  102. slpManRegisterUsrdefinedBackupCb(appBeforeSlp1,NULL,SLPMAN_SLEEP1_STATE);
  103. slpManRegisterUsrdefinedRestoreCb(appAfterSlp1,NULL,SLPMAN_SLEEP1_STATE);
  104. slpManRegisterUsrdefinedBackupCb(appBeforeSlp2,NULL,SLPMAN_SLEEP2_STATE);
  105. slpManRegisterUsrdefinedRestoreCb(appAfterSlp2,NULL,SLPMAN_SLEEP2_STATE);
  106. slpManSlpState_t slpstate = slpManGetLastSlpState();
  107. TimerHandle_t montior_timer = NULL;
  108. TimerHandle_t work_timer = NULL;
  109. slpManWakeSrc_e Wakeup_source;
  110. Wakeup_source = slpManGetWakeupSrc();//获取唤醒源
  111. #ifdef USING_PRINTF1
  112. printf("Wakeup_source:%d \n",Wakeup_source);
  113. #endif
  114. #ifdef DEBUGLOG
  115. Debug_printf("Wkp-%d \n",Wakeup_source);
  116. #endif
  117. appGetNVMSavedData();
  118. LoadAppDataInfo();
  119. #ifdef USING_PRINTF1
  120. UINT8 *pReadAppConfig;
  121. UINT32 readCount;
  122. //AppConfigHeader AppConfigHr;
  123. OSAFILE file;
  124. file = OsaFopen(APP_CONFIG_FILE_NAME,"rb");
  125. OsaFseek(file, 0, SEEK_SET);
  126. pReadAppConfig = OsaAllocZeroMemory(AppConfigHr.fileBodySize+4);
  127. readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize+4, 1, file);
  128. printf("AppConfigHr.fileBodySize+4 = %d\n",AppConfigHr.fileBodySize+4);
  129. printf("readCount = %d\n",readCount);
  130. printf("the config data = \n");
  131. for (int i ;i<AppConfigHr.fileBodySize+4;i++)
  132. printf("%d ",*(pReadAppConfig+i));
  133. printf("\n");
  134. #endif
  135. #ifdef USING_PRINTF1
  136. UINT8 *pReadAppData;
  137. UINT32 readCount;
  138. //AppConfigHeader AppConfigHr;
  139. OSAFILE file;
  140. file = OsaFopen(APP_DATAINFO_FILE_NAME,"rb");
  141. OsaFseek(file, 0, SEEK_SET);
  142. pReadAppData = OsaAllocZeroMemory(AppDataHr.fileBodySize+3);
  143. readCount = OsaFread(pReadAppData, AppDataHr.fileBodySize+3, 1, file);
  144. printf("AppDataHr.fileBodySize+3 = %d\n",AppDataHr.fileBodySize+3);
  145. printf("readCount = %d\n",readCount);
  146. printf("the data = ");
  147. for (int i=0 ;i<AppDataHr.fileBodySize+3;i++)
  148. printf("%x(%d) ",*(pReadAppData+i),i);
  149. printf("\n");
  150. #endif
  151. if(AppNVMData.AppSwVersion!=APPSWVERSION)
  152. {
  153. AppNVMData.HwVersion = HWVERSION;
  154. AppNVMData.BLSwVersion = BLSWVERSION;
  155. AppNVMData.DrvSwVersion = DRVSWVERSION;
  156. AppNVMData.AppSwVersion = APPSWVERSION;
  157. AppNVMData.appDataModify=TRUE;
  158. }
  159. montior_timer = xTimerCreate("montior_timer", 100 / portTICK_RATE_MS, pdTRUE, NULL, montior_timer_callback);
  160. work_timer = xTimerCreate("work_timer", AppNVMData.wakeupWorkTime*60*1000 / portTICK_RATE_MS, pdTRUE, NULL, work_timer_callback);
  161. /***calibrate the ADC Collect***/
  162. AdcSendReq(ADC_REQ_BITMAP_VBAT_CALI,&param,1,ADC_GET_RESULT_TIMOUT);
  163. AdcSendReq(ADC_REQ_BITMAP_INRES_CALI,&param,1,ADC_GET_RESULT_TIMOUT);
  164. NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
  165. NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
  166. NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
  167. NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
  168. FaultDisplay(LED_TURN_OFF);
  169. PROC_MAIN_STATE_SWITCH(PROCESS_STATE_IDLE);
  170. while(true)
  171. {
  172. switch(gProcess_Main_Task)
  173. {
  174. case PROCESS_STATE_IDLE:
  175. {
  176. Timer_count = 0;
  177. xTimerStart(montior_timer, 0);
  178. xTimerStart(work_timer, 0);
  179. Sleep_flag = false;
  180. PROC_MAIN_STATE_SWITCH(PROCESS_STATE_WORK);
  181. break;
  182. }
  183. case PROCESS_STATE_WORK:
  184. {
  185. osDelay(100);
  186. if(Error_count>=5 && CanMsgFlag==0x00 && UDSSwitch==0 &&BMS_Fota_update_flag==FALSE)
  187. {
  188. AppDataInfo.appDataModify = true;
  189. AppDataInfo.SysReStart = AppDataInfo.SysReStart +1;
  190. if(AppDataInfo.SysReStart>=0xfffe)
  191. {
  192. AppDataInfo.SysReStart = 0;
  193. }
  194. if(AppNVMData.appDataModify)
  195. {
  196. appSaveNVMData();
  197. }
  198. if(AppDataInfo.appDataModify)
  199. {
  200. appSaveDataInfo();
  201. }
  202. #ifdef DEBUGLOG
  203. Debug_printf("404\n");
  204. #endif
  205. appSetCFUN(0);
  206. osDelay(1000);
  207. EC_SystemReset();
  208. }
  209. if(Timer_count%10==0)
  210. {
  211. BattWorkStateDelayFunc(battWorkState);
  212. if( BattWorkStateDelay ==0x02)
  213. {
  214. BattChrgEndFlag=TRUE;
  215. }
  216. if(AppDataInfo.ErrorMsg != 0)
  217. {
  218. if(osOK==osMutexAcquire(Error_Mutex, 100))
  219. {
  220. UINT8 ErrorNumTemp = AppDataInfo.ErrorMsg;
  221. PutErrorNum((UINT16 *)ErrorNum,ErrorNumLen,ErrorNumTemp);
  222. }
  223. osMutexRelease(Error_Mutex);
  224. }
  225. if(Timer_count%(10*60)==0)
  226. {
  227. BattLockFunc();
  228. }
  229. }
  230. if(Work_timer_end)
  231. {
  232. xTimerStop(montior_timer, 0);
  233. PROC_MAIN_STATE_SWITCH(PROCESS_STATE_SLEEP);
  234. break;
  235. }
  236. else
  237. {
  238. switch (Adcindex)
  239. {
  240. case FAST_CHARGE_TEMP:
  241. NB_ADC_Get(&adcValue,FAST_CHARGE_TEMP);
  242. fastChargeTemp = LookUpRTtable(adcValue);
  243. break;
  244. case NORMAL_CHARGE_TEMP:
  245. NB_ADC_Get(&adcValue,NORMAL_CHARGE_TEMP);
  246. normalChargeTemp = LookUpRTtable(adcValue);
  247. break;
  248. case OTHER_TEMP_1:
  249. NB_ADC_Get(&adcValue,OTHER_TEMP_1);
  250. heatTemp1 = LookUpRTtable(adcValue);
  251. break;
  252. case OTHER_TEMP_2:
  253. NB_ADC_Get(&adcValue,OTHER_TEMP_2);
  254. heatTemp2 = LookUpRTtable(adcValue);
  255. break;
  256. case VBAT:
  257. NB_ADC_Get(&adcValue,VBAT);
  258. Adcindex = 0;
  259. break;
  260. default:
  261. Adcindex=0;
  262. break;
  263. }
  264. Adcindex++;
  265. }
  266. #ifdef USING_PRINTF1
  267. printf("TcpService:%d,UDSSwitch:%d,BMS_Fota_update_flag:%d,battWorkState:%d,Can_Msg_Enble:%d\r\n",TcpService,UDSSwitch,BMS_Fota_update_flag,battWorkState,Can_Msg_Enble);
  268. #endif
  269. if(TcpService!=0x00||UDSSwitch==1||BMS_Fota_update_flag||battWorkState!=0||CanMsgFlag==0x01||chargerConnectState==0x01)
  270. {
  271. xTimerReset(work_timer,0);
  272. }
  273. if(BattChrgEndFlag)
  274. {
  275. xTimerChangePeriod(work_timer,AppNVMData.chargEndWorkTime*60*1000 / portTICK_RATE_MS,0);
  276. xTimerReset(work_timer,0);
  277. }
  278. break;
  279. }
  280. case PROCESS_STATE_SLEEP:
  281. {
  282. Sleep_flag = true;
  283. if((minCellVol<2800 && minCellVol>0)||(maxCellVol<3000 && maxCellVol>0))
  284. {
  285. AppNVMData.appDataModify = TRUE;
  286. AppNVMData.sleepTime = 60;
  287. }
  288. else if((minCellVol>4000&&minCellVol<6000) && AppNVMData.sleepTime==60)
  289. {
  290. AppNVMData.appDataModify = TRUE;
  291. AppNVMData.sleepTime = 10;
  292. }
  293. if(AppNVMData.appDataModify)
  294. {
  295. appSaveNVMData();
  296. }
  297. if(AppDataInfo.appDataModify)
  298. {
  299. appSaveDataInfo();
  300. }
  301. if(NB_Fota_update_flag)
  302. {
  303. appSetCFUN(0);
  304. osDelay(1000);
  305. EC_SystemReset();
  306. }
  307. osDelay(1*1000);
  308. xTimerStop(work_timer, 0);
  309. slpManSlpState_t State;
  310. uint8_t cnt;
  311. if(slpManCheckVoteState(MainSlpHandler, &State, &cnt)==RET_TRUE)
  312. {
  313. #ifdef USING_PRINTF
  314. printf("[%d]We Can Check Vote Main State, state=%d, cnt=%d\r\n",__LINE__,State,cnt);
  315. #endif
  316. }
  317. slpManPlatVoteForceEnableSleep(MainSlpHandler, SLP_SLP1_STATE);
  318. if(slpManCheckVoteState(MainSlpHandler, &State, &cnt)==RET_TRUE)
  319. {
  320. #ifdef USING_PRINTF
  321. printf("[%d]We Can Check Vote Main State Again, state=%d, cnt=%d\r\n",__LINE__,State,cnt);
  322. #endif
  323. }
  324. #ifdef USING_PRINTF
  325. printf("[%d]Waiting sleep\r\n",__LINE__);
  326. #endif
  327. FaultDisplay(LED_TURN_ON);
  328. slpManSlpState_t slpstate = slpManPlatGetSlpState();
  329. #ifdef USING_PRINTF
  330. printf("which slpstate can go now :%d \n",slpstate);
  331. #endif
  332. #ifdef DEBUGLOG
  333. Debug_printf("slp-%d,%d\n",slpstate,AppDataInfo.SysReStart);
  334. #endif
  335. slpManDeepSlpTimerStart(deepslpTimerID, AppNVMData.sleepTime*1000*60);
  336. UINT8 sleeptime_count=0;
  337. RxInterprut = 0;
  338. Aoi1Event=0;
  339. Aoi2Event=0;
  340. while(1)
  341. {
  342. if(!slpManDeepSlpTimerIsRunning(deepslpTimerID))
  343. slpManDeepSlpTimerDel(deepslpTimerID);
  344. slpManDeepSlpTimerStart(deepslpTimerID, AppNVMData.sleepTime*1000*60);
  345. osDelay(1*60*1000/portTICK_PERIOD_MS);
  346. sleeptime_count++;
  347. #ifdef USING_PRINTF
  348. printf("sleeptime_count :%d \n",sleeptime_count);
  349. #endif
  350. if(sleeptime_count>10||RxInterprut==1||Aoi1Event==1||Aoi2Event==1)
  351. {
  352. #ifdef DEBUGLOG
  353. Debug_printf("405\n");
  354. #endif
  355. appSetCFUN(0);
  356. osDelay(1000);
  357. EC_SystemReset();
  358. }
  359. }
  360. break;
  361. }
  362. default:
  363. {
  364. PROC_MAIN_STATE_SWITCH(PROCESS_STATE_IDLE);
  365. #ifdef USING_PRINTF
  366. printf("default!\n");
  367. #endif
  368. break;
  369. }
  370. }
  371. }
  372. }
  373. void MainTaskInit(void *arg)
  374. {
  375. #ifndef USING_PRINTF
  376. if(BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_CONTROL) != 0)
  377. {
  378. HAL_UART_RecvFlowControl(false);
  379. }
  380. #endif
  381. osThreadAttr_t task_attr;
  382. memset(&task_attr,0,sizeof(task_attr));
  383. memset(gProcess_Main_TaskStack, 0xA5, PROC_MAIN_TASK_STACK_SIZE);
  384. task_attr.name = "Main_Task";
  385. task_attr.stack_mem = gProcess_Main_TaskStack;
  386. task_attr.stack_size = PROC_MAIN_TASK_STACK_SIZE;
  387. task_attr.priority = osPriorityNormal;
  388. task_attr.cb_mem = &gProcess_Main_Task_t;
  389. task_attr.cb_size = sizeof(StaticTask_t);
  390. MainTaskId = osThreadNew(MainTask, NULL, &task_attr);
  391. }
  392. void MainTaskDeInit(void *arg)
  393. {
  394. osThreadTerminate(MainTaskId);
  395. MainTaskId = NULL;
  396. }
  397. //定时器回调函数区
  398. void montior_timer_callback(TimerHandle_t xTimer)
  399. {
  400. #ifdef USING_PRINTF1
  401. if (Timer_count%50==0)
  402. {
  403. printf("Main Task,Batt_Cell_Num:%d,%d!\n",BATT_CELL_VOL_NUM,Timer_count);
  404. }
  405. #endif
  406. Timer_count++;
  407. if(Timer_count>100000*100)
  408. {
  409. Timer_count=0;
  410. }
  411. }
  412. void work_timer_callback(TimerHandle_t xTimer)
  413. {
  414. Work_timer_end = true;
  415. #ifdef USING_PRINTF
  416. printf("Hello work Timer!\n");
  417. #endif
  418. }
  419. //睡眠进出函数区
  420. static void appBeforeHib(void *pdata, slpManLpState state)
  421. {
  422. uint32_t *p_param = (uint32_t *)pdata;
  423. #ifdef USING_PRINTF
  424. printf("Before Hibernate:%d \n",state);
  425. #endif
  426. slpManAONIOLatchEn(AonIOLatch_Enable);
  427. }
  428. static void appAfterHib(void *pdata, slpManLpState state)
  429. {
  430. #ifdef USING_PRINTF
  431. printf("Try Hibernate Failed:%d \n",state);
  432. #endif
  433. }
  434. static void appBeforeSlp1(void *pdata, slpManLpState state)
  435. {
  436. #ifdef USING_PRINTF
  437. printf("Before Sleep1:%d \n",state);
  438. #endif
  439. slpManAONIOLatchEn(AonIOLatch_Enable);
  440. }
  441. static void appAfterSlp1(void *pdata, slpManLpState state)
  442. {
  443. #ifdef USING_PRINTF
  444. printf("After Sleep1:%d \n",state);
  445. #endif
  446. }
  447. static void appBeforeSlp2(void *pdata, slpManLpState state)
  448. {
  449. #ifdef USING_PRINTF
  450. printf("before sleep2:%d \n",state);
  451. #endif
  452. slpManAONIOLatchEn(AonIOLatch_Enable);
  453. }
  454. static void appAfterSlp2(void *pdata, slpManLpState state)
  455. {
  456. #ifdef USING_PRINTF
  457. printf("sleep2 failed:%d \n",state);
  458. #endif
  459. }
  460. static void appGetNVMSavedData(void)
  461. {
  462. appLoadConfig();
  463. }
  464. void appSaveNVMData(void)
  465. {
  466. appSaveConfig();
  467. }
  468. static void appSaveConfig(void)
  469. {
  470. OSAFILE fp = PNULL;
  471. UINT32 writeCount = 0;
  472. AppConfigHeader AppConfigHr; //4 bytes
  473. /*
  474. * open the NVM file
  475. */
  476. fp = OsaFopen(APP_CONFIG_FILE_NAME, "wb"); //read & write
  477. if(OsaFseek(fp, 0, SEEK_SET) != 0)
  478. {
  479. #ifdef USING_PRINTF
  480. printf("Seek file failed [%d] \r\n",__LINE__);
  481. #endif
  482. OsaFclose(fp);
  483. return;
  484. }
  485. if (fp == PNULL)
  486. {
  487. #ifdef USING_PRINTF
  488. printf(" NVM, can't open/create NVM: 'qxappconfig.nvm', save NVM failed\n");
  489. #endif
  490. return;
  491. }
  492. /*
  493. * write the header
  494. */
  495. AppConfigHr.fileBodySize = sizeof(AppNVMData);
  496. AppConfigHr.version = APP_CONFIG_FILE_LATEST_VERSION;
  497. AppConfigHr.checkSum = OsaCalcCrcValue((UINT8 *)&AppNVMData, sizeof(AppNVMData));
  498. writeCount = OsaFwrite(&AppConfigHr, sizeof(AppConfigHeader), 1, fp);
  499. if (writeCount != 1)
  500. {
  501. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppConfigSave_2, P_ERROR, 0,
  502. // " NVM: 'qxappconfig.nvm', write the file header failed");
  503. #ifdef USING_PRINTF
  504. printf(" NVM: 'qxappconfig.nvm', write the file header failed\n");
  505. #endif
  506. OsaFclose(fp);
  507. return;
  508. }
  509. /*
  510. * write the file body
  511. */
  512. AppNVMData.appDataModify = FALSE;
  513. writeCount = OsaFwrite(&AppNVMData, sizeof(AppNVMData), 1, fp);
  514. if (writeCount != 1)
  515. {
  516. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppConfigSave_3, P_ERROR, 0,
  517. // " NVM: 'qxappconfig.nvm', write the file body failed");
  518. #ifdef USING_PRINTF
  519. printf(" NVM: 'qxappconfig.nvm', write the file body failed\n");
  520. #endif
  521. }
  522. OsaFclose(fp);
  523. return;
  524. }
  525. void appLoadConfig(void)
  526. {
  527. OSAFILE fp = PNULL;
  528. UINT32 readCount = 0;
  529. //AppConfigHeader AppConfigHr; //4 bytes
  530. UINT8 crcCheck = 0;
  531. void *pReadAppConfig = (void *)&AppNVMData;
  532. /*
  533. * open the NVM file
  534. */
  535. fp = OsaFopen(APP_CONFIG_FILE_NAME, "rb"); //read only
  536. if (fp == PNULL)
  537. {
  538. #ifdef USING_PRINTF
  539. printf(" NVM, can't open NVM: 'qxappConfig.nvm', use the defult value\n");
  540. #endif
  541. setDefaultAppDataValue();
  542. appSaveConfig();
  543. return;
  544. }
  545. /*
  546. * read the file header
  547. */
  548. readCount = OsaFread(&AppConfigHr, sizeof(AppConfigHeader), 1, fp);
  549. UINT8 readtimes=0;
  550. while (readCount != 1 && readtimes<=5 )
  551. {
  552. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_header_e_1, P_ERROR, 1,
  553. // "NVM: 'qxappconfig.nvm', can't read header, return: %d, use the defult value", readCount);
  554. #ifdef USING_PRINTF
  555. printf("NVM: 'qxappconfig.nvm', can't read header, return: %d, use the defult value \n");
  556. #endif
  557. readtimes++;
  558. readCount = OsaFread(&AppConfigHr, sizeof(AppConfigHeader), 1, fp);
  559. osDelay(10);
  560. }
  561. if(readtimes>5)
  562. {
  563. OsaFclose(fp);
  564. setDefaultAppDataValue();
  565. appSaveConfig();
  566. return;
  567. }
  568. if (AppConfigHr.version != APP_CONFIG_FILE_LATEST_VERSION)
  569. {
  570. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_ver_w_1, P_ERROR, 2,
  571. // "NVM: 'qxappconfig.nvm', version: %d not latest: %d, try to adapt",
  572. // AppConfigHr.version, MID_WARE_NVM_FILE_LATEST_VERSION);
  573. #ifdef USING_PRINTF
  574. printf("NVM: 'qxappconfig.nvm', version: %d not latest: %d, try to adapt\n",
  575. AppConfigHr.version, MID_WARE_NVM_FILE_LATEST_VERSION);
  576. #endif
  577. if (AppConfigHr.fileBodySize > 1024) //in fact this NVM size should limited in 1KB
  578. {
  579. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_ver_e_1, P_ERROR, 2,
  580. // "NVM: 'qxappconfig.nvm', version: %d, NVM body size: %d > 1024, not right, use the default value",
  581. // AppConfigHr.version, AppConfigHr.fileBodySize);
  582. #ifdef USING_PRINTF
  583. printf("NVM: 'qxappconfig.nvm', version: %d, NVM body size: %d > 1024, not right, use the default value",
  584. AppConfigHr.version, AppConfigHr.fileBodySize);
  585. #endif
  586. OsaFclose(fp);
  587. setDefaultAppDataValue();
  588. appSaveConfig();
  589. return;
  590. }
  591. /*
  592. * As need to do adaption, can't read the old NVM into "mwNvmConfig", here we allocate a new buffer to store it
  593. */
  594. pReadAppConfig = OsaAllocZeroMemory(AppConfigHr.fileBodySize);
  595. if (pReadAppConfig == PNULL)
  596. {
  597. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_buff_e_1, P_ERROR, 2,
  598. // "NVM: 'qxappconfig.nvm', version: %d, can not allo memsize: %d, use the default value",
  599. // AppConfigHr.version, AppConfigHr.fileBodySize);
  600. #ifdef USING_PRINTF
  601. printf("NVM: 'qxappconfig.nvm', version: %d, can not allo memsize: %d, use the default value",
  602. AppConfigHr.version, AppConfigHr.fileBodySize);
  603. #endif
  604. OsaFclose(fp);
  605. setDefaultAppDataValue();
  606. appSaveConfig();
  607. return;
  608. }
  609. //needAdjust = TRUE;
  610. }
  611. else if (AppConfigHr.fileBodySize != sizeof(AppNVMData)) //file version is the same, but NVM file size not right
  612. {
  613. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_2, P_ERROR, 2,
  614. // "MW NVM: 'midwareconfig.nvm', file body size not right: (%u/%u), use the defult value",
  615. // AppConfigHr.fileBodySize, sizeof(AppNVMData));
  616. #ifdef USING_PRINTF
  617. printf("MW NVM: 'midwareconfig.nvm', file body size not right: (%u/%u), use the defult value",
  618. AppConfigHr.fileBodySize, sizeof(AppNVMData));
  619. #endif
  620. OsaFclose(fp);
  621. setDefaultAppDataValue();
  622. appSaveConfig();
  623. return;
  624. }
  625. /*
  626. * read the file body
  627. */
  628. readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp);
  629. crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData));
  630. readtimes = 0;
  631. //while (readtimes<=5 && crcCheck != AppConfigHr.checkSum)
  632. while (readtimes<=5 && readCount != 1)
  633. {
  634. readtimes++;
  635. readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp);
  636. crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData));
  637. }
  638. if (readtimes>5)
  639. {
  640. //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_3, P_ERROR, 2,
  641. // "NVM: 'qxappconfig.nvm', can't read body, or body not right, (%u/%u), use the defult value",
  642. // crcCheck, AppConfigHr.checkSum);
  643. #ifdef USING_PRINTF
  644. printf(" NVM: 'qxappconfig.nvm', can't read body, or body not right, (%u/%u), use the defult value\n ",
  645. crcCheck, AppConfigHr.checkSum);
  646. #endif
  647. OsaFclose(fp);
  648. setDefaultAppDataValue();
  649. appSaveConfig();
  650. /*
  651. if (needAdjust)
  652. {
  653. OsaFreeMemory(&pReadAppConfig);
  654. }
  655. */
  656. return;
  657. }
  658. #if 0
  659. if (needAdjust)
  660. {
  661. OsaFclose(fp);
  662. setDefaultAppDataValue();
  663. appSaveConfig();
  664. /* free memory */
  665. OsaFreeMemory(&pReadAppConfig);
  666. }
  667. #endif
  668. #if 0
  669. int i=0;
  670. printf("AppConfigHeader:\n");
  671. printf("%d,%d,%d\n",AppConfigHr.fileBodySize,AppConfigHr.version,AppConfigHr.checkSum);
  672. printf("AppConfigFileBody:\n");
  673. printf("%d,%d,%d\n",AppNVMData.chargEndWorkTime,AppNVMData.wakeupWorkTime,AppNVMData.sleepTime);
  674. printf("\n");
  675. #endif
  676. OsaFclose(fp);
  677. return;
  678. }
  679. //if the AppNVMData.version(read form nvm) != APP_CONFIG_FILE_LATEST_VERSION, it will setDefaultAppDataValue()
  680. //so if you want to modify the default value, please modify the APP_CONFIG_FILE_LATEST_VERSION (in MainTask.h) meanwhile, so that will be store to the nvm file
  681. static void setDefaultAppDataValue(void)
  682. {
  683. UINT8 i = 0;
  684. memset(&AppNVMData, 0x00, sizeof(AppNVMDataType));
  685. for(i=0;i<BATT_SN_LEN;i++)
  686. {
  687. AppNVMData.battSN[i] = defaultBattSN[i]; //the defult sn is "0000..0000"(17 bytes ASCII)
  688. }
  689. AppNVMData.isBattLocked = false;
  690. AppNVMData.chargEndWorkTime = 30; //30 min
  691. AppNVMData.wakeupWorkTime = 2; //2min
  692. AppNVMData.sleepTime = 5; //5min
  693. AppNVMData.HwVersion = HWVERSION;
  694. AppNVMData.BLSwVersion = BLSWVERSION;
  695. AppNVMData.DrvSwVersion = DRVSWVERSION;
  696. AppNVMData.AppSwVersion = APPSWVERSION;
  697. AppNVMData.EOLState = EOLSTATE; //未进行下线配置,北京电池测试默认进行下线测试
  698. return;
  699. }
  700. static void appSaveDataInfo(void)
  701. {
  702. OSAFILE fp = PNULL;
  703. UINT32 writeCount = 0;
  704. fp = OsaFopen(APP_DATAINFO_FILE_NAME, "wb"); //read & write
  705. if(OsaFseek(fp, 0, SEEK_SET) != 0)
  706. {
  707. #ifdef USING_PRINTF
  708. printf("Seek file failed [%d] \r\n",__LINE__);
  709. #endif
  710. OsaFclose(fp);
  711. return;
  712. }
  713. if (fp == PNULL)
  714. {
  715. #ifdef USING_PRINTF
  716. printf(" NVM, can't open/create NVM: 'qxappconfig.nvm', save NVM failed\n");
  717. #endif
  718. return;
  719. }
  720. AppDataHr.fileBodySize = sizeof(AppDataInfo);
  721. AppDataHr.checkSum = OsaCalcCrcValue((UINT8 *)&AppDataInfo, sizeof(AppDataInfo));
  722. #ifdef USING_PRINTF
  723. printf(" AppDataHr.fileBodySize:%x\n",AppDataHr.fileBodySize);
  724. #endif
  725. writeCount = OsaFwrite(&AppDataHr, sizeof(AppDataHr), 1, fp);
  726. if (writeCount != 1)
  727. {
  728. #ifdef USING_PRINTF
  729. printf(" NVM: 'qxappconfig.nvm', write the file header failed\n");
  730. #endif
  731. OsaFclose(fp);
  732. return;
  733. }
  734. AppDataInfo.appDataModify = FALSE;
  735. writeCount = OsaFwrite(&AppDataInfo, sizeof(AppDataInfo), 1, fp);
  736. if (writeCount != 1)
  737. {
  738. #ifdef USING_PRINTF
  739. printf(" NVM: 'qxappconfig.nvm', write the file body failed\n");
  740. #endif
  741. }
  742. OsaFclose(fp);
  743. return;
  744. }
  745. static void LoadAppDataInfo(void)
  746. {
  747. OSAFILE fp = PNULL;
  748. UINT32 readCount = 0;
  749. UINT8 crcCheck = 0;
  750. void *pReadAppConfig = (void *)&AppDataInfo;
  751. fp = OsaFopen(APP_DATAINFO_FILE_NAME, "rb"); //read only
  752. if (fp == PNULL)
  753. {
  754. #ifdef USING_PRINTF
  755. printf(" NVM, can't open NVM: 'qxappData.nvm', use the defult value\n");
  756. #endif
  757. setDefaultAppDataInfo();
  758. appSaveDataInfo();
  759. return;
  760. }
  761. readCount = OsaFread(&AppDataHr, sizeof(AppDataHr), 1, fp);
  762. UINT8 readtimes=0;
  763. while (readCount != 1 && readtimes<=5 )
  764. {
  765. readtimes++;
  766. readCount = OsaFread(&AppDataHr, sizeof(AppDataHr), 1, fp);
  767. osDelay(10);
  768. }
  769. if(readtimes>5)
  770. {
  771. OsaFclose(fp);
  772. setDefaultAppDataInfo();
  773. appSaveDataInfo();
  774. return;
  775. }
  776. if(AppDataHr.fileBodySize==sizeof(AppDataInfo))//结构体数据没变动,可直接读出
  777. {
  778. readCount = OsaFread(pReadAppConfig, AppDataHr.fileBodySize, 1, fp);
  779. //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData));
  780. readtimes = 0;
  781. while (readtimes<=5 && readCount != 1)
  782. {
  783. readtimes++;
  784. readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp);
  785. //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData));
  786. }
  787. }
  788. else
  789. {
  790. setDefaultAppDataInfo();
  791. readCount = OsaFread(pReadAppConfig, AppDataHr.fileBodySize, 1, fp);
  792. //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData));
  793. readtimes = 0;
  794. while (readtimes<=5 && readCount != 1)
  795. {
  796. readtimes++;
  797. readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp);
  798. //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData));
  799. }
  800. appSaveDataInfo();
  801. #ifdef USING_PRINTF
  802. printf(" Struct update\n");
  803. #endif
  804. }
  805. OsaFclose(fp);
  806. return;
  807. }
  808. void RecoveyTheData(void)
  809. {
  810. setDefaultAppDataInfo();
  811. appSaveDataInfo();
  812. }
  813. //无法找到文件时的第一次启动,后续不会启动此函数
  814. static void setDefaultAppDataInfo(void)
  815. {
  816. memset(&AppDataInfo, 0x00, sizeof(AppDataInfo));
  817. AppDataInfo.appDataModify = false;
  818. AppDataInfo.BmsChrgInfoSendFreq = 5;
  819. AppDataInfo.BmsDisChrgInfoSendFreq = 30;
  820. AppDataInfo.GpsChrgInfoSendFreq = 30;
  821. AppDataInfo.GpsDisChrgInfoSendFreq = 5;
  822. AppDataInfo.BattCurrentNegFlag = 1;
  823. AppDataInfo.CumulativeCapacity = 0;
  824. AppDataInfo.AccMileage = 0;
  825. AppDataInfo.SysReStart = 0;
  826. AppDataInfo.RelayControl = 0;
  827. AppDataInfo.userLock = 0;
  828. AppDataInfo.rentalLock = 0;
  829. AppDataInfo.ErrorMsg = 0;
  830. AppDataInfo.rentaltype = 0;
  831. memset(AppDataInfo.ExpiryTimeArray, 0x00, sizeof(AppDataInfo.ExpiryTimeArray));
  832. return;
  833. }
  834. void BattWorkStateDelayFunc(UINT8 battWorkCurrentState)
  835. {
  836. static UINT8 workDelayCounter;
  837. if(battWorkCurrentState==BATT_DISCHARGE_SYM)//从 充电或者静置 转放电 3s延时
  838. {
  839. workDelayCounter++;
  840. if(workDelayCounter>=3)
  841. {
  842. workDelayCounter=0;
  843. BattWorkStateDelay = battWorkCurrentState;
  844. }
  845. }
  846. else if(battWorkCurrentState==BATT_CHARGE_SYM)//从 放电或者静置 转充电30s延时
  847. {
  848. workDelayCounter++;
  849. if(workDelayCounter>=30)
  850. {
  851. workDelayCounter=0;
  852. BattWorkStateDelay = battWorkCurrentState;
  853. }
  854. }
  855. else
  856. {
  857. BattWorkStateDelay = battWorkCurrentState;
  858. workDelayCounter = 0;
  859. }
  860. }
  861. INT8 rentalEndDetectFunc(void)
  862. {
  863. OsaUtcTimeTValue TimeStracture;
  864. UTC8TimeType UTC8Time,ExpiryTime;
  865. UINT16 year;
  866. UINT8 month,day,hour,minute,sec;
  867. appGetSystemTimeUtcSync(&TimeStracture);
  868. year=(TimeStracture.UTCtimer1&0xffff0000)>>16;
  869. month=(TimeStracture.UTCtimer1&0xff00)>>8;
  870. day=TimeStracture.UTCtimer1&0xff;
  871. hour=(TimeStracture.UTCtimer2&0xff000000)>>24;
  872. minute=(TimeStracture.UTCtimer2&0xff0000)>>16;
  873. sec=(TimeStracture.UTCtimer2&0xff00)>>8;
  874. UTCToBeijing((UTC8TimeType *)&UTC8Time,year,month,day,hour,minute,sec);
  875. if(UTC8Time.year>2000)
  876. {
  877. #ifdef USING_PRINTF
  878. printf("retal Jug:%d %d %d %d,%d %d %d %d\n",UTC8Time.year,UTC8Time.month,UTC8Time.day,UTC8Time.hour,AppDataInfo.ExpiryTimeArray[0],AppDataInfo.ExpiryTimeArray[1],AppDataInfo.ExpiryTimeArray[2],AppDataInfo.ExpiryTimeArray[3]);
  879. #endif
  880. if(((UTC8Time.year - 0x07D0) & 0xFF)==AppDataInfo.ExpiryTimeArray[0])//年份相等判定月份
  881. {
  882. if(UTC8Time.month==AppDataInfo.ExpiryTimeArray[1])//月份相等判定日期
  883. {
  884. if(UTC8Time.day==AppDataInfo.ExpiryTimeArray[2])//日期相等判定小时
  885. {
  886. // if(UTC8Time.hour<=AppDataInfo.ExpiryTimeArray[3])//小时相等不锁定,小时超出锁定
  887. // {
  888. // return 0;
  889. // }
  890. // else
  891. // {
  892. // return 1;
  893. // }
  894. return 0;
  895. }
  896. else if(UTC8Time.day>AppDataInfo.ExpiryTimeArray[2])
  897. {
  898. return 1;
  899. }
  900. else if(UTC8Time.day<AppDataInfo.ExpiryTimeArray[2])
  901. {
  902. return 0;
  903. }
  904. }
  905. else if(UTC8Time.month>AppDataInfo.ExpiryTimeArray[1])//实际月份大于终止月份
  906. {
  907. return 1;
  908. }
  909. else if(UTC8Time.month<AppDataInfo.ExpiryTimeArray[1])//实际月份小于终止月份
  910. {
  911. return 0;
  912. }
  913. }
  914. else if(((UTC8Time.year - 0x07D0) & 0xFF)>AppDataInfo.ExpiryTimeArray[0])//实际年份大于终止年份
  915. {
  916. return 1;
  917. }
  918. else if(((UTC8Time.year - 0x07D0) & 0xFF)<AppDataInfo.ExpiryTimeArray[0])//年比较,实际年份小于终止年份
  919. {
  920. return 0;
  921. }
  922. }
  923. else
  924. {
  925. return -1;//没有获取到时间返回
  926. }
  927. }
  928. void BattLockFunc(void)
  929. {
  930. if(AppDataInfo.rentaltype==0)//测试模式
  931. {
  932. ;
  933. }
  934. else if (AppDataInfo.rentaltype==1)//零售模式
  935. {
  936. if(AppDataInfo.rentalLock==TRUE)
  937. {
  938. AppDataInfo.userLock = FALSE;
  939. AppDataInfo.rentalLock=FALSE;
  940. AppDataInfo.appDataModify=TRUE;
  941. }
  942. }
  943. else if(AppDataInfo.rentaltype==2)// 租赁模式
  944. {
  945. INT8 ret = -1;
  946. ret = rentalEndDetectFunc();
  947. if(ret==1 && AppDataInfo.rentalLock==FALSE)//租期判定是否超期函数
  948. {
  949. #ifdef USING_PRINTF
  950. printf("retal lock,%d\n",ret);
  951. #endif
  952. AppDataInfo.rentalLock=TRUE;
  953. AppDataInfo.appDataModify=TRUE;
  954. }
  955. else if(ret==0 && AppDataInfo.rentalLock==TRUE)
  956. {
  957. #ifdef USING_PRINTF
  958. printf("retal unlock,%d\n",ret);
  959. #endif
  960. AppDataInfo.rentalLock=FALSE;
  961. AppDataInfo.appDataModify=TRUE;
  962. AppDataInfo.userLock = FALSE;
  963. }
  964. }
  965. if(AppDataInfo.rentalLock==FALSE&&AppDataInfo.userLock==FALSE)
  966. {
  967. AppNVMData.isBattLocked = FALSE;
  968. AppNVMData.appDataModify = TRUE;
  969. }
  970. else if(AppDataInfo.rentalLock==TRUE||AppDataInfo.userLock==TRUE)
  971. {
  972. AppNVMData.isBattLocked = TRUE;
  973. AppNVMData.appDataModify = TRUE;
  974. }
  975. return;
  976. }