#include "bsp_flash.h" #include "lwutil.h" #include "bsp_rtc.h" #include "bsp_hr.h" #include "at_device_ml307.h" #include #include #define LOG_TAG "bsp_flash" #define LOG_LVL LOG_LVL_DBG #include #include //在此修改默认的服务器地址 struct flash_sever_info sever_info = { .server_url = "8.130.122.162", .server_port = "7153", // .server_port = "36078", // .server_url = "8.135.10.183", }; extern int Convert_To_Hex(const struct flash_sever_info *sever_info, uint8_t *hex_array); #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)->nb_upload_cycle) \ : (id) == kIotRetryId ? (&(info)->nb_retry) \ : (id) == kEmagneticSwitchId ? (&(info)->emagnetic_switch) \ : (id) == kRelaySwitchId ? (&(info)->relay_switch) \ : (id) == kIotImeiId ? ((info)->nb_imei) \ : (id) == kIotImsiId ? ((info)->nb_imsi) \ : (id) == kIotIccidId ? ((info)->nb_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_NB_UPLOAD_CYCLE_ADDR, FLASH_NB_RETRY_ADDR, FLASH_TEMP_ALARM_THRESHOLD_ADDR, FLASH_EMAGNETIC_SWITCH_ADDR, FLASH_RELAY_SWITCH_ADDR, FLASH_NB_IMEI_ADDR, FLASH_NB_IMSI_ADDR, FLASH_NB_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_NB_UPLOAD_CYCLE_LEN, FLASH_NB_RETRY_LEN, FLASH_TEMP_ALARM_THRESHOLD_LEN, FLASH_EMAGNETIC_SWITCH_LEN, FLASH_RELAY_SWITCH_LEN, FLASH_NB_IMEI_LEN, FLASH_NB_IMSI_LEN, FLASH_NB_ICCID_LEN, }; static rt_base_t interrupt_value; /*默认的系统配置*/ rt_uint8_t sys_hw_ver = 0x10; rt_uint8_t sys_sw_ver = 0x11; rt_uint8_t sys_nb_retry = 0x03; // 重试次数3次 rt_uint16_t sys_nb_upload_cycle = 0x0078; // 120分钟一次 rt_uint16_t sys_alarm_h_value = 0x0032; // 50 rt_uint16_t sys_alarm_l_value = 0x09C4; // 2500 rt_uint8_t sys_temp_alarm_threshold = 0x32; rt_uint8_t sys_emagnetic_switch = 0x04; // 具备阀门功能 rt_uint8_t sys_relay_switch = 0x04; // 具备继电器功能 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_Iot_Imei(char *buf, rt_size_t len) { if ((*(rt_uint8_t *)FLASH_NB_IMEI_ADDR != 0xE3)&&(*(rt_uint8_t *)FLASH_NB_IMEI_ADDR != 0x39)) { rt_memcpy(buf, (char *)FLASH_NB_IMEI_ADDR, len); LOG_D("NB IMEI: %s", buf); return 0; } else { /*如果没有写进去,则全部是0*/ for (rt_uint8_t i = 0; i < len; i++) { buf[i] = '0'; } LOG_D("NB IMSI: %s", buf); return -1; } } int Get_Iot_Imsi(char *buf, rt_size_t len) { if ((*(rt_uint8_t *)FLASH_NB_IMSI_ADDR != 0xE3)&&(*(rt_uint8_t *)FLASH_NB_IMSI_ADDR != 0x39)) { rt_memcpy(buf, (char *)FLASH_NB_IMSI_ADDR, len); LOG_D("NB IMSI: %s", buf); return 0; } else { /*如果没有写进去,则全部是0*/ for (rt_uint8_t i = 0; i < len; i++) { buf[i] = '0'; } LOG_D("NB IMSI: %s", buf); return -1; } } int Get_Iot_Iccid(char *buf, rt_size_t len) { if ((*(rt_uint8_t *)FLASH_NB_ICCID_ADDR != 0xE3)&&(*(rt_uint8_t *)FLASH_NB_ICCID_ADDR != 0x39)) { rt_memcpy(buf, (char *)FLASH_NB_ICCID_ADDR, len); LOG_D("NB ICCID: %s", buf); return 0; } else { /*如果没有写进去,则全部是0*/ for (rt_uint8_t i = 0; i < len; i++) { buf[i] = '0'; } LOG_D("NB 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_uint16_t *)(page_buf + in_page_offset) = value; return Flash_Write_ConfigInfo(page_buf); } int Flash_Get_Sever_Addr_Info(struct flash_sever_info *sever_info) { rt_uint8_t data[FLASH_SERVER_LEN]; rt_memcpy(data, (rt_uint8_t *)FLASH_SERVER_ADDR_ADDR, FLASH_SERVER_LEN); if (data == RT_NULL) { LOG_E("Flash_Get_Sever_Addr_Info failed"); return -RT_ERROR; } 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_Addr_Info(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); } TeCalibrationStatus Flash_Get_Calibration_State(void) { return *(rt_uint8_t *)FLASH_CALIBRATION_STATUS_ADDR; } int Flash_Set_Calibration_State(TeCalibrationStatus status) { rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; rt_uint8_t in_page_offset = (FLASH_CALIBRATION_STATUS_ADDR - FLASH_CONFIG_INFO_START_ADDR); LOG_D("FLASH_CALIBRATION_STATUS_ADDR = %X", FLASH_CALIBRATION_STATUS_ADDR); Flash_ErasePage_ReadConfigInfo(page_buf); //*将传入的数据写到flash地址中 page_buf[in_page_offset] = status; return Flash_Write_ConfigInfo(page_buf); } /*写入MAC地址*/ int Flash_Set_Mac_Addr(rt_uint8_t *mac_addr, rt_uint8_t number) { rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; rt_uint8_t in_page_offset = ((FLASH_VALVE_1_MAC_ADDR_ADDR + number * FLASH_VALVE_MAC_ADDR_LEN) - FLASH_CONFIG_INFO_START_ADDR); if (mac_addr == RT_NULL) { return -RT_ERROR; } Flash_ErasePage_ReadConfigInfo(page_buf); for (size_t i = 0; i < FLASH_VALVE_MAC_ADDR_LEN; i++) { page_buf[in_page_offset++] = mac_addr[i]; } return Flash_Write_ConfigInfo(page_buf); } /*读取MAC地址*/ int Flash_Get_Mac_Addr(rt_uint8_t *mac_addr, rt_uint8_t number) { rt_uint8_t data[FLASH_VALVE_MAC_ADDR_LEN]; char mac[16] = {20}; rt_memcpy(data, (rt_uint8_t *)(FLASH_VALVE_1_MAC_ADDR_ADDR + number * FLASH_VALVE_MAC_ADDR_LEN), FLASH_VALVE_MAC_ADDR_LEN); if (data == RT_NULL) { LOG_E("Flash_Get_Mac_Addr failed"); return -RT_ERROR; } //进行两次判断的原因主要为,防止MAC地址确实有个e3或者e99,但是MAC地址确是正确的情况,防止出现错误,两次判断可以从一定程度上降低这种风险 if (((data[0] == 0xe3) || (data[0] == 0x39))&&((data[1] == 0xe3) || (data[1] == 0x39))) { rt_memset(data, 0, sizeof(data)); return RT_EEMPTY; } rt_snprintf(mac, 20, "%02x:%02x:%02x:%02x:%02x:%02x", data[5], data[4], data[3], data[2], data[1], data[0]); LOG_I("mac_addr:%s", mac); rt_memcpy(mac_addr, data, FLASH_VALVE_MAC_ADDR_LEN); return RT_EOK; } /*设置无线调压器数量*/ int Flash_Set_Valve_Num(rt_uint8_t valve_num) { rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; rt_uint8_t in_page_offset = (FLASH_VALVE_NUM_ADDR - FLASH_CONFIG_INFO_START_ADDR); Flash_ErasePage_ReadConfigInfo(page_buf); page_buf[in_page_offset] = valve_num; return Flash_Write_ConfigInfo(page_buf); } /*获取无线调压器数量*/ rt_uint8_t Flash_Get_Valve_Num(void) { return *(rt_uint8_t *)FLASH_VALVE_NUM_ADDR; } /** * @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); Flash_ErasePage_ConfigInfo(); } 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); TuFlashProductTimeLimitFrame ReadLimitTime; Flash_GetProductTimeLimit(&ReadLimitTime, id); } 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); LOG_D("FactoryTime:%04d-%02d-%02d,%02d:%02d", 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; // LOG_D("factory_seconds = %d, expiration_seconds = %d", factory_seconds, expiration_seconds); TsRtcDateTime DateTime; Seconds2DateTime(expiration_seconds, &DateTime); Flash_SetProductTimeLimit(DateTime.year, DateTime.month, DateTime.day, DateTime.hour, DateTime.minute, DateTime.second, kExpirationTimeId); if (Flash_GetProductTimeLimit(&LimitTime, kExpirationTimeId) == READY) { LOG_D("Flash_GetProductTimeLimit:%04d-%02d-%02d,%02d:%02d:%02d", LimitTime.Struct.year, LimitTime.Struct.month, LimitTime.Struct.day, LimitTime.Struct.hour, LimitTime.Struct.minute, LimitTime.Struct.second); } } } 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) { size_t value = 0; if (hr_sys_cfg_info_len[id] == 1) { return *(rt_uint8_t *)hr_sys_cfg_info_addr[id]; } else if (hr_sys_cfg_info_len[id] == 2) { rt_uint8_t buf[2] = {0}; rt_memcpy(&buf, (rt_uint8_t *)hr_sys_cfg_info_addr[id], hr_sys_cfg_info_len[id]); value = buf[0] | (buf[1] << 8); LOG_D("buf[0]= %u, buf[1]: %u", buf[0], buf[1]); } LOG_D("value: %u", value); return value; } 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); } // LOG_D("/**BSP_Flash_First_Init (%d)**/", record); } Flash_ErasePage_ConfigInfo(); } int BSP_Flash_Init(void) { if (*(rt_uint16_t *)FLASH_INIT_FLAG_ADDR != 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_SetProductTimeLimit(2024, 9, 8, 13, 58, 20, kFactoryTimeId); Flash_SetProductTimeLimit(2024 + 8, 9, 8, 13, 58, 20, kExpirationTimeId); sci.hw_ver = sys_hw_ver; sci.sw_ver = sys_sw_ver; sci.alarm_l_value = sys_alarm_l_value; sci.alarm_h_value = sys_alarm_h_value; sci.nb_upload_cycle = sys_nb_upload_cycle; sci.nb_retry = sys_nb_retry; sci.temp_alarm_threshold = sys_temp_alarm_threshold; sci.emagnetic_switch = sys_emagnetic_switch; sci.relay_switch = sys_relay_switch; Flash_Set_WorkDuration(work_duration); LOG_D("work_duration:%d", Flash_Get_WorkDuration()); Convert_To_Hex(&sever_info, sever_data); for (size_t i = 0; i < sizeof(sever_data); i++) { LOG_D("%02x", sever_data[i]); } if(Flash_Set_Sever_Addr_Info(sever_data) <= 0) { LOG_D("Flash_Set_Sever_Addr_Info error!"); } Flash_Set_Calibration_State(kSysGasCalibStatus);//未标定状态 Flash_Set_Valve_Num(0); Flash_Write(FLASH_HW_VER_ADDR, (rt_uint8_t *)&sci, (sizeof(sys_config_info) - 50)); } return 0; } #ifdef RT_USING_COMPONENTS_INIT INIT_BOARD_EXPORT(BSP_Flash_Init); #endif #ifdef TEST_ENABLE static 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