/**************************************************************************** * * Copy right: Qx. * File name: MainTask.c * Description: APP任务调取和异常处理 * History: 2021-03-05 * PS:主线程里面关闭了网络为了测试睡眠和唤醒 ****************************************************************************/ #include "bsp.h" #include "bsp_custom.h" #include "osasys.h" #include "ostask.h" #include "queue.h" #include "ps_event_callback.h" #include "cmisim.h" #include "cmimm.h" #include "cmips.h" #include "sockets.h" #include "psifevent.h" #include "ps_lib_api.h" #include "lwip/netdb.h" //#include #include "debug_log.h" #include "slpman_ec616.h" #include "plat_config.h" #include "ec_tcpip_api.h" #include "hal_module_adapter.h" #include "timers.h" #include "app.h" #include "MainTask.h" #include "TcpTask.h" #include "Fota.h" #include "UartTask.h" #include "sensor.h" #include "Signal.h" extern UINT8 UDSSwitch; extern volatile bool NB_Fota_update_flag; extern volatile bool BMS_Fota_update_flag; CHAR defaultBattSN[BATT_SN_LEN] = "MGYGYN660N214E009";//未进行下线检测的默认SN //全局变量 UINT32 Timer_count;//每100ms加1 volatile BOOL Sleep_flag = false;//睡眠标志位 extern UINT32 TcpService; extern UINT8 BattChrgEndFlag; AppConfigHeader AppConfigHr; //4 bytes AppNVMDataType AppNVMData; AppDataHeader AppDataHr; AppDataBody AppDataInfo; //主线程堆栈声明区 static StaticTask_t gProcess_Main_Task_t; static UINT8 gProcess_Main_TaskStack[PROC_MAIN_TASK_STACK_SIZE]; static osThreadId_t MainTaskId = NULL; uint8_t MainSlpHandler = 0xff;//主线程睡眠句柄 uint8_t deepslpTimerID = DEEPSLP_TIMER_ID7;//睡眠定时器ID volatile bool Work_timer_end = false; static process_Main gProcess_Main_Task; #define PROC_MAIN_STATE_SWITCH(a) (gProcess_Main_Task = a) extern void GsensorInit(void); extern void GsensorI2CHandler(ARM_I2C_SignalEvent_t cb_event); extern void GsensorI2CCallback(UINT32 event); //函数声明区 static void appBeforeHib(void *pdata, slpManLpState state); static void appAfterHib(void *pdata, slpManLpState state); static void appBeforeSlp1(void *pdata, slpManLpState state); static void appAfterSlp1(void *pdata, slpManLpState state); static void appBeforeSlp2(void *pdata, slpManLpState state); static void appAfterSlp2(void *pdata, slpManLpState state); void montior_timer_callback(TimerHandle_t xTimer); void work_timer_callback(TimerHandle_t xTimer); static void setDefaultAppDataValue(void); void appLoadConfig(void); void appSaveConfig(void); static void appGetNVMSavedData(void); void appSaveNVMData(void); static void setDefaultAppDataInfo(void); static void LoadAppDataInfo(void); static void appSaveDataInfo(void); //主线程任务区 static void MainTask(void* arg) { GsensorI2CHandler(GsensorI2CCallback); GsensorInit(); int32_t inParam = 0xAABBCCDD; UINT32 param; UINT32 adcValue; UINT8 i=0; slpManSetPmuSleepMode(true,SLP_HIB_STATE,false); slpManApplyPlatVoteHandle("MainSlp",&MainSlpHandler); slpManPlatVoteDisableSleep(MainSlpHandler, SLP_SLP1_STATE); slpManRegisterUsrdefinedBackupCb(appBeforeHib,&inParam,SLPMAN_HIBERNATE_STATE); slpManRegisterUsrdefinedRestoreCb(appAfterHib,NULL,SLPMAN_HIBERNATE_STATE); slpManRegisterUsrdefinedBackupCb(appBeforeSlp1,NULL,SLPMAN_SLEEP1_STATE); slpManRegisterUsrdefinedRestoreCb(appAfterSlp1,NULL,SLPMAN_SLEEP1_STATE); slpManRegisterUsrdefinedBackupCb(appBeforeSlp2,NULL,SLPMAN_SLEEP2_STATE); slpManRegisterUsrdefinedRestoreCb(appAfterSlp2,NULL,SLPMAN_SLEEP2_STATE); slpManSlpState_t slpstate = slpManGetLastSlpState(); TimerHandle_t montior_timer = NULL; TimerHandle_t work_timer = NULL; slpManWakeSrc_e Wakeup_source; Wakeup_source = slpManGetWakeupSrc();//获取唤醒源 #ifdef USING_PRINTF1 printf("Wakeup_source:%d \n",Wakeup_source); #endif #ifdef DEBUGLOG Debug_printf("Wakeup-%d \n",Wakeup_source); #endif appGetNVMSavedData(); LoadAppDataInfo(); #ifdef USING_PRINTF1 UINT8 *pReadAppConfig; UINT32 readCount; //AppConfigHeader AppConfigHr; OSAFILE file; file = OsaFopen(APP_CONFIG_FILE_NAME,"rb"); OsaFseek(file, 0, SEEK_SET); pReadAppConfig = OsaAllocZeroMemory(AppConfigHr.fileBodySize+4); readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize+4, 1, file); printf("AppConfigHr.fileBodySize+4 = %d\n",AppConfigHr.fileBodySize+4); printf("readCount = %d\n",readCount); printf("the config data = \n"); for (int i ;i10) { EC_SystemReset(); } } break; } default: { PROC_MAIN_STATE_SWITCH(PROCESS_STATE_IDLE); #ifdef USING_PRINTF printf("default!\n"); #endif break; } } } } void MainTaskInit(void *arg) { #ifndef USING_PRINTF if(BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_CONTROL) != 0) { HAL_UART_RecvFlowControl(false); } #endif osThreadAttr_t task_attr; memset(&task_attr,0,sizeof(task_attr)); memset(gProcess_Main_TaskStack, 0xA5, PROC_MAIN_TASK_STACK_SIZE); task_attr.name = "Main_Task"; task_attr.stack_mem = gProcess_Main_TaskStack; task_attr.stack_size = PROC_MAIN_TASK_STACK_SIZE; task_attr.priority = osPriorityNormal; task_attr.cb_mem = &gProcess_Main_Task_t; task_attr.cb_size = sizeof(StaticTask_t); MainTaskId = osThreadNew(MainTask, NULL, &task_attr); } void MainTaskDeInit(void *arg) { osThreadTerminate(MainTaskId); MainTaskId = NULL; } //定时器回调函数区 void montior_timer_callback(TimerHandle_t xTimer) { #ifdef USING_PRINTF1 if (Timer_count%50==0) { printf("Main Task,Batt_Cell_Num:%d,%d!\n",BATT_CELL_VOL_NUM,Timer_count); } #endif Timer_count++; if(Timer_count>100000*100) { Timer_count=0; } } void work_timer_callback(TimerHandle_t xTimer) { Work_timer_end = true; #ifdef USING_PRINTF printf("Hello work Timer!\n"); #endif } //睡眠进出函数区 static void appBeforeHib(void *pdata, slpManLpState state) { uint32_t *p_param = (uint32_t *)pdata; #ifdef USING_PRINTF printf("Before Hibernate:%d \n",state); #endif slpManAONIOLatchEn(AonIOLatch_Enable); } static void appAfterHib(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("Try Hibernate Failed:%d \n",state); #endif } static void appBeforeSlp1(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("Before Sleep1:%d \n",state); #endif slpManAONIOLatchEn(AonIOLatch_Enable); } static void appAfterSlp1(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("After Sleep1:%d \n",state); #endif } static void appBeforeSlp2(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("before sleep2:%d \n",state); #endif slpManAONIOLatchEn(AonIOLatch_Enable); } static void appAfterSlp2(void *pdata, slpManLpState state) { #ifdef USING_PRINTF printf("sleep2 failed:%d \n",state); #endif } static void appGetNVMSavedData(void) { appLoadConfig(); } void appSaveNVMData(void) { appSaveConfig(); } static void appSaveConfig(void) { OSAFILE fp = PNULL; UINT32 writeCount = 0; AppConfigHeader AppConfigHr; //4 bytes /* * open the NVM file */ fp = OsaFopen(APP_CONFIG_FILE_NAME, "wb"); //read & write if(OsaFseek(fp, 0, SEEK_SET) != 0) { #ifdef USING_PRINTF printf("Seek file failed [%d] \r\n",__LINE__); #endif OsaFclose(fp); return; } if (fp == PNULL) { #ifdef USING_PRINTF printf(" NVM, can't open/create NVM: 'qxappconfig.nvm', save NVM failed\n"); #endif return; } /* * write the header */ AppConfigHr.fileBodySize = sizeof(AppNVMData); AppConfigHr.version = APP_CONFIG_FILE_LATEST_VERSION; AppConfigHr.checkSum = OsaCalcCrcValue((UINT8 *)&AppNVMData, sizeof(AppNVMData)); writeCount = OsaFwrite(&AppConfigHr, sizeof(AppConfigHeader), 1, fp); if (writeCount != 1) { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppConfigSave_2, P_ERROR, 0, // " NVM: 'qxappconfig.nvm', write the file header failed"); #ifdef USING_PRINTF printf(" NVM: 'qxappconfig.nvm', write the file header failed\n"); #endif OsaFclose(fp); return; } /* * write the file body */ AppNVMData.appDataModify = FALSE; writeCount = OsaFwrite(&AppNVMData, sizeof(AppNVMData), 1, fp); if (writeCount != 1) { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppConfigSave_3, P_ERROR, 0, // " NVM: 'qxappconfig.nvm', write the file body failed"); #ifdef USING_PRINTF printf(" NVM: 'qxappconfig.nvm', write the file body failed\n"); #endif } OsaFclose(fp); return; } void appLoadConfig(void) { OSAFILE fp = PNULL; UINT32 readCount = 0; //AppConfigHeader AppConfigHr; //4 bytes UINT8 crcCheck = 0; void *pReadAppConfig = (void *)&AppNVMData; /* * open the NVM file */ fp = OsaFopen(APP_CONFIG_FILE_NAME, "rb"); //read only if (fp == PNULL) { #ifdef USING_PRINTF printf(" NVM, can't open NVM: 'qxappConfig.nvm', use the defult value\n"); #endif setDefaultAppDataValue(); appSaveConfig(); return; } /* * read the file header */ readCount = OsaFread(&AppConfigHr, sizeof(AppConfigHeader), 1, fp); UINT8 readtimes=0; while (readCount != 1 && readtimes<=5 ) { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_header_e_1, P_ERROR, 1, // "NVM: 'qxappconfig.nvm', can't read header, return: %d, use the defult value", readCount); #ifdef USING_PRINTF printf("NVM: 'qxappconfig.nvm', can't read header, return: %d, use the defult value \n"); #endif readtimes++; readCount = OsaFread(&AppConfigHr, sizeof(AppConfigHeader), 1, fp); osDelay(10); } if(readtimes>5) { OsaFclose(fp); setDefaultAppDataValue(); appSaveConfig(); return; } if (AppConfigHr.version != APP_CONFIG_FILE_LATEST_VERSION) { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_ver_w_1, P_ERROR, 2, // "NVM: 'qxappconfig.nvm', version: %d not latest: %d, try to adapt", // AppConfigHr.version, MID_WARE_NVM_FILE_LATEST_VERSION); #ifdef USING_PRINTF printf("NVM: 'qxappconfig.nvm', version: %d not latest: %d, try to adapt\n", AppConfigHr.version, MID_WARE_NVM_FILE_LATEST_VERSION); #endif if (AppConfigHr.fileBodySize > 1024) //in fact this NVM size should limited in 1KB { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_ver_e_1, P_ERROR, 2, // "NVM: 'qxappconfig.nvm', version: %d, NVM body size: %d > 1024, not right, use the default value", // AppConfigHr.version, AppConfigHr.fileBodySize); #ifdef USING_PRINTF printf("NVM: 'qxappconfig.nvm', version: %d, NVM body size: %d > 1024, not right, use the default value", AppConfigHr.version, AppConfigHr.fileBodySize); #endif OsaFclose(fp); setDefaultAppDataValue(); appSaveConfig(); return; } /* * As need to do adaption, can't read the old NVM into "mwNvmConfig", here we allocate a new buffer to store it */ pReadAppConfig = OsaAllocZeroMemory(AppConfigHr.fileBodySize); if (pReadAppConfig == PNULL) { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_buff_e_1, P_ERROR, 2, // "NVM: 'qxappconfig.nvm', version: %d, can not allo memsize: %d, use the default value", // AppConfigHr.version, AppConfigHr.fileBodySize); #ifdef USING_PRINTF printf("NVM: 'qxappconfig.nvm', version: %d, can not allo memsize: %d, use the default value", AppConfigHr.version, AppConfigHr.fileBodySize); #endif OsaFclose(fp); setDefaultAppDataValue(); appSaveConfig(); return; } //needAdjust = TRUE; } else if (AppConfigHr.fileBodySize != sizeof(AppNVMData)) //file version is the same, but NVM file size not right { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_2, P_ERROR, 2, // "MW NVM: 'midwareconfig.nvm', file body size not right: (%u/%u), use the defult value", // AppConfigHr.fileBodySize, sizeof(AppNVMData)); #ifdef USING_PRINTF printf("MW NVM: 'midwareconfig.nvm', file body size not right: (%u/%u), use the defult value", AppConfigHr.fileBodySize, sizeof(AppNVMData)); #endif OsaFclose(fp); setDefaultAppDataValue(); appSaveConfig(); return; } /* * read the file body */ readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp); crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData)); readtimes = 0; //while (readtimes<=5 && crcCheck != AppConfigHr.checkSum) while (readtimes<=5 && readCount != 1) { readtimes++; readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp); crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData)); } if (readtimes>5) { //ECOMM_TRACE(UNILOG_PLA_MIDWARE, AppLoadNvmConfig_3, P_ERROR, 2, // "NVM: 'qxappconfig.nvm', can't read body, or body not right, (%u/%u), use the defult value", // crcCheck, AppConfigHr.checkSum); #ifdef USING_PRINTF printf(" NVM: 'qxappconfig.nvm', can't read body, or body not right, (%u/%u), use the defult value\n ", crcCheck, AppConfigHr.checkSum); #endif OsaFclose(fp); setDefaultAppDataValue(); appSaveConfig(); /* if (needAdjust) { OsaFreeMemory(&pReadAppConfig); } */ return; } #if 0 if (needAdjust) { OsaFclose(fp); setDefaultAppDataValue(); appSaveConfig(); /* free memory */ OsaFreeMemory(&pReadAppConfig); } #endif #if 0 int i=0; printf("AppConfigHeader:\n"); printf("%d,%d,%d\n",AppConfigHr.fileBodySize,AppConfigHr.version,AppConfigHr.checkSum); printf("AppConfigFileBody:\n"); printf("%d,%d,%d\n",AppNVMData.chargEndWorkTime,AppNVMData.wakeupWorkTime,AppNVMData.sleepTime); printf("\n"); #endif OsaFclose(fp); return; } //if the AppNVMData.version(read form nvm) != APP_CONFIG_FILE_LATEST_VERSION, it will setDefaultAppDataValue() //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 static void setDefaultAppDataValue(void) { UINT8 i = 0; memset(&AppNVMData, 0x00, sizeof(AppNVMDataType)); for(i=0;i5) { OsaFclose(fp); setDefaultAppDataInfo(); appSaveDataInfo(); return; } if(AppDataHr.fileBodySize==sizeof(AppDataInfo))//结构体数据没变动,可直接读出 { readCount = OsaFread(pReadAppConfig, AppDataHr.fileBodySize, 1, fp); //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData)); readtimes = 0; while (readtimes<=5 && readCount != 1) { readtimes++; readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp); //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData)); } } else { setDefaultAppDataInfo(); readCount = OsaFread(pReadAppConfig, AppDataHr.fileBodySize, 1, fp); //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData)); readtimes = 0; while (readtimes<=5 && readCount != 1) { readtimes++; readCount = OsaFread(pReadAppConfig, AppConfigHr.fileBodySize, 1, fp); //crcCheck = OsaCalcCrcValue((UINT8 *)pReadAppConfig, sizeof(AppNVMData)); } appSaveDataInfo(); #ifdef USING_PRINTF printf(" Struct update\n"); #endif } OsaFclose(fp); return; } //无法找到文件时的第一次启动,后续不会启动此函数 static void setDefaultAppDataInfo(void) { memset(&AppDataInfo, 0x00, sizeof(AppDataInfo)); AppDataInfo.appDataModify = false; AppDataInfo.BmsChrgInfoSendFreq = 5; AppDataInfo.BmsDisChrgInfoSendFreq = 30; AppDataInfo.GpsChrgInfoSendFreq = 30; AppDataInfo.GpsDisChrgInfoSendFreq = 5; AppDataInfo.BattCurrentNegFlag = 1; AppDataInfo.CumulativeCapacity = 0; return; }