#include "bsp_flash.h" #include "lwutil.h" #include "bsp_rtc.h" // #include "bsp_wdg.h" #include "bsp_hr.h" #include "at_device_nt26k.h" #include #include #include "user_sys.h" #define LOG_TAG "bsp_flash" #define LOG_LVL LOG_LVL_DBG #include #include #define GETATTR(info, id) ((id) == kHwVerId ? (&(info)->hw_ver) \ : (id) == kSwVerId ? (&(info)->sw_ver) \ : (id) == kAlarmLValueId ? (&(info)->alarm_l_value) \ : (id) == kAlarmHValueId ? (&(info)->alarm_h_value) \ : (id) == kTempAlarmThresholdId ? (&(info)->temp_alarm_threshold) \ : (id) == kIotUploadCycleId ? (&(info)->iot_upload_cycle) \ : (id) == kIotRetryId ? (&(info)->iot_retry) \ : (id) == kEmagneticSwitchId ? (&(info)->emagnetic_switch) \ : (id) == kRelaySwitchId ? (&(info)->relay_switch) \ : (id) == kIotImeiId ? ((info)->iot_imei) \ : (id) == kIotImsiId ? ((info)->iot_imsi) \ : (id) == kIotIccidId ? ((info)->iot_iccid) \ : NULL) TsTotalRecords TotalRecords; const rt_uint32_t hr_start_addr[7] = {FLASH_HR_ALARM_START_ADDR, FLASH_HR_ALARM_RCY_START_ADDR, FLASH_HR_FAULT_START_ADDR, FLASH_HR_FAULT_RCY_START_ADDR, FLASH_HR_POWER_FAILURE_START_ADDR, FLASH_HR_POWER_ON_START_ADDR, FLASH_HR_SENSOR_FAILURE_START_ADDR}; const rt_uint8_t hr_record_max_num[7] = {HR_ALARM_MAX_NUM, HR_ALARM_RCY_MAX_NUM, HR_FAULT_MAX_NUM, HR_FAULT_RCY_MAX_NUM, HR_POWER_FAILURE_MAX_NUM, HR_POWER_ON_MAX_NUM, HR_SENSOR_FAILURE_MAX_NUM}; const rt_uint8_t hr_record_pages[7] = {HR_ALARM_PAGES, HR_ALARM_RCY_PAGES, HR_FAULT_PAGES, HR_FAULT_RCY_PAGES, HR_POWER_FAILURE_PAGES, HR_POWER_ON_PAGES, HR_SENSOR_FAILURE_PAGES}; const rt_uint32_t hr_sys_cfg_info_addr[kCnt] = { FLASH_HW_VER_ADDR, FLASH_SW_VER_ADDR, FLASH_ALARM_L_VALUE_ADDR, FLASH_ALARM_H_VALUE_ADDR, FLASH_IOT_UPLOAD_CYCLE_ADDR, FLASH_IOT_RETRY_ADDR, FLASH_TEMP_ALARM_THRESHOLD_ADDR, FLASH_EMAGNETIC_SWITCH_ADDR, FLASH_RELAY_SWITCH_ADDR, FLASH_IOT_IMEI_ADDR, FLASH_IOT_IMSI_ADDR, FLASH_IOT_ICCID_ADDR, }; const rt_uint32_t hr_sys_cfg_info_len[kCnt] = { FLASH_HW_VER_LEN, FLASH_SW_VER_LEN, FLASH_ALARM_L_VALUE_LEN, FLASH_ALARM_H_VALUE_LEN, FLASH_IOT_UPLOAD_CYCLE_LEN, FLASH_IOT_RETRY_LEN, FLASH_TEMP_ALARM_THRESHOLD_LEN, FLASH_EMAGNETIC_SWITCH_LEN, FLASH_RELAY_SWITCH_LEN, FLASH_IOT_IMEI_LEN, FLASH_IOT_IMSI_LEN, FLASH_IOT_ICCID_LEN, }; static rt_base_t interrupt_value; /*默认的系统配置*/ flash_sever_info sever_info = { .server_url = SYS_IOT_URL, .server_port = SYS_IOT_PORT, }; static void BSP_Flash_UnLock (void) { #if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE) RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2; #endif interrupt_value = rt_hw_interrupt_disable(); FLASH_Unlock(); } static void BSP_Flash_Lock (void) { FLASH_Lock(); #if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE) RCC->CFGR0 &= ~(uint32_t)RCC_HPRE_DIV2; #endif rt_hw_interrupt_enable (interrupt_value); } static void BSP_Flash_FastUnLock (void) { #if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE) RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2; #endif interrupt_value = rt_hw_interrupt_disable(); FLASH_Unlock_Fast(); } static void BSP_Flash_FastLock (void) { FLASH_Lock_Fast(); #if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE) RCC->CFGR0 &= ~(uint32_t)RCC_HPRE_DIV2; #endif rt_hw_interrupt_enable (interrupt_value); } static rt_size_t Flash_Read (rt_uint32_t addr, rt_uint8_t *buf, rt_size_t len) { rt_size_t read_len = 0; for (rt_size_t i = 0; i < len; i++, buf++, addr++, read_len++) { *buf = *(rt_uint8_t *)addr; } return read_len; } int Get_IotImei (char *buf, rt_size_t len) { if ((*(rt_uint8_t *)FLASH_IOT_IMEI_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_IMEI_ADDR != 0x39)) { char imei_buf[FLASH_IOT_IMEI_LEN]={0}; Flash_Read(FLASH_IOT_IMEI_ADDR, (rt_uint8_t *)&imei_buf[0], len); LOG_D ("read imei: %s", imei_buf); rt_memcpy(buf, imei_buf, len); return 0; } else { /*如果没有写进去,则全部是0*/ for (rt_uint8_t i = 0; i < len; i++) { buf[i] = '0'; } LOG_D ("IOT IMSI: %s", buf); return -1; } } int Get_IotImsi (char *buf, rt_size_t len) { if ((*(rt_uint8_t *)FLASH_IOT_IMSI_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_IMSI_ADDR != 0x39)) { char imsi_buf[FLASH_IOT_IMSI_LEN]={0}; Flash_Read(FLASH_IOT_IMSI_ADDR, (rt_uint8_t *)imsi_buf, len); LOG_D ("read imsi: %s", imsi_buf); rt_memcpy(buf, imsi_buf, len); return 0; } else { /*如果没有写进去,则全部是0*/ for (rt_uint8_t i = 0; i < len; i++) { buf[i] = '0'; } LOG_D ("IOT IMSI: %s", buf); return -1; } } int Get_IotIccid (char *buf, rt_size_t len) { if ((*(rt_uint8_t *)FLASH_IOT_ICCID_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_ICCID_ADDR != 0x39)) { char iccid_buf[FLASH_IOT_ICCID_LEN]={0}; Flash_Read(FLASH_IOT_ICCID_ADDR, (rt_uint8_t *)iccid_buf, len); LOG_D ("read iccid: %s", iccid_buf); rt_memcpy(buf, iccid_buf, len); return 0; } else { /*如果没有写进去,则全部是0*/ for (rt_uint8_t i = 0; i < len; i++) { buf[i] = '0'; } LOG_D ("IOT ICCID: %s", buf); return -1; } } /** * @description: * @param {uint32_t} addr * @param {uint8_t} *buf * @param {size_t} len * @return {*} */ static rt_size_t Flash_Write (rt_uint32_t addr, rt_uint8_t *buf, rt_size_t len) { rt_size_t i = 0; __attribute__ ((aligned (2))) rt_uint16_t write_data; if (addr % 2 != 0) return 0; FLASH_ClearFlag (FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR); BSP_Flash_UnLock(); for (i = 0; i < len; i += 2, buf += 2, addr += 2) { rt_memcpy (&write_data, buf, 2); FLASH_ProgramHalfWord (addr, write_data); /* You can add your code under here. */ if (*(rt_uint16_t *)addr != write_data) { BSP_Flash_Lock(); LOG_E ("Flash_Write Error"); return 0; } } BSP_Flash_Lock(); return i; } int BSP_Flash_Write_Info (rt_uint8_t *buf, rt_size_t len) { rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; rt_uint8_t in_page_offset = (FLASH_HW_VER_ADDR - FLASH_CONFIG_INFO_START_ADDR); Flash_ErasePage_ReadConfigInfo (page_buf); for (rt_uint8_t i = 0; i < len; i++) { page_buf[in_page_offset + i] = buf[i]; } return Flash_Write_ConfigInfo (page_buf); } rt_uint16_t Flash_Get_WorkDuration (void) { return *(rt_uint16_t *)(FLASH_WORK_TIME_ADDR); } int Flash_Set_WorkDuration (rt_uint16_t value) { rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; rt_uint8_t in_page_offset = (FLASH_WORK_TIME_ADDR - FLASH_CONFIG_INFO_START_ADDR); Flash_ErasePage_ReadConfigInfo (page_buf); rt_memcpy (page_buf + in_page_offset, &value, FLASH_WORK_TIME_LEN); return Flash_Write_ConfigInfo (page_buf); } int Flash_Get_Sever_Data (flash_sever_info *sever_info) { rt_uint8_t data[FLASH_SERVER_LEN] = {0}; rt_memcpy (data, (rt_uint8_t *)FLASH_SERVER_ADDR_ADDR, FLASH_SERVER_LEN); LOG_D ("data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x", 0, data[0], 1, data[1], 2, data[2], 3, data[3], 4, data[4], 5, data[5]); rt_snprintf (sever_info->server_url, sizeof (sever_info->server_url), "%d.%d.%d.%d", data[3], data[2], data[1], data[0]); rt_uint16_t port_num = ((data[5] << 8) | data[4]); LOG_D ("port_num = %d", port_num); rt_snprintf (sever_info->server_port, sizeof (sever_info->server_port), "%d", port_num); LOG_D ("server_url:%s, server_port:%s", sever_info->server_url, sever_info->server_port); return 0; } int Flash_Set_Sever_Data (rt_uint8_t *data) { rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; rt_uint8_t in_page_offset = (FLASH_SERVER_ADDR_ADDR - FLASH_CONFIG_INFO_START_ADDR); if (data == RT_NULL) { return -RT_ERROR; } Flash_ErasePage_ReadConfigInfo (page_buf); //*将传入的数据写到flash地址中 for (size_t i = 0; i < FLASH_SERVER_LEN; i++) { page_buf[in_page_offset++] = data[i]; } return Flash_Write_ConfigInfo (page_buf); } /** * @description: Flash Erase Page * @param {TeRecord} record * @param {uint8_t} page * @return {*} */ static ErrorStatus Flash_ErasePage_Records (TeRecord record, rt_uint8_t page_offset) { ErrorStatus flag = READY; rt_uint8_t erase_page = 0; if (page_offset <= hr_record_pages[record] - 1) { erase_page = page_offset; } else { erase_page = hr_record_pages[record] - 1; } BSP_Flash_FastUnLock(); FLASH_ErasePage_Fast (hr_start_addr[record] + FLASH_PAGE_SIZE * erase_page); BSP_Flash_FastLock(); for (rt_uint8_t i = 0; i < (FLASH_PAGE_SIZE / 2); i++) { if (*(rt_uint16_t *)((hr_start_addr[record] + FLASH_PAGE_SIZE * erase_page) + 2 * i) != 0xE339) { flag = NoREADY; } } LOG_D ("/**Flash_Erase(%d)Page(%d)=%d**/", record, erase_page, flag); return flag; } void Flash_Erase_Records (TeRecord record) { for (rt_uint8_t erase_page = 0; erase_page < hr_record_pages[record]; erase_page++) { Flash_ErasePage_Records (record, erase_page); } LOG_D ("Flash_Erase_Records(%d)", record); } /* * @description: * @param {TeRecord} record * @return {*} */ static rt_uint16_t Flash_GetMaxIndex_Records (TeRecord record) { rt_uint16_t index_max = 0; for (rt_uint8_t page = 0; page < hr_record_pages[record]; page++) { for (rt_uint8_t i = 0; i < FLASH_PAGE_HR_RECORD_NUM; i++) { if (*(rt_uint16_t *)(hr_start_addr[record] + FLASH_PAGE_SIZE * page + FLASH_HR_ONE_RECORD_SIZE * i) == HR_RECORD_FRAME_HEADER) { index_max = LWUTIL_MAX (index_max, *(rt_uint16_t *)(hr_start_addr[record] + FLASH_PAGE_SIZE * page + FLASH_HR_ONE_RECORD_SIZE * i + 2)); } } } LOG_D ("Flash_Get_Records(%d)MaxNum = %d", record, index_max); return index_max; } /** * @description: * @param {TeRecord} record * @return {*} */ rt_uint8_t Flash_GetNum_Records (TeRecord record) { rt_uint8_t num = 0; rt_uint16_t num_max = Flash_GetMaxIndex_Records (record); if (num_max <= hr_record_max_num[record]) { num = num_max; } else { num = hr_record_max_num[record]; } LOG_D ("Flash_GetNum_(%d)Records = %d", record, num); return num; } /** * @description: * @param {TuFlashHrRecordFrame*} pHrRecord * @param {TeRecord} record * @param {uint8_t} index * @return {*} */ void Flash_Read_Record (TuFlashHrRecordFrame *pHrRecord, TeRecord record, rt_uint8_t index) { LOG_D ("/*********Flash_Read_(%d)Record(%d)***************/", record, index); uint16_t index_max = Flash_GetMaxIndex_Records (record); rt_uint8_t page_offset = 0; rt_uint8_t in_page_offset = 0; if (index <= index_max) { if (index_max > hr_record_max_num[record]) { if (record < kRecordSensoEndOfLife) { // index_redirect = index_max - (hr_record_max_num[record] - index); uint16_t index_redirect = index_max - (50 - index); LOG_D ("index_redirect = %d", index_redirect); page_offset = ((index_redirect - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record]; in_page_offset = ((index_redirect - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE; } else { page_offset = 0; in_page_offset = ((index_max - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE; } } else { page_offset = ((index - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record]; in_page_offset = ((index - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE; } LOG_D ("page_offset = %d", page_offset); LOG_D ("in_page_offset = %d", in_page_offset); uint32_t addr = (hr_start_addr[record] + FLASH_PAGE_SIZE * page_offset + in_page_offset); LOG_D ("addr = %04X", addr); Flash_Read (addr, pHrRecord->buf, HR_RECORD_FRAME_LEN); LOG_D ("Flash_Read_(%d)Record(%d):%04d-%02d-%02d,%02d:%02d", record, index, pHrRecord->Struct.year, pHrRecord->Struct.month, pHrRecord->Struct.day, pHrRecord->Struct.hour, pHrRecord->Struct.minute); } else { rt_memset (pHrRecord->buf, 0, HR_RECORD_FRAME_LEN); LOG_E ("Flash_GetMaxNum_(%d)Records Error!: (index_max)%d < %d", record, index_max, index); } } /** * @description: * @param {TuFlashHrRecordFrame*} pHrRecord * @param {uint16_t} index * @return {*} */ void Flash_Write_RecordIndex (TuFlashHrRecordFrame *pHrRecord, TeRecord record, rt_uint16_t index) { LOG_D ("/*********Flash_Write_RecordIndex***************/"); rt_uint8_t page_offset = ((index - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record]; LOG_D ("page_offset = %d", page_offset); rt_uint8_t in_page_offset = ((index - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE; LOG_D ("in_page_offset = %d", in_page_offset); rt_uint32_t addr = (hr_start_addr[record] + FLASH_PAGE_SIZE * page_offset + in_page_offset); LOG_D ("addr = %04X", addr); Flash_Write (addr, pHrRecord->buf, HR_RECORD_FRAME_LEN); TuFlashHrRecordFrame pReadRecord; Flash_Read (addr, pReadRecord.buf, HR_RECORD_FRAME_LEN); LOG_D ("(%04X)Flash_Write_(%d)RecordIndex(%d):%04d-%02d-%02d,%02d:%02d", pReadRecord.Struct.header, record, pReadRecord.Struct.index, pReadRecord.Struct.year, pReadRecord.Struct.month, pReadRecord.Struct.day, pReadRecord.Struct.hour, pReadRecord.Struct.minute); } void Flash_Write_Record (TeRecord record) { LOG_D ("/*********Flash_Write_Record***************/"); rt_uint16_t index_max = Flash_GetMaxIndex_Records (record); rt_uint16_t index_new = index_max + 1; LOG_D ("index_new = %d", index_new); rt_uint16_t index_start; rt_uint8_t index_start_page_offset; rt_uint8_t index_max_page_offset; rt_uint8_t index_max_in_page_offset; if (index_max <= hr_record_max_num[record]) { index_start = 0; index_start_page_offset = 0; index_max_page_offset = ((index_max - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record]; LOG_D ("index_max_page_offset = %d", index_max_page_offset); } else { index_start = index_max - (hr_record_max_num[record] - 1); LOG_D ("index_start = %d", index_start); index_start_page_offset = ((index_start - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record]; LOG_D ("index_start_page_offset = %d", index_start_page_offset); index_max_page_offset = ((index_max - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record]; } index_max_in_page_offset = (index_max - 1) % FLASH_PAGE_HR_RECORD_NUM; LOG_D ("index_max_in_page_offset = %d", index_max_in_page_offset); if ((index_max_in_page_offset + 1) == (FLASH_PAGE_HR_RECORD_NUM - 1) && index_max_page_offset == (hr_record_pages[record] - 1)) { Flash_ErasePage_Records (record, 0); } else if ((index_max_in_page_offset + 1) == (FLASH_PAGE_HR_RECORD_NUM - 1) && index_max_page_offset == index_start_page_offset - 1) { Flash_ErasePage_Records (record, index_max_page_offset + 1); } RTC_GetTime(); TuFlashHrRecordFrame HrRecord; HrRecord.Struct.header = HR_RECORD_FRAME_HEADER; HrRecord.Struct.index = index_new; HrRecord.Struct.year = RtcDateTime.year; HrRecord.Struct.month = RtcDateTime.month; HrRecord.Struct.day = RtcDateTime.day; HrRecord.Struct.hour = RtcDateTime.hour; HrRecord.Struct.minute = RtcDateTime.minute; Flash_Write_RecordIndex (&HrRecord, record, index_new); } void Flash_ErasePage_ConfigInfo (void) { BSP_Flash_FastUnLock(); FLASH_ErasePage_Fast (FLASH_CONFIG_INFO_START_ADDR); BSP_Flash_FastLock(); } void Flash_ErasePage_ReadConfigInfo (rt_uint8_t *page_buf) { Flash_Read (FLASH_CONFIG_INFO_START_ADDR, page_buf, FLASH_PAGE_SIZE); rt_thread_mdelay (10); Flash_ErasePage_ConfigInfo(); rt_thread_mdelay (10); } int Flash_Write_ConfigInfo (rt_uint8_t *page_buf) { return Flash_Write (FLASH_CONFIG_INFO_START_ADDR, page_buf, FLASH_PAGE_SIZE); } ErrorStatus Flash_GetProductTimeLimit (TuFlashProductTimeLimitFrame *pLimitTime, TeFlashProductTimeLimitId id) { ErrorStatus flag = NoREADY; rt_uint32_t addr = 0; if (id == kFactoryTimeId) { addr = FLASH_FACTORY_TIME_START_ADDR; } else if (id == kExpirationTimeId) { addr = FLASH_EXPIRATION_TIME_START_ADDR; } if (addr != 0) { Flash_Read (addr, pLimitTime->buf, sizeof (TuFlashProductTimeLimitFrame)); if (pLimitTime->Struct.header == FLASH_PRODUCT_TIME_FRAME_HEADER) { flag = READY; LOG_D ("Flash_GetProductTimeLimit(%d):%04d-%02d-%02d,%02d:%02d:%02d", id, pLimitTime->Struct.year, pLimitTime->Struct.month, pLimitTime->Struct.day, pLimitTime->Struct.hour, pLimitTime->Struct.minute, pLimitTime->Struct.second); } else { LOG_E ("Flash_GetProductTimeLimit Error!"); } } return flag; } void Flash_SetProductTimeLimit (rt_uint16_t year, rt_uint8_t mon, rt_uint8_t day, rt_uint8_t hour, rt_uint8_t min, rt_uint8_t second, TeFlashProductTimeLimitId id) { TuFlashProductTimeLimitFrame LimitTime; rt_uint8_t page_buf[FLASH_PAGE_SIZE]; Flash_ErasePage_ReadConfigInfo (page_buf); LimitTime.Struct.header = FLASH_PRODUCT_TIME_FRAME_HEADER; LimitTime.Struct.year = year; LimitTime.Struct.month = mon; LimitTime.Struct.day = day; LimitTime.Struct.hour = hour; LimitTime.Struct.minute = min; LimitTime.Struct.second = second; rt_uint8_t in_page_offset = 0; if (id == kFactoryTimeId) { in_page_offset = (FLASH_FACTORY_TIME_START_ADDR - FLASH_CONFIG_INFO_START_ADDR); } else if (id == kExpirationTimeId) { in_page_offset = (FLASH_EXPIRATION_TIME_START_ADDR - FLASH_CONFIG_INFO_START_ADDR); } for (rt_uint8_t i = 0; i < sizeof (TuFlashProductTimeLimitFrame); i++) { page_buf[in_page_offset + i] = LimitTime.buf[i]; } Flash_Write_ConfigInfo (page_buf); } void Set_ExpirationTime (rt_uint16_t days) { uint32_t factory_seconds, expiration_seconds; TuFlashProductTimeLimitFrame LimitTime; if (Flash_GetProductTimeLimit (&LimitTime, kFactoryTimeId) == READY) { factory_seconds = DateTime2Seconds (LimitTime.Struct.year, LimitTime.Struct.month, LimitTime.Struct.day, LimitTime.Struct.hour, LimitTime.Struct.minute, LimitTime.Struct.second); expiration_seconds = factory_seconds + days * 24 * 3600; TsRtcDateTime DateTime; Seconds2DateTime (expiration_seconds, &DateTime); Flash_SetProductTimeLimit (DateTime.year, DateTime.month, DateTime.day, DateTime.hour, DateTime.minute, DateTime.second, kExpirationTimeId); } } rt_uint8_t Flash_Sys_Cfg (TeFlashCfgInfoId id, rt_uint8_t *buf, rt_size_t len) { rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; Flash_ErasePage_ReadConfigInfo (page_buf); rt_uint8_t in_page_offset = (hr_sys_cfg_info_addr[id] - FLASH_CONFIG_INFO_START_ADDR); if (len > hr_sys_cfg_info_len[id]) { LOG_E ("Flash_Sys_Cfg: id value too long ->%d", id); LOG_D ("buf len %d > id len[%d]", len, hr_sys_cfg_info_len[id]); return -RT_ERROR; } for (rt_uint8_t i = 0; i < hr_sys_cfg_info_len[id]; i++) { page_buf[in_page_offset + i] = buf[i]; } return Flash_Write_ConfigInfo (page_buf); } /*这个返回一两个字节的数,方便提取*/ size_t Flash_Get_SysCfg (TeFlashCfgInfoId id) { rt_uint8_t iot_upload_cycle[2] = {0}; rt_uint16_t iot_upload; if (id != kIotUploadCycleId) { return *(rt_uint8_t *)hr_sys_cfg_info_addr[id]; } else { rt_memcpy (&iot_upload_cycle[0], (rt_uint8_t *)hr_sys_cfg_info_addr[id], 2); iot_upload = ((iot_upload_cycle[0] << 8) + iot_upload_cycle[1]); LOG_D ("iot_upload: %d", iot_upload); return iot_upload; } } ErrorStatus Flash_GetTotalRecord (TsTotalRecords *pTotalRecords) { ErrorStatus flag = NoREADY; pTotalRecords->alarm = Flash_GetNum_Records (kRecordAlarm); pTotalRecords->alarm_rcy = Flash_GetNum_Records (kRecordAlarmRcy); pTotalRecords->fault = Flash_GetNum_Records (kRecordFault); pTotalRecords->fault_rcy = Flash_GetNum_Records (kRecordFaultRcy); pTotalRecords->power_failure = Flash_GetNum_Records (kRecordPowerDown); pTotalRecords->power_on = Flash_GetNum_Records (kRecordPowerOn); pTotalRecords->sensor_failure = Flash_GetNum_Records (kRecordSensoEndOfLife); flag = READY; return flag; } ErrorStatus Flash_GetRecord (TeFrameC2 record_type, rt_uint8_t index, TsRecordsTime *pRecordsTime) { ErrorStatus flag = NoREADY; if (kNumOfRecords < record_type && record_type < kGetCurrentTime) { TuFlashHrRecordFrame pHrReadRecord; Flash_Read_Record (&pHrReadRecord, record_type - 1, index); LOG_D ("(%d)Flash_GetRecord(%d):%04d-%02d-%02d,%02d:%02d", record_type - 1, pHrReadRecord.Struct.index, pHrReadRecord.Struct.year, pHrReadRecord.Struct.month, pHrReadRecord.Struct.day, pHrReadRecord.Struct.hour, pHrReadRecord.Struct.minute); pRecordsTime->year_h = pHrReadRecord.Struct.year / 256; pRecordsTime->year_l = pHrReadRecord.Struct.year % 256; pRecordsTime->month = pHrReadRecord.Struct.month; pRecordsTime->day = pHrReadRecord.Struct.day; pRecordsTime->hour = pHrReadRecord.Struct.hour; pRecordsTime->minute = pHrReadRecord.Struct.minute; flag = READY; } return flag; } /** * @description: * @return {*} */ void BSP_Flash_EraseRecodrs (void) { for (rt_uint8_t record = 0; record <= kRecordSensoEndOfLife; record++) { for (rt_uint8_t i = 0; i < hr_record_pages[record]; i++) { Flash_ErasePage_Records (record, i); } } Flash_ErasePage_ConfigInfo(); } int BSP_Flash_Init (void) { rt_uint16_t flag_value = *(rt_uint16_t *)FLASH_INIT_FLAG_ADDR; rt_thread_mdelay(10); if (flag_value != FLASH_FIRST_INIT_VALUE) { LOG_D ("BSP_Flash_EraseRecodrs!"); rt_uint8_t flash_init_flag[2]; sys_config_info sci; rt_uint8_t sever_data[6] = {0}; flash_init_flag[0] = FLASH_FIRST_INIT_VALUE % 256; flash_init_flag[1] = FLASH_FIRST_INIT_VALUE / 256; BSP_Flash_EraseRecodrs(); Flash_Write (FLASH_INIT_FLAG_ADDR, flash_init_flag, sizeof (flash_init_flag)); Flash_Set_WorkDuration (work_duration); LOG_D ("work_duration:%d", Flash_Get_WorkDuration()); Convert_To_Hex (&sever_info, sever_data); if (Flash_Set_Sever_Data (sever_data) <= 0) { LOG_D ("Flash_Set_Sever_Data error!"); } Flash_SetProductTimeLimit (2025, 1, 19, 13, 50, 20, kFactoryTimeId); Set_ExpirationTime (MAX_EXPIRATION_DAYS); sci.hw_ver = SYS_HW_VERSION; sci.sw_ver = SYS_SW_VERSION; sci.alarm_l_value = SYS_ALARM_VALVE; sci.alarm_h_value = SYS_ALARM_VALVE_MAX; sci.iot_upload_cycle = SYS_IOT_UPLOAD_CYCLE_MIN; sci.iot_retry = SYS_IOT_RETRY; sci.temp_alarm_threshold = SYS_TEMP_ALARM_THRESHOLD; sci.emagnetic_switch = SYS_EMV_SWITCH; sci.relay_switch = SYS_RELAY_SWITCH; Flash_Write (FLASH_HW_VER_ADDR, (rt_uint8_t *)&sci, (sizeof (sys_config_info) - 50)); } return 0; } #ifdef RT_USING_COMPONENTS_INIT INIT_PREV_EXPORT (BSP_Flash_Init); #endif #ifdef TEST_ENABLE void TEST_Flash_GetMaxIndex_Records (int argc, char **argv) { if (argc == 2) { rt_uint8_t record = atoi (argv[1]); LOG_D ("Flash_GetMaxIndex_Records(%d) = %d", record, Flash_GetMaxIndex_Records (record)); } else { LOG_E ("TEST_Flash_GetMaxIndex_Records --use _cmd_ [record](0~6)"); } } MSH_CMD_EXPORT (TEST_Flash_GetMaxIndex_Records, "TEST_Flash_GetMaxIndex_Records"); static void TEST_Flash_Erase_Records (int argc, char **argv) { if (argc == 2) { int record = atoi (argv[1]); Flash_Erase_Records (record); } else { LOG_E ("TEST_Flash_Erase_Records --use _cmd_ [record](0~6)"); } } MSH_CMD_EXPORT (TEST_Flash_Erase_Records, "TEST_Flash_Erase_Records"); static void TEST_Flash_Write_Record (int argc, char **argv) { if (argc == 3) { int record = atoi (argv[1]); int num = atoi (argv[2]); for (rt_uint8_t i = 0; i < num; i++) { Flash_Write_Record (record); rt_thread_mdelay (2); // BSP_WDG_Loop(); } } else { LOG_E ("TEST_Flash_Write_Record --use _cmd_ [record(0~6)] [num]"); } } MSH_CMD_EXPORT (TEST_Flash_Write_Record, "TEST_Flash_Write_Record"); static void TEST_Flash_GetNum_Records (int argc, char **argv) { if (argc == 2) { int record = atoi (argv[1]); if (0 <= record && record <= 6) { LOG_D ("TEST_Flash_GetNum_Records(%d) = %d", record, Flash_GetNum_Records (record)); } else { LOG_E ("TEST_Flash_GetNum_Records --use _cmd_ [record](0~6)"); } } else { LOG_E ("TEST_Flash_GetNum_Records --use _cmd_ [record](0~6)"); } } MSH_CMD_EXPORT (TEST_Flash_GetNum_Records, "TEST_Flash_GetNum_Records"); static void TEST_Flash_GetProductTimeLimit (int argc, char **argv) { if (argc == 2) { int id = atoi (argv[1]); TuFlashProductTimeLimitFrame LimitTime; Flash_GetProductTimeLimit (&LimitTime, id); } else { LOG_E ( "TEST_Flash_GetProductTimeLimit --use _cmd_ [id(0:FACTORY; 1:EXPIRATION)]"); } } MSH_CMD_EXPORT (TEST_Flash_GetProductTimeLimit, "TEST_Flash_GetProductTimeLimit"); static void TEST_Flash_SetProductTimeLimit (int argc, char **argv) { if (argc == 8) { int year = atoi (argv[1]); int mon = atoi (argv[2]); int day = atoi (argv[3]); int hour = atoi (argv[4]); int min = atoi (argv[5]); int second = atoi (argv[6]); int id = atoi (argv[7]); Flash_SetProductTimeLimit (year, mon, day, hour, min, second, id); } else { LOG_E ( "TEST_Flash_SetProductTimeLimit --use _cmd_ [y] [m] [d] [h] [m] [s] [id(0:FACTORY; 1:EXPIRATION)]"); } } MSH_CMD_EXPORT (TEST_Flash_SetProductTimeLimit, "TEST_Flash_SetProductTimeLimit"); void Set_FactoryRtcTime (void) { RTC_GetTime(); LOG_D ("%4d-%02d-%02d, %02d:%02d:%02d", RtcDateTime.year, RtcDateTime.month, RtcDateTime.day, RtcDateTime.hour, RtcDateTime.minute, RtcDateTime.second); Flash_SetProductTimeLimit (RtcDateTime.year, RtcDateTime.month, RtcDateTime.day, RtcDateTime.hour, RtcDateTime.minute, RtcDateTime.second, kFactoryTimeId); } MSH_CMD_EXPORT (Set_FactoryRtcTime, "Use RTC time Set_FactoryRtcTime"); static void TEST_Flash_Set_ExpirationTime (int argc, char **argv) { if (argc == 2) { int days = atoi (argv[1]); Set_ExpirationTime (days); } else { LOG_E ("TEST_Flash_Set_ExpirationTime --use _cmd_ [days]"); } } MSH_CMD_EXPORT (TEST_Flash_Set_ExpirationTime, "TEST_Flash_Set_ExpirationTime"); static void TEST_Flash_Get_Sys_Info (int argc, char **argv) { if (argc == 2) { int id = atoi (argv[1]); Flash_Get_SysCfg (id); } else { LOG_E ("TEST_Flash_Get_Sys_Info "); } } MSH_CMD_EXPORT (TEST_Flash_Get_Sys_Info, "TEST_Flash_Get_Sys_Info"); #endif