/*
 * @Description: 存储模块-svc层
 * @Author: yangsw
 * @Date: 2021-05-20 18:35:04
 * @LastEditTime: 2024-01-08 18:38:29
 * @LastEditors: LiDa
 * @Reference: 
 */
#include "svc_flash.h"
#include "pulse/svc/svc_pulse.h"
#include "log/svc/svc_log.h"
#include "util/util_data.h"
#include "util/util_time.h"
#include "cloud/svc/svc_cloud_protocol.h"
#include "cloud/svc/svc_cloud.h"
#include "rtc/svc/svc_rtc.h"
#include "bat/svc/svc_bat.h"
#include "ota/svc/svc_ota.h"

#include "sr_log.h"
#include "sr_fal.h"

S_Flash_Data s_flash_data;
static SR_FAL_PART_T *paramPart = SR_NULL;  //分区指针

// S_Flash_Data s_flash_data;
// __no_init S_Flash_Manage s_flash_manage;
// static void Svc_Flash_Dayusage_Init(void);
// static void Svc_Flash_ReadDayusage_Test(void);
S_Flash_Day_Usage ReadDayUsage;//占用大量栈空间，导致栈溢出,所以将该变量移到全局区
static E_Result_State Device_Para_init(void);
/**
 * @brief: 存储模块初始化
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Init(void)
{ 
    
  SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);
    			
  //注：上电初始化阶段，FAL的fal_part_init()会初始化分区，内部会初始化flash

  //分区表查看和分区获取
  SR_FalShowPartTable();
  paramPart = SR_FalPartFind(FLASH_PARAM_PART_NAME);


  if(Svc_Com_Sys_Get_Work_Mode() == E_FactoryTestMode)
  {
    Svc_Com_Delay_Ms(64,500);

    //扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    gw_u16 u16Secoff = FLASH_DEVICE_SECURITY_ADDR/FLASH_SECTOR_SIZE;
	  SR_FalPartErase(paramPart, u16Secoff, 1);
    
    u16Secoff = FLASH_DEVICE_SECURITY_BAK_ADDR/FLASH_SECTOR_SIZE;
	  SR_FalPartErase(paramPart, u16Secoff, 1);
    
    for(gw_u8 i = 0; i < 100; i++)
    {
          u16Secoff = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE +i;  //*
	        SR_FalPartErase(paramPart, u16Secoff, 1);  
          Svc_Com_Delay_Ms(2,64);	
    }

    u16Secoff = FLASH_USAGE_ADDR/FLASH_SECTOR_SIZE;
	  SR_FalPartErase(paramPart, u16Secoff, 1);  
    
    u16Secoff = FLASH_USAGE_BAK_ADDR/FLASH_SECTOR_SIZE;
	  SR_FalPartErase(paramPart, u16Secoff, 1);  
    
    u16Secoff = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+2;  //与上面*重复了？？？
	  SR_FalPartErase(paramPart, u16Secoff, 1);  

    u16Secoff = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+3;  //与上面*重复了？？？
	  SR_FalPartErase(paramPart, u16Secoff, 1);  

    u16Secoff = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+4;  //与上面*重复了？？？
	  SR_FalPartErase(paramPart, u16Secoff, 1);  

    u16Secoff = FLASH_DEVICE_PARA_ADDR /FLASH_SECTOR_SIZE;
	  SR_FalPartErase(paramPart, u16Secoff, 1);  

    u16Secoff = FLASH_DEVICE_PARA_BAK_ADDR /FLASH_SECTOR_SIZE;
	  SR_FalPartErase(paramPart, u16Secoff, 1);  

  }
  else
  {
#if 0
    
    Svc_Com_Delay_Ms(64,500);
    gw_u16 u16Secoff = FLASH_DEVICE_SECURITY_ADDR/FLASH_SECTOR_SIZE;
    Bsp_Flash_Erase_Sector(u16Secoff);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    gw_u16 u16Secoff1 = FLASH_DEVICE_SECURITY_BAK_ADDR/FLASH_SECTOR_SIZE;
    Bsp_Flash_Erase_Sector(u16Secoff1);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    for(gw_u8 i = 0; i < 100; i++)
    {
          gw_u16 u16Secoff = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE +i;
          Bsp_Flash_Erase_Sector(u16Secoff);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
          Svc_Com_Delay_Ms(2,64);	
    }
    gw_u16 u16Secoff2 = FLASH_USAGE_ADDR/FLASH_SECTOR_SIZE;
    Bsp_Flash_Erase_Sector(u16Secoff2);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    gw_u16 uSecoff3 = FLASH_USAGE_BAK_ADDR/FLASH_SECTOR_SIZE;
    Bsp_Flash_Erase_Sector(uSecoff3);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对  
    gw_u16 Secoff4 = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+2;
    Bsp_Flash_Erase_Sector(Secoff4);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    gw_u16 Secoff7 = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+3;
    Bsp_Flash_Erase_Sector(Secoff7);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    gw_u16 Secoff8 = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+4;
    Bsp_Flash_Erase_Sector(Secoff8);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    gw_u16 Secoff5 = FLASH_DEVICE_PARA_ADDR /FLASH_SECTOR_SIZE;
    Bsp_Flash_Erase_Sector(Secoff5);//<<<<<<<<<<<<<<<扇区擦除失败处理，若 扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
    gw_u16 Secoff6 = FLASH_DEVICE_PARA_BAK_ADDR /FLASH_SECTOR_SIZE;
    Bsp_Flash_Erase_Sector(Secoff6);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对  
   
    // Device_Para_init(); 
  #endif
    Svc_Flash_Power_Off();
    Svc_Flash_Read_User_Data();
    // Svc_Flash_Dayusage_Init();
    // Svc_Flash_ReadDayusage_Test();
		Svc_Rtc_Get_Time_Flash();    
  }

    //  s_flash_data.s_usage_info.u8LastHistoryUpdataTime[0] = 23;
    //  s_flash_data.s_usage_info.u8LastHistoryUpdataTime[1] = 6;
    //  s_flash_data.s_usage_info.u8LastHistoryUpdataTime[2] = 15;

		/*上报重连等待时间 */  
			//s_flash_data.s_para.u8ResendWaiteTime=20;
//	  /* ASCII 码 xxx.xxx.xxx.xxx,xxxx IP 和端口 用,分开*/    
			//memset(s_flash_data.s_para.s_nb_info.IpInfo,0,sizeof(s_flash_data.s_para.s_nb_info.IpInfo));
//	  memset(s_flash_data.s_para.u8Apn,0,sizeof(s_flash_data.s_para.u8Apn));
			//memcpy(s_flash_data.s_para.s_nb_info.IpInfo,"221.229.214.202,5683",20);  
			//memcpy(s_flash_data.s_para.s_nb_info.IpInfo,"117.60.157.137,5683",20);  
			//memcpy(s_flash_data.s_para.s_nb_info.IpInfo,"180.101.147.115,5683",20);  
			
			//s_flash_data.s_para.u8DenseStartTime=12;   
//		memcpy(s_flash_data.s_para.u8Apn,"ctnb",strlen("ctnb"));  

//    /* PLMN*/    
//	  memcpy(s_flash_data.s_para.u8Plmn,"46011",strlen("46011"));  
//    /* Band*/   		
//		s_flash_data.s_para.u8Band=5;
//    /*强制写参数，测试用*/
//		s_flash_data.s_para.u8CommCycle=2;
			//s_flash_data.s_para.u32ReportCycle=0;
			//s_flash_data.s_para.u32ReportCycle=86400;
			//s_flash_data.s_usage_info.u8LastUpdataTime[1]=12;
			//s_flash_data.s_usage_info.u8LastUpdataTime[2]=2;
//    // s_flash_data.s_para.s_nb_info.pu16ServerPort=60005;
//     s_flash_data.s_security.pu8MeterNum[0]=0x12;
//     s_flash_data.s_security.pu8MeterNum[1]=0x34;
//     s_flash_data.s_security.pu8MeterNum[2]=0x56;
//     s_flash_data.s_security.pu8MeterNum[3]=0x78;
//	   s_flash_data.s_security.pu8MeterNum[4]=0x90;
//     s_flash_data.s_security.pu8MeterNum[5]=0x12;
//     s_flash_data.s_security.pu8MeterNum[6]=0x34;
//		 
//		 
//		  /*设备类型*/
//			s_flash_data.s_security.pu8MeterType=1;
//		 /*设备子类型*/
//			s_flash_data.s_security.pu8MeterChildType=2;	

    // s_flash_data.s_para.s_nb_info.pu8ServerIp[0]=47;
    // s_flash_data.s_para.s_nb_info.pu8ServerIp[1]=96;
    // s_flash_data.s_para.s_nb_info.pu8ServerIp[2]=69;
    // s_flash_data.s_para.s_nb_info.pu8ServerIp[3]=160;
    /*强制写参数，测试用*/
    // /*欠压导致flash无法读写，MCU不再进行工作，直接睡死*/
    // if(s_flash_data.u8flashCheckFail==1){
    //     while(1){
    //         Svc_Lp_No_Wakeup_Sleep();
    //     }
    // }
		
		//memcpy(s_flash_data.s_security.pu8RunKey,"1234567812345678",16);  
//		s_flash_data.s_security.pu8RunKey[0]=1;
//		s_flash_data.s_security.pu8RunKey[1]=2;
//		s_flash_data.s_security.pu8RunKey[2]=3;
//		s_flash_data.s_security.pu8RunKey[3]=4;
//		s_flash_data.s_security.pu8RunKey[4]=5;
//		s_flash_data.s_security.pu8RunKey[5]=6;
//		s_flash_data.s_security.pu8RunKey[6]=7;
//		s_flash_data.s_security.pu8RunKey[7]=8;
//		s_flash_data.s_security.pu8RunKey[8]=1;
//		s_flash_data.s_security.pu8RunKey[9]=2;
//		s_flash_data.s_security.pu8RunKey[10]=3;
//		s_flash_data.s_security.pu8RunKey[11]=4;
//		s_flash_data.s_security.pu8RunKey[12]=5;
//		s_flash_data.s_security.pu8RunKey[13]=6;
//		s_flash_data.s_security.pu8RunKey[14]=7;
//		s_flash_data.s_security.pu8RunKey[15]=8;
}

// #define p 8
// static void Svc_Flash_ReadDayusage_Test(void){
//       gw_u8 u8StartTime[6];
//       for(gw_u8 j = 1; j <= 5; j++)
//       {
//         //密集用量测试
//           u8StartTime[0] = 23;
//           u8StartTime[1] = p;
//           u8StartTime[2] = j;
//           u8StartTime[3] = 0;
//           u8StartTime[4] = 0;
//           u8StartTime[5] = 0;
 
//           if(Read_Day_Usage(&ReadDayUsage,u8StartTime)==E_STATE_ERROR){        //flash异常，无法写入        
//               //记录异常事件
//               // Svc_Cloud_Meter_Err_Record(E_MEC_DataLoss);
//               //
//               SR_LOG(INFO,"%s error\r\n",__FUNCTION__);		
//               return;
//           } 
//         Svc_Com_Delay_Ms(2,64);	           
//       }
// }

/**
 * @brief: 天用量信息初始化
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
// #define t 6
// static void Svc_Flash_Dayusage_Init(void){
//       // S_Flash_Day_Usage	  *ps_day_usage = &s_flash_data.s_usage_info.s_day_usage;	
//       S_Flash_Dense_Usage *ps_usage_dense_data = &s_flash_data.s_usage_info.s_day_usage.s_Dense_usage;
//       S_Flash_Real_Usage  *ps_real_usage = &s_flash_data.s_usage_info.s_day_usage.s_real_usage;
//       S_Flash_Hour_Usage  *ps_hour_usage = &s_flash_data.s_usage_info.s_day_usage.s_hour_usage;   
//       memset(ps_usage_dense_data,0,sizeof(S_Flash_Dense_Usage));
      
//       for(gw_u8 j = 1; j <= 28; j++)
//       {
//         //密集用量测试
//           ps_usage_dense_data->u8StartTime[0] = 23;
//           ps_usage_dense_data->u8StartTime[1] = t;
//           ps_usage_dense_data->u8StartTime[2] = j;
//           ps_usage_dense_data->u8StartTime[3] = 0;
//           ps_usage_dense_data->u8StartTime[4] = 0;
//           ps_usage_dense_data->u8StartTime[5] = 0;
//           ps_usage_dense_data->u8RecordNumb = 48;
//           for(gw_u8 i = 0; i<48; i++)
//           {
//               ps_usage_dense_data->u16RecordUsage[i][0] = i;
//               ps_usage_dense_data->u16RecordUsage[i][1] = i;
//           }
//           //实时用量测试
//           ps_real_usage->u16BatVol = 300;
//           ps_real_usage->u16MaxUsage = 3000;
//           ps_real_usage->u32TotalUsage = 65535;
//           ps_real_usage->u32TotalUsagePosMidnight = 3000;
//           ps_real_usage->u32TotalUsageNegMidnight  =3000;
//           ps_real_usage->u8InfoTime[0] = 23;
//           ps_real_usage->u8InfoTime[1] = t; 
//           ps_real_usage->u8InfoTime[2] = j;
//           ps_real_usage->u8InfoTime[3] = 0;
//           ps_real_usage->u8InfoTime[4] = 0;
//           ps_real_usage->u8InfoTime[5] = 0;

//           ps_real_usage->u8MaxUseTime[0] = 23;
//           ps_real_usage->u8MaxUseTime[1] = t; 
//           ps_real_usage->u8MaxUseTime[2] = j;
//           ps_real_usage->u8MaxUseTime[3] = 0;
//           ps_real_usage->u8MaxUseTime[4] = 0;
//           ps_real_usage->u8MaxUseTime[5] = 0;
//           //小时用量测试
//           ps_hour_usage->u8RecordNumb = 48;
//           for(gw_u8 i = 0; i<48; i++)
//           {
//               ps_hour_usage->u16RecordUse[i] = i;
//           }
//           s_flash_data.s_usage_info.s_day_usage.u8StartTime[0] = 23;
//           s_flash_data.s_usage_info.s_day_usage.u8StartTime[1] = t;
//           s_flash_data.s_usage_info.s_day_usage.u8StartTime[2] = j;
//           s_flash_data.s_usage_info.s_day_usage.u8StartTime[3] = 0;
//           s_flash_data.s_usage_info.s_day_usage.u8StartTime[4] = 0;
//           s_flash_data.s_usage_info.s_day_usage.u8StartTime[5] = 0;
//           if(Svc_Flash_Write_Day_Usage(&s_flash_data.s_usage_info.s_day_usage)==E_STATE_ERROR){                 //flash异常，无法写入        
//               //记录异常事件
//               // Svc_Cloud_Meter_Err_Record(E_MEC_DataLoss);
//               //
//               SR_LOG(INFO,"%s error\r\n",__FUNCTION__);		
//               return;
//           }  
//                   Svc_Com_Delay_Ms(2,64);	         
//       }
// }
/**
 * @brief: flash电源打开
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Power_On(void){
#if FLASH_W25X_ENABLE
		Bsp_Flash_Init();
    Bsp_Flash_Power_On();		
#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Power_On();
#endif
    Bsp_Iwdg_Feed();//喂狗<<  
}

/**
 * @brief: flash电源关闭
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Power_Off(void){

   Bsp_Iwdg_Feed();//喂狗<<
    
#if FLASH_W25X_ENABLE  
    Bsp_Flash_Power_Off();  
		// Svc_Flash_Lp();
#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Power_Off();
#endif  
}
/**
 * @brief: 存储模块唤醒后的初始化
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Wakeup_Init(void){ 
#if FLASH_W25X_ENABLE
    Bsp_Flash_Init();
#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Init();
#endif  
    Svc_Flash_Power_Off();
}
/**
 * @brief: 获取存储模块相关数据结构体指针
 * @param  {void}
 * @return {S_Flash_Data*} 存储模块相关数据结构体指针
 * @note: 
 * @see: 
 */
S_Flash_Data* Svc_Flash_Get_Data(void){
    return &s_flash_data;
}

/**
 * @brief: 设备安全信息初始化
 * @param  {void}
 * @return {E_Result_State} 执行结果
 * @note:  这个函数没有调用 - 22.8.16yess
 * @see: 
 */
static E_Result_State Device_Security_init(void){
    S_Flash_Device_Security *ps_device_security=&s_flash_data.s_security;
    memset(ps_device_security,0,sizeof(S_Flash_Device_Security));
    ps_device_security->u8Sig=FLASH_SIG_USED;
   
    /*设备类型*/
    ps_device_security->pu8MeterType=1;
		/*设备子类型*/
    ps_device_security->pu8MeterChildType=2;	
    /*设备计量模式*/
    ps_device_security->pu8MeterDetectModel=5;     
     /*厂家编号*/
    ps_device_security->pu8FactoryNum=3; 
    /*协议版本*/
    ps_device_security->u8ProtocolVer=2;
    /*表号*/    
	  ps_device_security->pu8MeterNum[0]=0X12;
	  ps_device_security->pu8MeterNum[1]=0X34;
	  ps_device_security->pu8MeterNum[2]=0X56;
	  ps_device_security->pu8MeterNum[3]=0X78;
		ps_device_security->pu8MeterNum[4]=0X90;
		ps_device_security->pu8MeterNum[5]=0X12;
		ps_device_security->pu8MeterNum[6]=0X34;
    /*运行密钥*/
		memcpy(s_flash_data.s_security.pu8RunKey,"1234567812345678",16);  
		// memcpy(s_flash_data.s_security.product_id,"1234567890123456",16);      
		
    /*软件版本*/
    ps_device_security->pu8SoftVer=SOFT_VERSION; 

    if(Svc_Flash_Write_Device_Security(&s_flash_data.s_security)==E_STATE_ERROR){  //flash异常，无法写入            
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 设备参数初始化
 * @param  {void}
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 */
static E_Result_State Device_Para_init(void){
    S_Flash_Device_Para *ps_device_para=&s_flash_data.s_para;
    memset(ps_device_para,0,sizeof(S_Flash_Device_Para));
    /*超大切断流量，（参数可由后台设置）*/   
    ps_device_para->u32LargeFlowCutPoint=PLUSE_LARGE_ALARM_FLOW;
    /*反流切断流量，（参数可由后台设置）*/
    ps_device_para->u32NegFlowCutPoint=PLUSE_NEG_ALARM_FLOW;
    /*超大流量持续时间,单位：分，*/
    ps_device_para->u8LargeFlowDuration=30;
    /*反流持续时间,单位：分，断*/
    ps_device_para->u8NegFlowDuration=30;
    /*电压报警阀值,单位：0.01V*/    
    ps_device_para->u16BatAlarmVolt=330;
    /* ASCII 码 xxx.xxx.xxx.xxx,xxxx IP 和端口 用,分开*/    
    memcpy(ps_device_para->s_nb_info.IpInfo,"221.229.214.202,5683",20);   // 117.60.157.137,5683
    /* APN信息*/
    memcpy(ps_device_para->s_nb_info.u8Apn,"ctnb",strlen("ctnb"));   
     /* PLMN*/    
	  memcpy(ps_device_para->s_nb_info.u8Plmn,"46011",strlen("46011"));  
    /* Band*/   		
		s_flash_data.s_para.s_nb_info.u8Band=5;
    /* 上报重连次数*/
    ps_device_para->u8ResendTimes=2;      
    /*上报重连等待时间 */  
    ps_device_para->u8ResendWaiteTime=20;
		/*通讯间隔，单位：秒，*/
		s_flash_data.s_para.u32ReportCycle=86400;
		/*上报区间*/
		s_flash_data.s_para.u16ReportInterval=8;	//0--4点
    /*通讯间隔，单位：小时，*/
    ps_device_para->u8CommCycle=24;  
    /*周期采样间隔*/
    ps_device_para->u8HourPeriodTime=30; 
     /*密集采样间隔*/
    ps_device_para->u16DensePeriodTime=5;   
    /*周期上报离散起始 时间*/     
    //memset(ps_device_para->u8DiscreteStartTime,0,6);
    /*周期上报离散结束 时间*/
    //memset(ps_device_para->u8DiscreteStopTime,0,6);
    ps_device_para->u8DiscreteStopTime[3]=4;
    /*周期上报离散估长时间*/
    ps_device_para->u8DiscreteStepTime=1;  
    /*密集流量使能*/
    ps_device_para->u8DenseEnable=0;
    /*密集流量开始时间，默认值0,即0点开始*/  
    ps_device_para->u8DenseStartTime=0;   
    /*终端启停设置*/
    ps_device_para->u8StartStopEnable=0;  
    /*PN 脉冲常数 1-1L/P； 2-10L/P； 3-100L/P； 4-1000L/P；*/   
    ps_device_para->u16PluseEqu=1; 
    /*设置最大计量数 最大为 8 位*/
    ps_device_para->u32MaxTotalUsage=99999999;     
    /*设置表底数*/
    ps_device_para->u32BaseUsage=0; 

    if(Svc_Flash_Write_Device_Para(&s_flash_data.s_para)==E_STATE_ERROR){                 //flash异常，无法写入            
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 用量信息初始化
 * @param  {void}
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 */
static E_Result_State Usage_Info_Init(void){
		gw_u8 TimeDate[6]={21,1,1,0,0,0};
    S_Flash_Usage_Info *ps_usage_info=&s_flash_data.s_usage_info;
    memset(ps_usage_info,0,sizeof(S_Flash_Usage_Info)); 		
		ps_usage_info->pu32SystemTime= Util_Time_Date_To_Timestamp(TimeDate);
		ps_usage_info->u32LastSystemTime=ps_usage_info->pu32SystemTime;
    if(Svc_Flash_Write_Usage(&s_flash_data.s_usage_info)==E_STATE_ERROR){    //flash异常，无法写入               
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: flash 分区读取数据
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u8} *out_buff 读取数据存储的地址指针
 * @param {gw_u32} read_addr 待读取数据flash存放地址
 * @param {gw_u16} read_num 读取数据字节数
 */
void Svc_Flash_Read(gw_u8 *out_buff,gw_u32 read_addr,gw_u16 read_num){
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);
    Svc_Flash_Power_On();
		//Svc_Com_Delay_Ms(100,COM_SYS_CLK);  
		// HW_Delay_ms(2);
    // Svc_Timer_Delay_Ms(5);
    Svc_Com_Delay_Ms(2,64);	
#if FLASH_W25X_ENABLE
    //Bsp_Flash_Read(out_buff,read_addr,read_num);
	  SR_FalPartRead(paramPart,read_addr,out_buff,read_num);

#elif EEPROM_P24C_ENABLE
    Bsp_Eeprom_Read(out_buff,read_addr,read_num);
#endif    
		Svc_Flash_Power_Off();
}

/**
 * @brief: flash写数据
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {gw_u8*} data 待写数据存储的地址指针
 * @param {gw_u32} write_addr 数据flash存放地址
 * @param {gw_u16} write_num 写数据字节数
 */
E_Result_State Svc_Flash_Write(gw_u8* data,gw_u32 write_addr,gw_u16 write_num){
    S_Bat s_bat;
    s_bat=Svc_Bat_Get_Data();
    /*供电不足，不允许写数据*/
    if(s_bat.u16BatValtage<BAT_FLASH_LOW){
        SR_LOG(ERR,"bat low");
        return E_STATE_ERROR;
    }		
    Svc_Flash_Power_On();
		//Svc_Com_Delay_Ms(100,COM_SYS_CLK);  
		// HW_Delay_ms(2);
    Svc_Com_Delay_Ms(2,64);	
    //for(gw_s16 i=0;i<3;i++){
    #if FLASH_W25X_ENABLE
        //Bsp_Flash_Write(data,write_addr,write_num);
	      SR_FalPartWrite(paramPart,write_addr,data,write_num);

				Svc_Flash_Power_Off();
        return E_STATE_SUCCESS;
    #elif EEPROM_P24C_ENABLE
        if(Bsp_Eeprom_Write(data,write_addr,write_num)==E_STATE_SUCCESS){
            return E_STATE_SUCCESS;
        }
    #endif       
    // }
    // return E_STATE_ERROR;

}
/**
 * @brief: flash写数据，无擦除
 * @return {E_Result_State} 执行结果
 * @note: 无擦除，需保证写入位置为0xFF，不能跨扇区
 * @see: 
 * @param {gw_u8*} data 待写数据存储的地址指针
 * @param {gw_u32} write_addr 数据flash存放地址
 * @param {gw_u16} write_num 写数据字节数
 */
static E_Result_State Svc_Flash_Write_No_Erase(gw_u8* data,gw_u32 write_addr,gw_u16 write_num)
{
  gw_u32 u32BaseAddr = 0;
  S_Bat s_bat;
  s_bat=Svc_Bat_Get_Data();
  /*供电不足，不允许写数据*/
  if(s_bat.u16BatValtage<320){
      SR_LOG(ERR,"bat low!!");
      return E_STATE_ERROR;
  }
  u32BaseAddr = write_addr/FLASH_SECTOR_SIZE;
  if((write_addr + write_num)/FLASH_SECTOR_SIZE != u32BaseAddr){//跨扇区
      SR_LOG(ERR,"%s->Out of sector!!",__FUNCTION__);
      return E_STATE_ERROR;
  }
  Svc_Flash_Power_On();
  //Bsp_Flash_Write_No_Check(data,write_addr,write_num);
  //注意：虽然该函数内部会判断是否要擦除扇区，但如果待写入区域已全是0xFF，该函数不会执行擦除
	SR_FalPartWrite(paramPart,write_addr,data,write_num);

  Svc_Flash_Power_Off(); 
  return E_STATE_SUCCESS;   
}

/**
 * @brief: flash写OTA数据
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {gw_u8*} data 待写数据存储的地址指针
 * @param {gw_u32} write_addr 数据flash存放地址
 * @param {gw_u16} write_num 写数据字节数
 */
E_Result_State Svc_Flash_Write_Ota(gw_u8* data,gw_u32 write_addr,gw_u16 write_num){
    S_Bat s_bat;
    gw_u32 secpos;
    gw_u16 secoff;
    s_bat=Svc_Bat_Get_Data();
    /*供电不足，不允许写数据*/
    if(s_bat.u16BatValtage<BAT_FLASH_LOW){
        SR_LOG(ERR,"bat low");
        return E_STATE_ERROR;
    }		
    Svc_Com_Delay_Ms(2,64);	
    Svc_Flash_Power_On();
    #if FLASH_W25X_ENABLE
    secpos=write_addr/FLASH_SECTOR_SIZE;//扇区地址 0~511 for w25x16
    secoff=write_addr%FLASH_SECTOR_SIZE;//在扇区内的偏移
    if(secoff==0){//写扇区的第一个地址要擦除
        //Bsp_Flash_Erase_Sector(secpos);
	      SR_FalPartErase(paramPart, secpos, 1);

    }
    //Bsp_Flash_Write_No_Check(data,write_addr,write_num);
	  SR_FalPartWrite(paramPart,write_addr,data,write_num);

		Svc_Flash_Power_Off();
    return E_STATE_SUCCESS;
    #endif       
}

/**
 * @brief: 读取设备安全信息
 * @return {E_Result_State}
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
static E_Result_State Read_Device_Security(S_Flash_Device_Security *security){
    gw_u8 sum;
    gw_u8* ptr=(gw_u8*)security;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);
    Svc_Com_Delay_Ms(2,64);	
    Svc_Flash_Read(ptr,FLASH_DEVICE_SECURITY_ADDR,sizeof(S_Flash_Device_Security));
    /*标志检查*/
    if(security->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }  
    /*和校验检查*/
    sum=Util_Data_Check_Sum(ptr,(gw_u32)&security->u8CheckSum-(gw_u32)security);
    if(sum!=security->u8CheckSum)
    {
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    SR_LOG(INFO,"%s->read ok",__FUNCTION__);
    return E_STATE_SUCCESS;
}

#if FLASH_BAK_ENABLE
/**
 * @brief: 读取备份设备安全信息
 * @return {E_Result_State}
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
static E_Result_State Read_Device_Security_Bak(S_Flash_Device_Security *security){
    gw_u8 sum;
    gw_u8* ptr=(gw_u8*)security;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);	
    Svc_Com_Delay_Ms(2,64);	
    Svc_Flash_Read(ptr,FLASH_DEVICE_SECURITY_BAK_ADDR,sizeof(S_Flash_Device_Security));
    /*标志检查*/
    if(security->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }  
    /*和校验检查*/
    sum=Util_Data_Check_Sum(ptr,(gw_u32)&security->u8CheckSum-(gw_u32)security);
    if(sum!=security->u8CheckSum)
    {
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    SR_LOG(INFO,"%s->read ok",__FUNCTION__);
    return E_STATE_SUCCESS;
}
#endif

/**
 * @brief: 写设备安全信息
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
static E_Result_State Write_Device_Security(S_Flash_Device_Security *security){
    gw_u8* ptr=(gw_u8*)security;
    S_Flash_Device_Security readSecurity;
    security->u8Sig=FLASH_SIG_USED;
    security->u8CheckSum=Util_Data_Check_Sum(ptr,(gw_u32)&security->u8CheckSum-(gw_u32)security);
    /*写数据*/
    Svc_Flash_Write(ptr,FLASH_DEVICE_SECURITY_ADDR,sizeof(S_Flash_Device_Security));
#if FLASH_BAK_ENABLE
    /*写备份数据*/
    Svc_Flash_Write(ptr,FLASH_DEVICE_SECURITY_BAK_ADDR,sizeof(S_Flash_Device_Security));
#endif
    /*读写入数据进行校验*/
    if(Read_Device_Security(&readSecurity)==E_STATE_ERROR){
        SR_LOG(ERR,"%s->write fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    return  E_STATE_SUCCESS;
}

/**
 * @brief: 写设备安全参数-失败重写
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Security} *security 设备安全参数
 */
E_Result_State Svc_Flash_Write_Device_Security(S_Flash_Device_Security *security){
    gw_s8 i;
    for(i=0;i<FLASH_REPEAT_WRITE_NUM;i++){
        Bsp_Iwdg_Feed();
				// Svc_Wdg_Feed(1);	
        if(Write_Device_Security(security)==E_STATE_SUCCESS){
          Bsp_Iwdg_Feed();
						// Svc_Wdg_Feed(1);	
            return E_STATE_SUCCESS;
        }
    }
    Bsp_Iwdg_Feed();
		// Svc_Wdg_Feed(1);	
    return E_STATE_ERROR;
}

/**
 * @brief: 读设备参数
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Para} *para 设备参数
 */
static E_Result_State Read_Device_Para(S_Flash_Device_Para *para){
    gw_u8 sum;
    gw_u8* ptr=(gw_u8*)para;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);	
    // Svc_Timer_Delay_Ms(5);
    Svc_Flash_Read(ptr,FLASH_DEVICE_PARA_ADDR,sizeof(S_Flash_Device_Para));
    if(para->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    sum=Util_Data_Check_Sum(ptr,(gw_u32)&para->u8CheckSum-(gw_u32)para);
    if(sum!=para->u8CheckSum)
    {
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    SR_LOG(INFO,"%s->read ok",__FUNCTION__);
    return E_STATE_SUCCESS;
}

#if FLASH_BAK_ENABLE
/**
 * @brief: 读备份设备参数
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Para} *para 设备参数
 */
static E_Result_State Read_Device_Para_Bak(S_Flash_Device_Para *para){
    gw_u8 sum;
    gw_u8* ptr=(gw_u8*)para;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);	
    // Svc_Timer_Delay_Ms(1);
    Svc_Flash_Read(ptr,FLASH_DEVICE_PARA_BAK_ADDR,sizeof(S_Flash_Device_Para));
    if(para->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    sum=Util_Data_Check_Sum(ptr,(gw_u32)&para->u8CheckSum-(gw_u32)para);
    if(sum!=para->u8CheckSum)
    {
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    SR_LOG(INFO,"%s->read ok",__FUNCTION__);
    return E_STATE_SUCCESS;
}
#endif

/**
 * @brief: 写设备参数
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Para} *para 设备参数
 */
static E_Result_State Write_Device_Para(S_Flash_Device_Para *para){
    gw_u8* ptr=(gw_u8*)para;
    S_Flash_Device_Para readPara;
    para->u8Sig=FLASH_SIG_USED;
    para->u8CheckSum=Util_Data_Check_Sum(ptr,(gw_u32)&para->u8CheckSum-(gw_u32)para);		
    Svc_Flash_Write(ptr,FLASH_DEVICE_PARA_ADDR,sizeof(S_Flash_Device_Para));		
#if FLASH_BAK_ENABLE		
    Svc_Flash_Write(ptr,FLASH_DEVICE_PARA_BAK_ADDR,sizeof(S_Flash_Device_Para));
#endif		
    if(Read_Device_Para(&readPara)==E_STATE_ERROR){
        SR_LOG(ERR,"%s->write fail",__FUNCTION__);				
        return E_STATE_ERROR;
    }		
    return  E_STATE_SUCCESS;
}

/**
 * @brief: 写设备参数-失败重写
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Para} *para 设备参数
 */
E_Result_State Svc_Flash_Write_Device_Para(S_Flash_Device_Para *para){
    gw_s8 i;
    for(i=0;i<FLASH_REPEAT_WRITE_NUM;i++){
      Bsp_Iwdg_Feed();
				// Svc_Wdg_Feed(1);	
        if(Write_Device_Para(para)==E_STATE_SUCCESS){
          Bsp_Iwdg_Feed();
						// Svc_Wdg_Feed(1);	
            return E_STATE_SUCCESS;
        }
    }
    Bsp_Iwdg_Feed();
		// Svc_Wdg_Feed(1);	
    return E_STATE_ERROR;
}

/**
 * @brief: 检查地址是否全为空（0xff）
 * @return {E_Result_State} 执行结果
 * @note:  
 * @see:   
 * @param  {gw_u32} u32Addr 地址
 * @param  {gw_u16} u16Len  需检查的长度
 */
static E_Result_State Svc_Flash_Check_Addr_Empty(gw_u32 u32Addr, gw_u16 u16Len)
{
  const gw_u8 u8Compare[10] = {0xff, 0xff, 0xff, 0xff, 0xff, 
                               0xff, 0xff, 0xff, 0xff, 0xff};
  gw_u8 u8Data[10] = {0};
  
  while(1)
  {
    if(u16Len > 10)
    {
      Svc_Flash_Read(u8Data, u32Addr, 10);
      u16Len -= 10;     //剩余长度-10
      u32Addr += 10;    //地址+10
      if(memcmp(u8Data, u8Compare, 10)){return E_STATE_ERROR;}
    }
    else if(u16Len < 10)
    {
      Svc_Flash_Read(u8Data, u32Addr, u16Len);
      if(memcmp(u8Data, u8Compare, u16Len)){return E_STATE_ERROR;}
      
      break;
    }
    else if(u16Len == 10){break;}
  }
  
  return E_STATE_SUCCESS;
}

/**
 * @brief: 读用量信息
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Usage_Info} *usage_info 用量信息
 */
static E_Result_State Read_Usage(S_Flash_Usage_Info *usage_info){
    gw_u8 sum;
    gw_u8* ptr=(gw_u8*)usage_info;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);
    Svc_Com_Delay_Ms(2,64);	
    Svc_Flash_Read(ptr,FLASH_USAGE_ADDR,sizeof(S_Flash_Usage_Info));
    if(usage_info->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    sum=Util_Data_Check_Sum(ptr,(gw_u32)&usage_info->u8CheckSum-(gw_u32)usage_info);
    if(sum!=usage_info->u8CheckSum)
    {
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    SR_LOG(INFO,"%s->read ok",__FUNCTION__);
    return E_STATE_SUCCESS;
}

/**
 * @brief: 计算密集用量地址
 * @param  {gw_u16} u16DiffDay 与密集起始存储日期天数的差值
 * @return {gw_u32} 地址
 * @note:  不涉及扇区擦除
 * @see: 
 */
static gw_u32 Svc_Flash_Calc_DayUsage_Addr(gw_s32 s32DiffDay)//<<<<<<<<<<<<
{
  gw_u32 u32Addr;          //将地址初始化为无数据区
  gw_u8 u8IndexSector;
  #if LOG_FUNC_ENABLE
      SR_LOG(INFO,"%s->s16DiffDay:%d\r\n",__FUNCTION__, s32DiffDay);//测试用
  #endif
  if(s32DiffDay < 0)
  {
      if(s32DiffDay % 5 == 0){
         u8IndexSector = 256-(gw_u8)(s32DiffDay/5);
      }
      else{
          u8IndexSector = 256-(gw_u8)(s32DiffDay/5)+1;
      }
  }
  else{
      u8IndexSector = (s32DiffDay/5);
  }

  #if LOG_FUNC_ENABLE
      SR_LOG(INFO,"%s->u8IndexSector:%d\r\n",__FUNCTION__, u8IndexSector);//测试用
  #endif

  if(s32DiffDay < 0 && s32DiffDay >= -90)
  {
      u32Addr = FLASH_USAGE_DAY_START_ADDR + (s32DiffDay + (u8IndexSector)*5)*Size_Day_Usage;
      u32Addr += FLASH_SECTOR_SIZE*(19-u8IndexSector);      
  }
  else if(s32DiffDay >= 0 && s32DiffDay < 95)
  {
      u32Addr = FLASH_USAGE_DAY_START_ADDR + (s32DiffDay-u8IndexSector*5)*Size_Day_Usage;
      u32Addr += FLASH_SECTOR_SIZE*u8IndexSector;
  }
  #if LOG_FUNC_ENABLE
      SR_LOG(INFO,"%s->u32Addr:0x%lX\r\n",__FUNCTION__, u32Addr);//测试用
  #endif
  return u32Addr;
}

/**
 * @brief: 读数据
 * @return {E_Result_State} 执行结果
 * @note:  带校验，不会读取备用地址
 * @see:   23.3.21 - lida添加
 * @param {gw_u8} *u8Data 头指针
 */
static E_Result_State Svc_Flash_ReadDayUsage_Check(S_Flash_Day_Usage *day_usage, gw_u32 u32Addr)
{
    gw_u8* ptr=(gw_u8*)day_usage;    
    gw_u16 u8Sum = 0;
    Svc_Com_Delay_Ms(2,64);	   
    Svc_Flash_Read(ptr, u32Addr, Size_Day_Usage);
    /*校验存储标志*/
    if(day_usage->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
  //对比校验
    u8Sum = Util_Data_Check_Sum(ptr, (gw_u32)&day_usage->u8CheckSum-(gw_u32)day_usage);
    if(day_usage->u8CheckSum != u8Sum){
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
}

/**
 * @brief: 读天用量信息
 * @return {E_Result_State} 执行结果
 * @note:  23.3.21 - lida添加
 * @see: 
 * @param {S_Flash_Day_Usage} *day_usage 天用量信息
 */
E_Result_State Read_Day_Usage(S_Flash_Day_Usage *day_usage,gw_u8 *ReadTime){
    gw_u16 sum;
    gw_u32  u32SaveAddr=0;
    gw_s32 s32DayDiff;    
    gw_u8* ptr=(gw_u8*)day_usage;
  
    if(s_flash_data.s_para.u8Enable_StaDaySaveTime != 1){//表示还未存储过小时用气数据
        SR_LOG(ERR,"%s->You haven't started storing hourly data yet!!",__FUNCTION__);
        return E_STATE_ERROR;
    }
    /*计算对应日期的存储地址*/  
    s32DayDiff=Util_Time_Diff_Day(ReadTime,s_flash_data.s_para.u8StaDaySaveTime);//计算需要读取的时间与最新一次存储时间的差

    if(s32DayDiff < -90 || s32DayDiff >= 95){//说明没有存储该日期的数据
        SR_LOG(ERR,"%s->s32DayDiff:%d", __FUNCTION__, s32DayDiff);
        return E_STATE_ERROR;
    }
    u32SaveAddr=Svc_Flash_Calc_DayUsage_Addr(s32DayDiff);
    // /*读用量数据*/
    // if(Svc_Flash_ReadDayUsage_Check(day_usage, u32SaveAddr) == E_STATE_ERROR)
    // {
    //     return E_STATE_ERROR;
    // }
    Svc_Flash_Read(ptr, u32SaveAddr, sizeof(S_Flash_Day_Usage));
    /*校验存储标志*/
    if(day_usage->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
  //对比校验
    sum = Util_Data_Check_Sum(ptr, (gw_u32)&day_usage->u8CheckSum-(gw_u32)day_usage);
    if(day_usage->u8CheckSum != sum){
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    return E_STATE_SUCCESS;
//		SR_LOG(INFO,"%s->Data date:%u.%u.%u\r\n",__FUNCTION__,day_usage->u8StartTime[0],day_usage->u8StartTime[1],day_usage->u8StartTime[2]);//23.2.17yess - 测试用
		
}

#if FLASH_BAK_ENABLE
/**
 * @brief: 读备份用量信息
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Usage_Info} *usage_info 用量信息
 */
static E_Result_State Read_Usage_Bak(S_Flash_Usage_Info *usage_info){
    gw_u8 sum;
    gw_u8* ptr=(gw_u8*)usage_info;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);	
    Svc_Flash_Read(ptr,FLASH_USAGE_BAK_ADDR,sizeof(S_Flash_Usage_Info));
    if(usage_info->u8Sig!=FLASH_SIG_USED){
        SR_LOG(WARN,"%s->check sig fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    sum=Util_Data_Check_Sum(ptr,(gw_u32)&usage_info->u8CheckSum-(gw_u32)usage_info);
    if(sum!=usage_info->u8CheckSum)
    {
        SR_LOG(WARN,"%s->check sum fail",__FUNCTION__);
        return E_STATE_ERROR;
    }
    //SR_LOG(INFO,"%s->read ok",__FUNCTION__);
    return E_STATE_SUCCESS;
}
#endif

/**
 * @brief: 写用量信息
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Usage_Info} *usage_info 用量信息
 */
static E_Result_State Write_Usage(S_Flash_Usage_Info *usage_info){
    gw_u8* ptr=(gw_u8*)usage_info;   
    S_Flash_Usage_Info readUsage;//占用大量栈空间，导致栈溢出
    usage_info->u8Sig=FLASH_SIG_USED;
    usage_info->u8CheckSum=Util_Data_Check_Sum(ptr,(gw_u32)&usage_info->u8CheckSum-(gw_u32)usage_info);
    Svc_Flash_Write(ptr,FLASH_USAGE_ADDR,sizeof(S_Flash_Usage_Info));
#if FLASH_BAK_ENABLE
    Svc_Flash_Write(ptr,FLASH_USAGE_BAK_ADDR,sizeof(S_Flash_Usage_Info));
#endif
    if(Read_Usage(&readUsage)==E_STATE_ERROR){
        SR_LOG(ERR,"%s->write fail",__FUNCTION__);//会硬件复位？？不知道什么原因，似乎是栈溢出了
        return E_STATE_ERROR;
    }
    return  E_STATE_SUCCESS;
}

/**
 * @brief: 写天用量信息
 * @return {E_Result_State} 执行结果
 * @note:  lida
 * @see: 
 * @param {S_Flash_Day_Usage} *day_usage 天用量信息
 */
E_Result_State Write_Day_Usage(S_Flash_Day_Usage *day_usage){
    gw_u32  u32SaveAddr=0;
    gw_u8* ptr=(gw_u8*)day_usage;     
    gw_s32 s32DayDiff;    

    /*判断是否是首次存储数据*/
    if(s_flash_data.s_para.u8Enable_StaDaySaveTime!= 1)
    {
        //更新存储日期，并保存
        s_flash_data.s_para.u8Enable_StaDaySaveTime = 1;
        s_flash_data.s_para.u8StaDaySaveTime[0] = day_usage->u8StartTime[0];
        s_flash_data.s_para.u8StaDaySaveTime[1] = day_usage->u8StartTime[1];
        s_flash_data.s_para.u8StaDaySaveTime[2] = day_usage->u8StartTime[2];
        Svc_Flash_Write_Device_Para(&s_flash_data.s_para);
    }
    //计算当前时间和上一次存储时间的天数跨度
    s32DayDiff=Util_Time_Diff_Day(day_usage->u8StartTime,  s_flash_data.s_para.u8StaDaySaveTime);
    //时间跨度为负数，说明时间倒退，有异常
    if(s32DayDiff<0){
        SR_LOG(ERR,"%s->time error",__FUNCTION__);
        return E_STATE_ERROR;
    }    
    //  SR_LOG(INFO,"%s->u32SaveAddr:%lu\r\n",__FUNCTION__,u32SaveAddr);	//23.2.17yess - 测试用
    //计算数据写入地址
    u32SaveAddr=Svc_Flash_Calc_DayUsage_Addr(s32DayDiff);
    if(s32DayDiff >= 95){ //放在第一个扇区
      //更新存储日期，并保存
        s_flash_data.s_para.u8Enable_StaDaySaveTime = 1;
        s_flash_data.s_para.u8StaDaySaveTime[0] = day_usage->u8StartTime[0];
        s_flash_data.s_para.u8StaDaySaveTime[1] = day_usage->u8StartTime[1];
        s_flash_data.s_para.u8StaDaySaveTime[2] = day_usage->u8StartTime[2];
        Svc_Flash_Write_Device_Para(&s_flash_data.s_para);
        s32DayDiff = 0;
        u32SaveAddr = FLASH_USAGE_DAY_START_ADDR;
    }
    if(s32DayDiff % 5 == 0)
    {
        gw_u8 u8Index = s32DayDiff/5;
        gw_u16 u16Secoff = (FLASH_USAGE_DAY_START_ADDR + FLASH_SECTOR_SIZE*u8Index)/FLASH_SECTOR_SIZE;
        if(u32SaveAddr != (FLASH_USAGE_DAY_START_ADDR + FLASH_SECTOR_SIZE*u8Index))
        {
            SR_LOG(INFO,"%s->jump error\r\n",__FUNCTION__);	//23.2.17yess - 测试用           
        } 
        // SR_LOG(INFO,"%s->jump next scope:%lu\r\n",__FUNCTION__,u8Index);	//23.2.17yess - 测试用      
        //Bsp_Flash_Erase_Sector(u16Secoff);
        SR_FalPartErase(paramPart, u16Secoff, 1);
    }
    //检查地址数据是否为0xff，防止写入失败或改变原有的数据
    if(Svc_Flash_Check_Addr_Empty(u32SaveAddr, Size_Day_Usage) == E_STATE_ERROR){
        SR_LOG(WARN,"%s->Address 0x%lX has data!!!\r\n",__FUNCTION__, u32SaveAddr);
        return E_STATE_ERROR;
    }
    /*保存日用量信息*/
    day_usage->u8Sig=FLASH_SIG_USED;
    #if LOG_FUNC_ENABLE    
        SR_LOG(WARN,"%s->Address 0x%lX u8Sig is 0x%02X\r\n",__FUNCTION__, u32SaveAddr,day_usage->u8Sig);
    #endif
    day_usage->u8CheckSum=Util_Data_Check_Sum(ptr,(gw_u32)&day_usage->u8CheckSum-(gw_u32)day_usage);
    Svc_Flash_Write_No_Erase((gw_u8*)ptr, u32SaveAddr, sizeof(S_Flash_Day_Usage));
    // Svc_Flash_Write(ptr,u32SaveAddr,sizeof(S_Flash_Usage_Info));
    // readDayUsage  = (S_Flash_Day_Usage *)malloc(sizeof(S_Flash_Day_Usage));
    if(Read_Day_Usage(&ReadDayUsage,day_usage->u8StartTime)==E_STATE_ERROR){
        SR_LOG(ERR,"%s->write fail",__FUNCTION__);//会硬件复位？？不知道什么原因，似乎是栈溢出了
        return E_STATE_ERROR;
    }
    // if(readDayUsage!=NULL){
    //     free(readDayUsage);
    //     readDayUsage=NULL;
    // }
    return  E_STATE_SUCCESS;
}

/**
 * @brief: 写用量信息-失败重写
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Usage_Info} *usage_info 用量信息
 */
E_Result_State Svc_Flash_Write_Usage(S_Flash_Usage_Info *usage_info){
    gw_s8 i;
    for(i=0;i<FLASH_REPEAT_WRITE_NUM;i++){
      Bsp_Iwdg_Feed();
				// Svc_Wdg_Feed(1);	
        if(Write_Usage(usage_info)==E_STATE_SUCCESS){
          Bsp_Iwdg_Feed();
						// Svc_Wdg_Feed(1);	
            return E_STATE_SUCCESS;
        }
    }
    Bsp_Iwdg_Feed();
		// Svc_Wdg_Feed(1);	
    return E_STATE_ERROR;
}

/**
 * @brief: 写天用量信息-失败重写
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Usage_Info} *usage_info 用量信息
 */
E_Result_State Svc_Flash_Write_Day_Usage(S_Flash_Day_Usage *day_usage){
    gw_s8 i;
    for(i=0;i<FLASH_REPEAT_WRITE_NUM;i++){
      Bsp_Iwdg_Feed();
						// Svc_Wdg_Feed(1);
        if(Write_Day_Usage(day_usage)==E_STATE_SUCCESS){
          Bsp_Iwdg_Feed();
						// Svc_Wdg_Feed(1);	
            return E_STATE_SUCCESS;
        }
    }
    Bsp_Iwdg_Feed();
		// Svc_Wdg_Feed(1);	
    return E_STATE_ERROR;
}

/**
 * @brief: 读设备参数-失败重读
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Para} *para 设备参数
 */
E_Result_State Read_Device_Para_Repeat(S_Flash_Device_Para *para){
    gw_s8 i;
    S_Bat s_bat;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);	
    s_bat=Svc_Bat_Get_Data();
    for(i=0;i<FLASH_REPEAT_READ_NUM;i++)
    {
        if(Read_Device_Para(para)==E_STATE_ERROR)
        {
#if FLASH_BAK_ENABLE
            if(Read_Device_Para_Bak(para)==E_STATE_ERROR)
            {   
                if(s_bat.u16BatValtage<BAT_FLASH_LOW)
                {//开机读取flash失败，电源电压过低，flash已不能正常存储
                    SR_LOG(ERR,"flash func close,U:%d",s_bat.u16BatValtage);
                    s_flash_data.u8flashCheckFail=1;
                    return E_STATE_ERROR;
                }     
                Device_Para_init();
            }else
            {
                return E_STATE_SUCCESS;
            }
#else
            Device_Para_init();
#endif
        }
        else
        {
            return E_STATE_SUCCESS;
        }
    }
    return E_STATE_ERROR;
}

/**
 * @brief: 读设备安全信息-失败重读
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Device_Security} *security 设备安全信息
 */
E_Result_State Read_Device_Security_Repeat(S_Flash_Device_Security *security){
    gw_s8 i;
    S_Bat s_bat;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);	
    s_bat=Svc_Bat_Get_Data();
    for(i=0;i<FLASH_REPEAT_READ_NUM;i++){
        if(Read_Device_Security(security)==E_STATE_ERROR){
#if FLASH_BAK_ENABLE
            if(Read_Device_Security_Bak(security)==E_STATE_ERROR){
                if(s_bat.u16BatValtage<BAT_FLASH_LOW){//开机读取flash失败，电源电压过低，flash已不能正常存储
                    s_flash_data.u8flashCheckFail=1;
                    SR_LOG(ERR,"flash func close,U:%d",s_bat.u16BatValtage);
                    return E_STATE_ERROR;
                }  
                Device_Security_init();
            }else{
                return E_STATE_SUCCESS;
            }
#else
            Device_Security_init();
#endif    
        }else{
            // Svc_Log_Print("s_security->pu8SoftVer %d\r\n",security->pu8SoftVer);          
            return E_STATE_SUCCESS;
        }
    }

    return E_STATE_ERROR;
}

/**
 * @brief: 读用量信息-失败重读
 * @return {E_Result_State} 执行结果
 * @note: 
 * @see: 
 * @param {S_Flash_Usage_Info} *usage_info 用量信息
 */
E_Result_State Read_Usage_Repeat(S_Flash_Usage_Info *usage_info){
    gw_s8 i;
    S_Bat s_bat;
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);	
    s_bat=Svc_Bat_Get_Data();
    for(i=0;i<FLASH_REPEAT_READ_NUM;i++){
        if(Read_Usage(usage_info)==E_STATE_ERROR){
#if FLASH_BAK_ENABLE
            if(Read_Usage_Bak(usage_info)==E_STATE_ERROR){
                if(s_bat.u16BatValtage<BAT_FLASH_LOW){//开机读取flash失败，电源电压过低，flash已不能正常存储
                    s_flash_data.u8flashCheckFail=1;
                    SR_LOG(ERR,"flash func close,U:%d",s_bat.u16BatValtage);
                    return E_STATE_ERROR;
                }  
                Usage_Info_Init();
            }else{
                return E_STATE_SUCCESS;
            }
#else
            Usage_Info_Init();
#endif
        }else{
            return E_STATE_SUCCESS;
        }
    }
    return E_STATE_ERROR;
}

/**
 * @brief: 读用户数据
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Read_User_Data(void){
		// SR_LOG(DEBUG,"%s \r\n",__FUNCTION__);		
    S_Ota_Para s_ota_para;
    Bsp_Iwdg_Feed();
    Read_Device_Para_Repeat(&s_flash_data.s_para);
    Bsp_Iwdg_Feed();		
    Read_Device_Security_Repeat(&s_flash_data.s_security);
    Bsp_Iwdg_Feed();		
    Read_Usage_Repeat(&s_flash_data.s_usage_info);  
    Bsp_Iwdg_Feed();		
    Read_Device_OtaPara_Repeat(&s_ota_para);
    Bsp_Iwdg_Feed();
    //为1：代表OTA升级不成功，保持初始版本号
    if(s_ota_para.u8otasuccFlag == 1){
        s_ota_para.u8otasuccFlag = 0;
        s_flash_data.s_security.pu8SoftVer = SOFT_VERSION;//更新软件版本
        // Svc_Log_Print("version change fail");
    }	

}

/**
 * @brief: 初始化用户数据
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_User_Data_Reload(void){
    Device_Security_init();
    Device_Para_init();
    Usage_Info_Init();
}

/**
 * @brief: 存储小时用量
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u16} u16Usage 小时用量
 */
void Save_Hour_Usage(gw_s16 s16Usage,gw_u32 u32StartTime,gw_u32 u32StopTime){		
		gw_u8 StartTime[6];      //年，月，日，时，分，秒						
		S_Flash_Hour_Usage 	*ps_hour_usage;		  		
		ps_hour_usage=&s_flash_data.s_usage_info.s_day_usage.s_hour_usage;  	
		if(u32StopTime<=u32StartTime){
				return;
		}
		Util_Time_Timestamp_To_Time(u32StartTime,StartTime);	
		StartTime[3]=0;
		StartTime[4]=0;
		StartTime[5]=0;
		u32StartTime=Util_Time_Date_To_Timestamp(StartTime); //回到零点时间
	  if(u32StopTime<=u32StartTime){
				return;
		}
    ps_hour_usage->u8RecordNumb= (u32StopTime-u32StartTime)/(60*30);
		if(ps_hour_usage->u8RecordNumb>48){
				ps_hour_usage->u8RecordNumb=48;
		}
		if(ps_hour_usage->u8RecordNumb==0){
				return;
		}      
		ps_hour_usage->u16RecordUse[ps_hour_usage->u8RecordNumb-1]=s16Usage;
   
}

void Svc_Flash_30Min_Usage_Print(gw_u8 CaliFlag,gw_u8 DirFlag,gw_s32 UsgeData){	
	
		gw_u8 u8i=0;
		S_Flash_Device_Para *ps_device_para;
		S_Flash_Usage_Info  *ps_usage_info;		
		S_Flash_Hour_Usage 	*ps_hour_usage;
		S_Flash_Real_Usage 	*ps_real_usage;  		
		ps_usage_info=&s_flash_data.s_usage_info;		
    ps_hour_usage=&ps_usage_info->s_day_usage.s_hour_usage;		
		ps_real_usage=&ps_usage_info->s_day_usage.s_real_usage;
		ps_device_para=&s_flash_data.s_para;		
		if(CaliFlag==0){
				SR_LOG(INFO, "--------New 30Min Usage Save Start---------\r\n");  
		}
		else{
				SR_LOG(INFO, "-------Cali 30Min Usage Save Start---------\r\n"); 
		}
		Svc_Cloud_SysTime_Printf( );		
		
		if(DirFlag==PLUSE_FLOW_ROTATE_FORWARD){ //正走
				SR_LOG(INFO, "Usage 30Min Flow FORWARD\r\n");				
		}
		else{  //反走
				SR_LOG(INFO,"Usage 30Min Flow REVERSAL\r\n");
		}
		
		if(UsgeData>=ps_device_para->u32MaxTotalUsage){//数据超限，异常
				SR_LOG(INFO, "Usage 30Min Too Max =%d\r\n",UsgeData);				
		}
		else{
				SR_LOG(INFO,"Usage 30Min Save Data =%d\r\n",UsgeData);
		}
		SR_LOG(INFO, "ps_usage_info->u32TotalUsage=%d\r\n",ps_usage_info->u32TotalUsage);
		SR_LOG(INFO,"ps_real_usage->u32TotalUsage=%d \r\n",ps_real_usage->u32TotalUsage);	
		SR_LOG(INFO, "ps_usage_info->u32LastHourUsage=%d\r\n",ps_usage_info->u32LastHourUsage);		
		SR_LOG(INFO, "ps_hour_usage->u8RecordNumb=%d\r\n",ps_hour_usage->u8RecordNumb);		
	  for(u8i=0;u8i<ps_hour_usage->u8RecordNumb;u8i++){
				SR_LOG(INFO, "ps_hour_usage name=%d ,usage =%d\r\n",u8i,ps_hour_usage->u16RecordUse[u8i]);
		}
}

/**
 * @brief: 检查是否需要存储小时用量
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Check_Save_30Min_Usage(void){		
		gw_u8	u8Dir;		
		gw_s32 s32Usage;
    gw_u32 MaxTotalUsage;
    S_Cloud_Data *ps_cloud;   
		S_Flash_Device_Para *ps_device_para;
		S_Flash_Usage_Info  *ps_usage_info;		
		S_Flash_Hour_Usage 	*ps_hour_usage;		
    if(Svc_Cloud_Time_Is_Calibrate()==0){//时间未校准的情况下不存储
        return;
    }		
		ps_cloud=Svc_Cloud_Get_Data();		
		ps_device_para=&s_flash_data.s_para;
		MaxTotalUsage=ps_device_para->u32MaxTotalUsage;
		ps_usage_info=&s_flash_data.s_usage_info;		
    ps_hour_usage=&ps_usage_info->s_day_usage.s_hour_usage;				
    
    if(Svc_Cloud_Time_Check((char *)__FUNCTION__)==E_CHECK_FAIL){     
        return;
    }
    if((ps_cloud->pu8CurTime[4]==0)||(ps_cloud->pu8CurTime[4]==30)){//0分，30分 保存上半小时用量
			if(ps_hour_usage->u8HourSaveFlag==1){//这个小时还未存储过，需要存储            
            ps_hour_usage->u8HourSaveFlag=0;
						s32Usage=(ps_usage_info->u32TotalUsage+MaxTotalUsage-ps_usage_info->u32LastHourUsage)%MaxTotalUsage;//计算当前总用量和上一次统计时的总用量差值，即这一个30Min的使用量
				    if(ps_usage_info->u32TotalUsage>=ps_usage_info->u32LastHourUsage){//正走			
								u8Dir = PLUSE_FLOW_ROTATE_FORWARD;
								if(s32Usage>MAX_USAGE_30MIN){//数据超限，异常
										s32Usage = MAX_USAGE_30MIN;
								}							
						}
						else{   //正走反走都可能
                //这种情况是数据用量都在99999999范围，刚上电反转，就会进入该条件，打印log出现65535等就是出现负数。
								if(s32Usage>(MAX_USAGE_30MIN*2)){//数据超限，异常反走										
										s32Usage = (gw_s32)ps_usage_info->u32TotalUsage-(gw_s32)ps_usage_info->u32LastHourUsage;//数据可能是负数
										u8Dir = PLUSE_FLOW_ROTATE_REVERSAL;
								}
                //这种情况是上一个小时用量为9999999*的一个数据，下一个小时为一个很小的数，例如上一个小时99999900，当前为1000。
								else if(s32Usage>MAX_USAGE_30MIN){
										s32Usage = MAX_USAGE_30MIN;
										u8Dir = PLUSE_FLOW_ROTATE_FORWARD;
								}
								else{
										u8Dir = PLUSE_FLOW_ROTATE_FORWARD;
								}
						}           
            Save_Hour_Usage((gw_s16)s32Usage,Util_Time_Date_To_Timestamp(ps_usage_info->s_day_usage.u8StartTime),ps_cloud->u32CurTime);//保存小时用量
						#if LOG_FUNC_ENABLE 					  
						  Svc_Flash_30Min_Usage_Print(0,u8Dir,s32Usage);							
						#endif   						
            ps_usage_info->u32LastHourUsage=ps_usage_info->u32TotalUsage;//更新上一次统计时的总用量
        }
    }
    else{
        ps_hour_usage->u8HourSaveFlag=1;
    }
}
void Svc_Flash_Check_Save_30Min_Usage_Time_Calibrate(gw_u32 u32CurTime,gw_u32 CaliTime){
		gw_u8		u8Dir;
		gw_s32 	s32Usage;
    gw_u32 	MaxTotalUsage;    
		S_Flash_Device_Para *ps_device_para;
		S_Flash_Usage_Info  *ps_usage_info;	
		S_Flash_Hour_Usage *ps_hour_usage;		
		ps_usage_info=&s_flash_data.s_usage_info;
		ps_device_para=&s_flash_data.s_para;
    ps_hour_usage=&ps_usage_info->s_day_usage.s_hour_usage;
		MaxTotalUsage=ps_device_para->u32MaxTotalUsage;		
		if((u32CurTime/(60*30))!=(CaliTime/(60*30))){ 		//超过一个记录点							
			u32CurTime=u32CurTime+60*30; 										//增加一个记录点			存储当前数据			
			if(ps_hour_usage->u8HourSaveFlag==1){						//这个小时还未存储过，需要存储 如果刚刚存储过，可以不用再储存
            ps_hour_usage->u8HourSaveFlag=0;
						s32Usage=(ps_usage_info->u32TotalUsage+MaxTotalUsage-ps_usage_info->u32LastHourUsage)%MaxTotalUsage;//计算当前总用量和上一次统计时的总用量差值，即这一个30Min的使用量
				    if(ps_usage_info->u32TotalUsage>=ps_usage_info->u32LastHourUsage){				//正走				
								u8Dir = PLUSE_FLOW_ROTATE_FORWARD;
								if(s32Usage>MAX_USAGE_30MIN){//数据超限，异常										
										s32Usage = MAX_USAGE_30MIN;
								}							
						}
						else{  //正走反走都可能
								if(s32Usage>(MAX_USAGE_30MIN*2)){//数据超限，异常反走

										s32Usage = (gw_s32)ps_usage_info->u32TotalUsage-(gw_s32)ps_usage_info->u32LastHourUsage;

										u8Dir = PLUSE_FLOW_ROTATE_REVERSAL;
								}
								else if(s32Usage>MAX_USAGE_30MIN){
										s32Usage = MAX_USAGE_30MIN;
										u8Dir = PLUSE_FLOW_ROTATE_FORWARD;
								}
								else{
										u8Dir = PLUSE_FLOW_ROTATE_FORWARD;
								}
						}           
						Save_Hour_Usage((gw_s16)s32Usage,Util_Time_Date_To_Timestamp(ps_usage_info->s_day_usage.u8StartTime),u32CurTime);//保存小时用量
						#if LOG_FUNC_ENABLE     						
						Svc_Flash_30Min_Usage_Print(1,u8Dir,s32Usage);							
						#endif   
            ps_usage_info->u32LastHourUsage=ps_usage_info->u32TotalUsage;//更新上一次统计时的总用量
        }
    }
    else{
        ps_hour_usage->u8HourSaveFlag=1;
    }
		
}
void Svc_Flash_Dense_Usage_Print(void){		
		gw_u8 u8i=0;
		S_Flash_Dense_Usage *ps_dense_usage;
		S_Flash_Device_Para *ps_device_para;
		S_Flash_Usage_Info  *ps_usage_info;		   
		ps_device_para=&s_flash_data.s_para;		
		ps_usage_info=&s_flash_data.s_usage_info;
    ps_dense_usage=&ps_usage_info->s_day_usage.s_Dense_usage;    		
		
		SR_LOG(INFO,"----------Dense_Usage Info-------------\r\n");	
		Svc_Cloud_SysTime_Printf( );	
		SR_LOG(INFO,"Dense_Usage Start Time = %d\r\n",ps_device_para->u8DenseStartTime);
		
		SR_LOG(INFO,"ps_usage_info->u32TotalUsagePos = %d\r\n",ps_usage_info->u32TotalUsagePos);
		SR_LOG(INFO,"ps_usage_info->u32LastDenseUsagePos = %d\r\n",ps_usage_info->u32LastDenseUsagePos);
		SR_LOG(INFO,"ps_usage_info->u32TotalUsageNeg = %d\r\n",ps_usage_info->u32TotalUsageNeg);
		SR_LOG(INFO,"ps_usage_info->u32LastDenseUsageNeg = %d\r\n",ps_usage_info->u32LastDenseUsageNeg);
		
		SR_LOG(INFO,"ps_dense_usage->u8RecordNumb = %d\r\n",ps_dense_usage->u8RecordNumb);	
		for(u8i=0;u8i<ps_dense_usage->u8RecordNumb;u8i++){
        SR_LOG(INFO, "ps_dense_usage name=%d ,usage Pos  =%d   usage Neg  =%d\r\n",u8i,ps_dense_usage->u16RecordUsage[u8i][0],ps_dense_usage->u16RecordUsage[u8i][1]);
		}
	
}
	
/**
 * @brief: 检查是否需要存储密集流量用量
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Check_Save_Dense_Usage(void){    
		gw_u32 u32Usage;
    gw_u32 MaxTotalUsage;    
    S_Cloud_Data *ps_cloud;
    S_Flash_Dense_Usage *ps_dense_usage;
		S_Flash_Device_Para *ps_device_para;
		S_Flash_Usage_Info  *ps_usage_info;		
    if(Svc_Cloud_Time_Is_Calibrate()==0){//时间未校准的情况下不存储4
        return;
    }    
		ps_cloud=Svc_Cloud_Get_Data();		
		ps_device_para=&s_flash_data.s_para;		
		ps_usage_info=&s_flash_data.s_usage_info;
    ps_dense_usage=&ps_usage_info->s_day_usage.s_Dense_usage;   
		MaxTotalUsage=ps_device_para->u32MaxTotalUsage;     
      
    //当前时间与上一次系统时间是否在同一天,不在同一天则返回
    //如果用当前日冻结里的时间,则存在,如果密集流量从20:00:00开始,
    //则在时间到最00:00:00,最后一个流量数据会漏存
    if((ps_cloud->u32CurTime/(3600*24))!=(ps_cloud->u32LastTime/(3600*24))){
        return ;
    }
    if((ps_cloud->pu8CurTime[3]==ps_device_para->u8DenseStartTime)&&(ps_cloud->pu8CurTime[4]==0)){ //时 分
        if(ps_dense_usage->u8StartFlag==0){
            ps_dense_usage->u8RecordNumb=0;
            ps_dense_usage->u8StartFlag=1;
            ps_dense_usage->u16NextTime=300;
            ps_usage_info->u32LastDenseUsagePos=ps_usage_info->u32TotalUsagePos;
            ps_usage_info->u32LastDenseUsageNeg=ps_usage_info->u32TotalUsageNeg;
					  memcpy(&ps_dense_usage->u8StartTime,ps_cloud->pu8CurTime,6);
						#if LOG_FUNC_ENABLE   						
						Svc_Flash_Dense_Usage_Print( );						
						#endif   						
        }
    }    
    if(ps_dense_usage->u8StartFlag){
        if(ps_dense_usage->u16NextTime==0){
            ps_dense_usage->u16NextTime=300;             
            u32Usage=(ps_usage_info->u32TotalUsagePos+MaxTotalUsage-ps_usage_info->u32LastDenseUsagePos)%MaxTotalUsage;
            if(u32Usage>MAX_USAGE_5MIN){//数据超限，异常               
               u32Usage=MAX_USAGE_5MIN; 
            }
            ps_dense_usage->u16RecordUsage[ps_dense_usage->u8RecordNumb][0]=u32Usage;
            u32Usage=(ps_usage_info->u32TotalUsageNeg+MaxTotalUsage-ps_usage_info->u32LastDenseUsageNeg)%MaxTotalUsage;
            if(u32Usage>MAX_USAGE_5MIN){//数据超限，异常              
               u32Usage=MAX_USAGE_5MIN; 
            }
            ps_dense_usage->u16RecordUsage[ps_dense_usage->u8RecordNumb][1]=u32Usage;
           
						ps_dense_usage->u8RecordNumb++;
						if(ps_dense_usage->u8RecordNumb>=48){
								ps_dense_usage->u8RecordNumb=48;
								ps_dense_usage->u8StartFlag=0;	
								ps_dense_usage->u16NextTime=0;
						} 
						#if LOG_FUNC_ENABLE
						Svc_Flash_Dense_Usage_Print( );						
						#endif   
						ps_usage_info->u32LastDenseUsagePos=ps_usage_info->u32TotalUsagePos;
            ps_usage_info->u32LastDenseUsageNeg=ps_usage_info->u32TotalUsageNeg;
        }        
    }
}

void Svc_Flash_Day_Usage_Print(void){		
		gw_u8 u8i=0;	
		S_Flash_Hour_Usage 	*ps_hour_usage;
		S_Flash_Real_Usage 	*ps_real_usage;  
		S_Flash_Dense_Usage *ps_dense_usage;
		S_Flash_Device_Para *ps_device_para;
		S_Flash_Usage_Info  *ps_usage_info;
		ps_device_para=&s_flash_data.s_para;		
		ps_usage_info=&s_flash_data.s_usage_info;
    ps_dense_usage=&ps_usage_info->s_day_usage.s_Dense_usage;    	
		ps_hour_usage=&ps_usage_info->s_day_usage.s_hour_usage;
		ps_real_usage=&ps_usage_info->s_day_usage.s_real_usage;	
	
		SR_LOG(INFO,"-------Usage Day Info----------\r\n");	 		
		Svc_Cloud_SysTime_Printf( );	    
		SR_LOG(INFO,"ps_usage_info->u32TotalUsagePos=%d \r\n",ps_usage_info->u32TotalUsagePos);
		SR_LOG(INFO,"ps_usage_info->u32TotalUsageNeg=%d \r\n",ps_usage_info->u32TotalUsageNeg);		
		SR_LOG(INFO,"ps_usage_info->u32TotalUsage=%d \r\n",ps_usage_info->u32TotalUsage);	
		SR_LOG(INFO,"-------Usage 30Min Info----------\r\n");	 
		SR_LOG(INFO,"ps_real_usage->u32TotalUsagePosMidnight=%d \r\n",ps_real_usage->u32TotalUsagePosMidnight);
		SR_LOG(INFO,"ps_real_usage->u32TotalUsageNegMidnight=%d \r\n",ps_real_usage->u32TotalUsageNegMidnight);		
		SR_LOG(INFO,"ps_real_usage->u32TotalUsage=%d \r\n",ps_real_usage->u32TotalUsage);	
		
		SR_LOG(INFO, "ps_hour_usage->u8RecordNumb%d\r\n",ps_hour_usage->u8RecordNumb);		
	  for(u8i=0;u8i<ps_hour_usage->u8RecordNumb;u8i++){
				SR_LOG(INFO, "ps_hour_usage name=%d ,usage =%d\r\n",u8i,ps_hour_usage->u16RecordUse[u8i]);
		}	
		SR_LOG(INFO,"Dense_Usage Info\r\n");			
		SR_LOG(INFO,"Dense_Usage Start Time = %d\r\n",ps_device_para->u8DenseStartTime);				
		SR_LOG(INFO,"ps_dense_usage->u8RecordNumb = %d\r\n",ps_dense_usage->u8RecordNumb);	
		for(u8i=0;u8i<ps_dense_usage->u8RecordNumb;u8i++){
					SR_LOG(INFO, "ps_dense_usage name=%d ,usage Pos  =%d   usage Neg  =%d\r\n",u8i,ps_dense_usage->u16RecordUsage[u8i][0],ps_dense_usage->u16RecordUsage[u8i][1]);
		}
}

//S_Flash_Day_Usage Flash_Day_Usage_Buf;
/**
 * @brief: 检查是否需要存储日用量
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Check_Save_Day_Usage(void){
    gw_u8 *cur_time;      //年，月，日，时，分，秒       
		gw_u16       	u16BatVol;
    S_Cloud_Data *ps_cloud;
		S_Flash_Usage_Info  *ps_usage_info;
		S_Flash_Day_Usage 	*ps_day_usage;	
		S_Flash_Real_Usage  *ps_real_Usage;
    if(Svc_Cloud_Time_Is_Calibrate()==0){//时间未校准的情况下不存储
        return;
    }   
    ps_cloud=Svc_Cloud_Get_Data();
    cur_time=ps_cloud->pu8CurTime;      
		
		ps_usage_info=&s_flash_data.s_usage_info;
    ps_day_usage=&ps_usage_info->s_day_usage;
		ps_real_Usage=&ps_day_usage->s_real_usage;
    if(Svc_Cloud_Time_Check((char *)__FUNCTION__)==E_CHECK_FAIL){     
        return;
    }
    if((cur_time[3]==0)&&(cur_time[4]==0)){//0点0分，保存前一天用量
        if(ps_day_usage->u8DaySaveFlag==1){//今天还未存储过，需要存储           
            ps_day_usage->u8DaySaveFlag=0;
            ps_day_usage->s_usage_alarm=ps_usage_info->s_usage_alarm;                        
            memset(&ps_usage_info->s_usage_alarm,0,sizeof(S_Flash_Usage_Alarm)); 
						#if LOG_FUNC_ENABLE
						Svc_Flash_Day_Usage_Print();
						#endif
						Svc_Flash_Write_Day_Usage(ps_day_usage);
					  u16BatVol = ps_day_usage->s_real_usage.u16BatVol;
            memset(ps_day_usage,0,sizeof(S_Flash_Day_Usage));  					
            memcpy(ps_day_usage->u8StartTime,ps_cloud->pu8CurTime,6);
            ps_real_Usage->u32TotalUsageNegMidnight=ps_usage_info->u32TotalUsageNeg;
            ps_real_Usage->u32TotalUsagePosMidnight=ps_usage_info->u32TotalUsagePos;
						ps_real_Usage->u32TotalUsage=ps_usage_info->u32TotalUsage;
						memcpy(ps_real_Usage->u8MaxUseTime,ps_cloud->pu8CurTime,6);								
						memcpy(ps_real_Usage->u8InfoTime,ps_cloud->pu8CurTime,6);		
						ps_day_usage->s_real_usage.u16BatVol=u16BatVol;
            //Svc_Flash_Write_Usage(ps_usage_info);
        }        
    }else{
        ps_day_usage->u8DaySaveFlag=1;
    }
}

void Svc_Flash_Hour_Usage_Print(void){
		SR_LOG(INFO,"------One Hour Info usage save----- \r\n");
		Svc_Cloud_SysTime_Printf( );
}
/**
 * @brief: 检查是否需要存储用量信息
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Flash_Check_Save_Usage(void){
    gw_u8 *cur_time;      //年，月，日，时，分，秒   
    S_Cloud_Data *ps_cloud;   		
		S_Flash_Usage_Info  *ps_usage_info;
    if(Svc_Cloud_Time_Is_Calibrate()==0){//时间未校准的情况下不存储
        return;
    }
    ps_cloud=Svc_Cloud_Get_Data();
    cur_time=ps_cloud->pu8CurTime;        
    ps_usage_info=&s_flash_data.s_usage_info;
		if(Svc_Cloud_Time_Check((char *)__FUNCTION__)==E_CHECK_FAIL){     
        return;
    }
    if(cur_time[4]==0){//0分 一小时一存用量信息
        if(ps_usage_info->u8Usage_Info_SaveFlag==1){//还未存储过，需要存储
						#if LOG_FUNC_ENABLE   						
						Svc_Flash_Hour_Usage_Print();						
						#endif   
            Svc_Rtc_Set_Time_Flash();	
            ps_usage_info->u8Usage_Info_SaveFlag=0; 										
            Svc_Flash_Write_Usage(ps_usage_info);
        }        
    }else{
        ps_usage_info->u8Usage_Info_SaveFlag=1;
    }
}
/**
 * @brief: 累计用量更新
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u8} u8Qusm   流量，单位：L
 * @param {gw_u8} u8Dir    方向
 */
void Svc_Flash_Update_Usage(SR_PULSE_FLOW_T *FlowData){
    
    gw_u32 MaxTotalUsage;  
		S_Cloud_Data *ps_cloud;      
		S_Flash_Usage_Info 	*ps_usage_info;   
		S_Flash_Device_Para	*ps_device_para;   
		S_Flash_Real_Usage	*ps_real_usage;   
	
    ps_cloud=Svc_Cloud_Get_Data();
    ps_usage_info=&s_flash_data.s_usage_info;
		ps_device_para=&s_flash_data.s_para;
    MaxTotalUsage=ps_device_para->u32MaxTotalUsage;
		ps_real_usage = &ps_usage_info->s_day_usage.s_real_usage;
    if(FlowData->u8FLowDir == PLUSE_FLOW_ROTATE_FORWARD){
         ps_usage_info->u32TotalUsagePos = ps_usage_info->u32TotalUsagePos+FlowData->PulseEqu;
         if(ps_usage_info->u32TotalUsagePos>MaxTotalUsage){
            ps_usage_info->u32TotalUsagePos=0;
        }
    }
    else{
        ps_usage_info->u32TotalUsageNeg = ps_usage_info->u32TotalUsageNeg+FlowData->PulseEqu;
        if(ps_usage_info->u32TotalUsageNeg>MaxTotalUsage){
            ps_usage_info->u32TotalUsageNeg=0;   
        }
    }
		//累计用量 = （正总用量+最大计量数 - 逆总用量）%最大计量数
    ps_usage_info->u32TotalUsage=(ps_usage_info->u32TotalUsagePos+MaxTotalUsage-ps_usage_info->u32TotalUsageNeg)%MaxTotalUsage;
    ps_real_usage->u32TotalUsage=ps_usage_info->u32TotalUsage;
    if(Svc_Cloud_Time_Check((char *)__FUNCTION__)==E_CHECK_FAIL){     
        return;
    }  
    memcpy(ps_real_usage->u8InfoTime,ps_cloud->pu8CurTime,6);
}

/**
 * @brief: 电量检测定时器回调
 * @param  {void}
 * @return {void}
 * @note:  每1s执行一次
 * @see: 
 */
void Svc_Flash_Dense_Timer_Callback(void){
    if(s_flash_data.s_usage_info.s_day_usage.s_Dense_usage.u16NextTime>0){
       s_flash_data.s_usage_info.s_day_usage.s_Dense_usage.u16NextTime--; 
    }
}

void Svc_Flash_Base_Usage_Calibrate_Printf(void){
	  S_Flash_Data *ps_flash;
    S_Flash_Real_Usage 	*ps_real_usage;		
    S_Flash_Usage_Info 	*ps_usage_info;
    
    ps_flash=Svc_Flash_Get_Data();      
		ps_usage_info=&ps_flash->s_usage_info;
    ps_real_usage=&ps_usage_info->s_day_usage.s_real_usage;		
	
		SR_LOG(INFO,"ps_usage_info->u32TotalUsagePos=%d \r\n",ps_usage_info->u32TotalUsagePos);
		SR_LOG(INFO,"ps_usage_info->u32TotalUsageNeg=%d \r\n",ps_usage_info->u32TotalUsageNeg);		
		SR_LOG(INFO,"ps_usage_info->u32TotalUsage=%d \r\n",ps_usage_info->u32TotalUsage);	
		SR_LOG(INFO,"ps_usage_info->u32LastHourUsage=%d \r\n",ps_usage_info->u32LastHourUsage);
		SR_LOG(INFO,"ps_real_usage->u32TotalUsagePosMidnight=%d \r\n",ps_real_usage->u32TotalUsagePosMidnight);
		SR_LOG(INFO,"ps_usage_info->u32LastDenseUsagePos=%d \r\n",ps_usage_info->u32LastDenseUsagePos);		
}

/**
 * @brief: 表底数校准
 * @return {void}
 * @note: 
 * @see: 
 * @param {gw_u32} BaseUsage，表底数
 */
void Svc_Flash_Base_Usage_Calibrate(gw_u32 BaseUsage){
    
    gw_u32  u32TotalUsage=0;
		gw_u32 	u32DiffUsage=0;		
    gw_u32 	MaxTotalUsage=0;
    S_Flash_Data *ps_flash;
    S_Flash_Real_Usage 	*ps_real_usage;			
    S_Flash_Usage_Info 	*ps_usage_info;	
	
		#if LOG_FUNC_ENABLE   		
        SR_LOG(INFO, "-------Base_Usage_Calibrate Start---------\r\n"); 		
        Svc_Cloud_SysTime_Printf( );	
        Svc_Flash_Base_Usage_Calibrate_Printf();			
		#endif   
	
    ps_flash=Svc_Flash_Get_Data();  	
    MaxTotalUsage=ps_flash->s_para.u32MaxTotalUsage;
		ps_usage_info=&ps_flash->s_usage_info;
    ps_real_usage=&ps_usage_info->s_day_usage.s_real_usage;		
    
    u32TotalUsage=ps_usage_info->u32TotalUsage;
		
    if(BaseUsage>=u32TotalUsage){
				u32DiffUsage=BaseUsage-u32TotalUsage;
        Bsp_Com_Dis_Interrupts();    //关中断    
        ps_usage_info->u32TotalUsagePos=(ps_usage_info->u32TotalUsagePos+u32DiffUsage)%MaxTotalUsage;
			
				ps_usage_info->u32TotalUsage=(ps_usage_info->u32TotalUsagePos+MaxTotalUsage-ps_usage_info->u32TotalUsageNeg)%MaxTotalUsage;
			
        ps_usage_info->u32LastHourUsage=(ps_usage_info->u32LastHourUsage+u32DiffUsage)%MaxTotalUsage;       

        ps_usage_info->u32LastDenseUsagePos=(ps_usage_info->u32LastDenseUsagePos+u32DiffUsage)%MaxTotalUsage;
       
        ps_real_usage->u32TotalUsagePosMidnight=(ps_real_usage->u32TotalUsagePosMidnight+u32DiffUsage)%MaxTotalUsage;     			
        
        Bsp_Com_En_Interrupts(); 
    }
    else{
        Bsp_Com_Dis_Interrupts();    //关中断  
			
				u32DiffUsage=u32TotalUsage-BaseUsage;
			
				ps_usage_info->u32TotalUsagePos = (ps_usage_info->u32TotalUsagePos+MaxTotalUsage-u32DiffUsage)%MaxTotalUsage; 
			
				ps_usage_info->u32TotalUsage=(ps_usage_info->u32TotalUsagePos+MaxTotalUsage-ps_usage_info->u32TotalUsageNeg)%MaxTotalUsage;
			
				ps_usage_info->u32LastHourUsage = (ps_usage_info->u32LastHourUsage+MaxTotalUsage-u32DiffUsage)%MaxTotalUsage; 
			
				ps_usage_info->u32LastDenseUsagePos = (ps_usage_info->u32LastDenseUsagePos+MaxTotalUsage-u32DiffUsage)%MaxTotalUsage; 
			
				ps_real_usage->u32TotalUsagePosMidnight = (ps_real_usage->u32TotalUsagePosMidnight+MaxTotalUsage-u32DiffUsage)%MaxTotalUsage; 				
			
        Bsp_Com_En_Interrupts();
    }		
		ps_real_usage->u32TotalUsage=ps_usage_info->u32TotalUsage;
		
		#if LOG_FUNC_ENABLE
		SR_LOG(INFO, "-------Base_Usage_Calibrate Stop---------\r\n"); 
		Svc_Flash_Base_Usage_Calibrate_Printf( );			
		#endif   
		
    Svc_Flash_Write_Usage(&ps_flash->s_usage_info);  
		
}

void Svc_Flash_Upload_Para_Printf(void){
	  S_Flash_Data *ps_flash;
    S_Flash_Usage_Info 	*ps_usage_info;
    
    ps_flash=Svc_Flash_Get_Data();      
		ps_usage_info=&ps_flash->s_usage_info;

		SR_LOG(INFO,"ps_usage_info->u8LastUpdataTime=%d,%d,%d, \r\n",\
    ps_usage_info->u8LastUpdataTime[0],ps_usage_info->u8LastUpdataTime[1],ps_usage_info->u8LastUpdataTime[2]);
    SR_LOG(INFO,"ps_usage_info->u8LastHistoryUpdataTime=%d,%d,%d, \r\n",\
    ps_usage_info->u8LastHistoryUpdataTime[0],ps_usage_info->u8LastHistoryUpdataTime[1],ps_usage_info->u8LastHistoryUpdataTime[2]);


}
