CIU32_L051_M307R/bsp/src/bsp_flash.c

703 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author: mbw
* @Date: 2024-08-22 16:15:08
* @LastEditors: mbw && 1600520629@qq.com
* @LastEditTime: 2024-08-31 10:24:34
* @FilePath: \USART1_Interrupt - RT-Thread\bsp\src\bsp_flash.c
* @Description:
*
* Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
*/
#include "bsp_flash.h"
#include "bsp_rtc.h"
#include "rthw.h"
#include "stdlib.h"
#include "user_rtt.h"
#include "perf_counter.h"
#define LOG_TAG "bsp_flash" // 该模块对应的标签。不定义时默认NO_TAG
#define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别
#include <ulog.h> // 必须在 LOG_TAG 与 LOG_LVL 下面
// #define TEST 512
#define MAX(a, b) ((a) > (b)) ? (a) : (b)
ErrorStatus Flash_Write_Record(TeRecord record);
const 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 uint16_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 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 uint8_t hr_record_start_page_num[7] = {FLASH_HR_ALARM_PAGE, FLASH_HR_ALARM_RCY_PAGE,
FLASH_HR_FAULT_PAGE, FLASH_HR_FAULT_RCY_PAGE,
FLASH_HR_POWER_FAILURE_PAGE, FLASH_HR_POWER_ON_PAGE,
FLASH_HR_SENSOR_FAILIRE_START_PAGE};
// 定义常量
#define CHECKSUM_MASK 0xFF
// 数据帧结构体
typedef struct
{
uint32_t headerIndexChecksum; // 帧头、索引和校验和
uint32_t timestamp; // 时间戳
} DataFrame;
static rt_base_t interrupt_value;
static void BSP_Flash_UnLock(void)
{
interrupt_value = rt_hw_interrupt_disable();
/* Flash控制寄存器解锁 */
std_flash_unlock();
}
static void BSP_Flash_Lock(void)
{
/* Flash控制寄存器加锁 */
std_flash_lock();
rt_hw_interrupt_enable(interrupt_value);
}
// 计算和校验值
uint8_t Sum_Check(TuFlashHrRecordFrame *frame)
{
uint8_t sum = 0;
sum += (frame->time.year << 4) | frame->time.month;
sum += (frame->time.day << 3) | (frame->time.hour >> 2);
sum += ((frame->time.hour & 0x03) << 6) | frame->time.minute;
return ~sum; // 取反作为校验和
}
#if 1
/// @brief
/// @param addr
/// @param buf
/// @param len
/// @param mode 选择读的大小 字节 半字 字
/// @return
static size_t Flash_Read(uint32_t addr, uint8_t *buf, size_t len)
{
size_t read_len = 0;
for (size_t i = 0; i < len; i++, buf++, addr++, read_len++)
{
*buf = *(uint8_t *)addr;
}
return read_len;
}
/**
* @description: 向Flash中写入数据
* @param {uint32_t} addr
* @param {uint8_t} *buf
* @param {size_t} len
* @return {*}
*/
static std_status_t Flash_WriteWord(uint32_t addr, uint32_t write_data)
{
if (addr & 0x03 != 0) // 地址4字节对齐
{
LOG_E("addr %#X is not aligned\r\n", addr);
return ERROR;
}
/* 清除错误标志 */
std_flash_clear_flag(FLASH_FLAG_ALL_ERR);
BSP_Flash_UnLock();
if (std_flash_get_lock_status() == false)
{
if (std_flash_word_program(addr, write_data) != SUCCESS) // 写入操作 字节写入
{
LOG_D("addr = %#X, read %d", addr, *(uint32_t *)addr);
BSP_Flash_Lock();
return ERROR;
}
if (*(uint32_t *)addr != write_data)
{
LOG_D("Flash_Write Data Mismatch at addr %#X, expected %d got %d", addr, write_data, *(uint32_t *)addr);
BSP_Flash_Lock();
return ERROR;
}
}
BSP_Flash_Lock();
return SUCCESS;
}
static std_status_t Flash_WritePage(uint32_t addr, uint32_t *buf)
{
std_status_t status = SUCCESS;
if (addr & 0x03 != 0) // 地址4字节对齐
{
LOG_E("addr %#X is not aligned\r\n", addr);
return ERROR;
}
for (int i = 0; i < FLASH_HR_PAGE_NUM; i++) // 页写入的WORD数
{
status = Flash_WriteWord((addr + i * sizeof(uint32_t)), *(buf + i)); // 注意地址增加应按uint32_t大小增加
if (status != SUCCESS)
{
return status; // 返回错误状态
}
}
return status; // 如果所有写入成功返回SUCCESS
}
/**
* @description: 擦除产品信息页
* @return {*}
*/
void Flash_ErasePage_ConfigInfo(void)
{
if (std_flash_page_erase(127) != SUCCESS)
{
LOG_D("error_page = %#x\r\n");
}
}
/**
* @description: 写产品信息页(最后一页)
* @param {uint8_t*} frame
* @return {*}
*/
void Flash_Write_ConfigInfo(uint32_t *frame)
{
Flash_WritePage(FLASH_CONFIG_INFO_START_ADDR, frame);
}
/*获取当前页号*/
uint32_t Flash_Get_Current_Page(uint32_t addr)
{
return (addr - FLASH_START_ADDR) / FLASH_PAGE_BYTE_SIZE;
}
std_status_t Flash_ErasePage(uint32_t index)
{
BSP_Flash_UnLock();
RTT_LOG_D("ErasePage %d", index);
std_status_t status = std_flash_erase(FLASH_ERASE_PAGE, index);
BSP_Flash_Lock();
return status;
}
/**
* @description: 擦除历史记录区的页
* @param {TeRecord} addr 需要擦除的页的起始地址
* @return {*}
*/
static ErrorStatus Flash_ErasePage_Records(TeRecord record, uint8_t page_offset)
{
ErrorStatus flag = SUCCESS;
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;
}
if (Flash_ErasePage(Flash_Get_Current_Page(hr_start_addr[record] + erase_page * FLASH_PAGE_BYTE_SIZE)) != SUCCESS)
{
return ERROR;
}
for (uint16_t i = 0; i < FLASH_PAGE_BYTE_SIZE; i++) // 检查擦除是否完整
{
if (*(uint32_t *)((hr_start_addr[record] + FLASH_PAGE_BYTE_SIZE * erase_page) + i) != FLASH_DEFAULT_VALUE)
{
flag = ERROR;
}
}
return flag;
}
/**
* @description: 擦除数据记录区
* @return {*}
*/
void BSP_Flash_EraseRecodrs(void)
{
/*擦除所有的历史记录区*/
for (TeRecord record = kRecordAlarm; record < kRecordSensorFailure; record++)
{
for (uint8_t i = 0; i < hr_record_pages[record]; i++)
{
Flash_ErasePage_Records(record, i);
}
}
/*擦除初始信息区*/
Flash_ErasePage_ConfigInfo();
}
/**
* @description: 先读再擦,以确保原有数据不会被擦除
* @param {uint8_t} *page_buf
* @return {*}
*/
void Flash_ErasePage_ReadConfigInfo(uint8_t *page_buf)
{
Flash_Read(FLASH_CONFIG_INFO_START_ADDR, page_buf, FLASH_PAGE_BYTE_SIZE);
Flash_ErasePage_ConfigInfo();
}
#if 0
/**
* @description: 获取产品的出厂或到期时间
* @return {*}
*/
ErrorStatus Flash_GetProductTimeLimit(TuFlashProductTimeLimitFrame *pLimitTime, TeFlashProductTimeLimitId id)
{
ErrorStatus flag = ERROR;
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));
// LOG_D("pLimitTime->Struct.header = %#x\r\n", pLimitTime->Struct.header);
if (pLimitTime->Struct.header == FLASH_PRODUCT_TIME_FRAME_HEADER)
{
flag = SUCCESS;
LOG_D("Flash_GetProductTimeLimit(%d):%04d-%02d-%02d,%02d:%02d:%02d\r\n", id,
pLimitTime->Struct.year, pLimitTime->Struct.month, pLimitTime->Struct.day,
pLimitTime->Struct.hour, pLimitTime->Struct.minute, pLimitTime->Struct.second);
}
else
{
LOG_D("Flash_GetProductTimeLimit Error!");
}
}
return flag;
}
/**
* @description: 设置产品的出厂或到期时间
* @param {uint16_t} year
* @param {uint8_t} mon
* @param {uint8_t} day
* @param {uint8_t} hour
* @param {uint8_t} min
* @param {uint8_t} second
* @param {TeFlashProductTimeLimitId} id
* @return {*}
*/
void Flash_SetProductTimeLimit(uint16_t year, uint8_t mon, uint8_t day, uint8_t hour, uint8_t min, uint8_t second, TeFlashProductTimeLimitId id)
{
TuFlashProductTimeLimitFrame LimitTime;
TuFlashProductTimeLimitFrame ReadLimitTime;
uint8_t in_page_offset = 0;
uint8_t page_buf[FLASH_PAGE_SIZE] = {0}; // 暂存最后一页的值
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;
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 (uint8_t i = 0; i < sizeof(TuFlashProductTimeLimitFrame); i++)
{
page_buf[in_page_offset + i] = LimitTime.buf[i];
}
Flash_Write_ConfigInfo(&page_buf[0]);
Flash_GetProductTimeLimit(&ReadLimitTime, id);
}
#endif
/**
* @description: 产品信息初始化,
* @return {*}
*/
void BSP_Flash_Init(void)
{
if (*(uint32_t *)FLASH_CONFIG_INFO_START_ADDR != FLASH_FIRST_INIT_VALUE)
{
uint32_t info_page_buf[128] = {0};
BSP_Flash_EraseRecodrs(); // 擦除历史数据区
// TODO: 此处需要完善,比如写入初始化标志位,写入产品信息,写入出厂时间,写入到期时间,
Flash_WritePage(FLASH_CONFIG_INFO_START_ADDR, info_page_buf);
}
}
/**
* @description: 获取索引起始地址
* @param {TeRecord} record
* @return {*}
*/
TsRecordIndex Flash_GetIndex_Pos(TeRecord record)
{
uint32_t imdex_addr = RT_NULL;
TsRecordIndex Index_Frame = {0};
for (uint8_t page = 1; page <= hr_record_pages[record]; page++) // 遍历对应项的历史数据扇区
{
for (uint8_t i = 0; i < FLASH_HR_PAGE_RECORD_NUM; i++) // 获取扇区偏移量
{
imdex_addr = (hr_start_addr[record] + FLASH_PAGE_BYTE_SIZE * (page - 1) + HR_RECORD_FRAME_LEN * i);
if (*(uint32_t *)imdex_addr == FLASH_DEFAULT_VALUE)
{
/*获取最新的数据所在位置如果值为0xFFFFFFFF则表示该页有空位是最新的页*/
if (page < hr_record_pages[record]) // 当前页不是最后一页
{
if (*(uint32_t *)(imdex_addr + FLASH_PAGE_BYTE_SIZE) == FLASH_DEFAULT_VALUE)
{
/* 没进行循环写入*/
Index_Frame.hr_start_addr = hr_start_addr[record];
Index_Frame.hr_index_addr = imdex_addr;
Index_Frame.hr_num = (imdex_addr - hr_start_addr[record]) / HR_RECORD_FRAME_LEN;
Index_Frame.hr_page = page;
return Index_Frame;
}
else // 已经开始循环了
{
Index_Frame.hr_start_addr = (imdex_addr + FLASH_PAGE_BYTE_SIZE);
Index_Frame.hr_index_addr = imdex_addr;
Index_Frame.hr_num = hr_record_max_num[record];
Index_Frame.hr_page = page;
return Index_Frame;
}
}
else // 当前页是最后一页,那么首地址应该在第一页,其偏移量是最后一页的偏移量
{
Index_Frame.hr_start_addr = (hr_start_addr[record] + HR_RECORD_FRAME_LEN * i);
Index_Frame.hr_index_addr = imdex_addr;
Index_Frame.hr_num = hr_record_max_num[record];
Index_Frame.hr_page = page;
if (1 == hr_record_max_num[record])// 只有一条数据,则索引地址应该在第一页
{
Index_Frame.hr_start_addr = hr_start_addr[record];
}
return Index_Frame;
}
}
}
}
RTT_LOG_E("Flash_GetIndex_Pos Error!");
return Index_Frame;
}
/**
* @description:
* @param {TuFlashHrRecordFrame} *pHrRecord
* @param {TeRecord} record
* @param {uint8_t} index
* @return {*}
*/
ErrorStatus Flash_Read_Record(TuFlashHrRecordFrame *pHrRecord, TeRecord record, size_t index)
{
// LOG_D("/*********************Flash_Read_Record**********************/");
TsRecordIndex Index_Frame = Flash_GetIndex_Pos(record); // 已存储的数量
uint32_t index_addr = 0;
if (index <= hr_record_max_num[record])
{
if (index <= Index_Frame.hr_num)
{
{
if (Index_Frame.hr_start_addr == hr_start_addr[record]) // 是默认的起始地址,则读取数据就是对应的偏移量
{
index_addr = hr_start_addr[record] + (index - 1) * HR_RECORD_FRAME_LEN;
}
else
{
if ((Index_Frame.hr_start_addr + index * HR_RECORD_FRAME_LEN) <=
hr_record_pages[record] * FLASH_PAGE_BYTE_SIZE + hr_start_addr[record]) // 没超过所在项目的页最大地址,正常读取,此时应该在缓存页
{
RTT_LOG_D("read :hr_start_addr1 = %#x", Index_Frame.hr_start_addr);
index_addr = Index_Frame.hr_start_addr + (index - 1) * HR_RECORD_FRAME_LEN;
}
else // 超过了所在项目的最大地址
{
RTT_LOG_D("read :hr_start_addr2 = %#x", Index_Frame.hr_start_addr);
index_addr = (Index_Frame.hr_start_addr + (index - 1) * HR_RECORD_FRAME_LEN - hr_record_pages[record] * FLASH_PAGE_BYTE_SIZE);
}
}
}
{
pHrRecord->hr_data = (*(uint32_t *)index_addr);
if (pHrRecord->time.check_sum == Sum_Check(pHrRecord))
{
// RTT_LOG_D("Flash_Read_(%d)Record(%d):%04d-%02d-%02d,%02d:%02d", record, index,
// BASE_YEAR + pHrRecord->time.year, pHrRecord->time.month, pHrRecord->time.day,
// pHrRecord->time.hour, pHrRecord->time.minute);
RTT_LOG_D("read :hr_start_addr = %#x, hr_index_addr: %#x, hr_num: %d, hr_page:%d, read_data : %#X\r\n",
Index_Frame.hr_start_addr, index_addr, Index_Frame.hr_num, Index_Frame.hr_page, pHrRecord->hr_data);
return SUCCESS;
}
else
{
RTT_LOG_E("Error Time: %d-%d-%d,%d:%d", pHrRecord->time.year, pHrRecord->time.month, pHrRecord->time.day,
pHrRecord->time.hour, pHrRecord->time.minute);
RTT_LOG_E("read :hr_start_addr = %#x, hr_index_addr: %#x, hr_num: %d, hr_page:%d, read_data : %#X",
Index_Frame.hr_start_addr, index_addr, Index_Frame.hr_num, Index_Frame.hr_page, pHrRecord->hr_data);
RTT_LOG_E("Flash_GetMaxNum((%d)_Records(%d) Sum_Check(%#X) != check_sum(%#X),index_addr :%#X\r\n",
Index_Frame.hr_num, record, Sum_Check(pHrRecord), pHrRecord->time.check_sum, index_addr);
pHrRecord->hr_data = FLASH_DEFAULT_VALUE; // 默认值
return ERROR;
}
}
}
else
{
RTT_LOG_E("index num (%d) > Actual storage num %d", index, Index_Frame.hr_num);
return ERROR;
}
}
else
{
RTT_LOG_E("index num (%d) > hr record max num %d", index, hr_record_max_num[record]);
return ERROR;
}
}
/**
* @description: 向对应的历史数据存储区写入一次数据
* @param {TeRecord} record
* @return {*}
*/
ErrorStatus Flash_Write_Record(TeRecord record)
{
uint8_t rtctime[3], rtcdate[3];
TuFlashHrRecordFrame RecoderFrame = {0};
TsRecordIndex Index_Frame;
Index_Frame = Flash_GetIndex_Pos(record);
__cycleof__("my algorithm")
{
BSP_Rtc_Get_Calendar(rtcdate, rtctime);
}
if (record == kRecordSensorFailure && Index_Frame.hr_num >= HR_FAULT_MAX_NUM)
{
RTT_LOG_E("Flash_Write_(%d)Record(%d) num >= recorded Max num(%d)",
record, Index_Frame.hr_num, hr_record_max_num[record]);
return ERROR;
}
RecoderFrame.time.year = (std_rtc_convert_bcd2bin(rtcdate[0]) - 24);
RecoderFrame.time.month = std_rtc_convert_bcd2bin(rtcdate[1]);
RecoderFrame.time.day = std_rtc_convert_bcd2bin(rtcdate[2]);
RecoderFrame.time.hour = std_rtc_convert_bcd2bin(rtctime[0]);
RecoderFrame.time.minute = std_rtc_convert_bcd2bin(rtctime[1]);
RecoderFrame.time.check_sum = Sum_Check(&RecoderFrame);
RTT_LOG_D("write:hr_start_addr = %#x, hr_index_addr: %#x, hr_num: %d, hr_page:%d, write_data : %#X",
Index_Frame.hr_start_addr, Index_Frame.hr_index_addr, Index_Frame.hr_num, Index_Frame.hr_page, RecoderFrame.hr_data);
RTT_LOG_D("Flash_Write_(%d)Record:%04d-%02d-%02d %02d:%02d, check_sum : %#X",
record, RecoderFrame.time.year + BASE_YEAR, RecoderFrame.time.month, RecoderFrame.time.day,
RecoderFrame.time.hour, RecoderFrame.time.minute, RecoderFrame.time.check_sum);
{
/*写入数据*/
if (Flash_WriteWord(Index_Frame.hr_index_addr, RecoderFrame.hr_data) != SUCCESS)
{
RTT_LOG_E("hr_write_data_error");
RTT_LOG_E("hr_start_addr = %#x, hr_index_addr: %#x, hr_num: %d, hr_page:%d, write_data : %#X",
Index_Frame.hr_start_addr, Index_Frame.hr_index_addr, Index_Frame.hr_num, Index_Frame.hr_page, RecoderFrame.hr_data);
return ERROR;
}
}
{
/*如果把当前页写完了,要把下一页擦了,这样索引才不会出错,否则会导致索引出错*/
if (Index_Frame.hr_index_addr == hr_start_addr[record] + (Index_Frame.hr_page) * FLASH_PAGE_BYTE_SIZE - HR_RECORD_FRAME_LEN)
{
RTT_LOG_I("Index_Frame.hr_index_addr = hr_start_addr[record] + i * FLASH_PAGE_BYTE_SIZE - HR_RECORD_FRAME_LEN = %#X", Index_Frame.hr_index_addr);
if (hr_record_pages[record] - Index_Frame.hr_page > 0) // 当前页不是最后一页,还不需要返回擦
{
if (Flash_ErasePage(Index_Frame.hr_page + hr_record_start_page_num[record]) != SUCCESS)
{
RTT_LOG_I("Erase Page %d", Index_Frame.hr_page + hr_record_start_page_num[record]);
return ERROR;
}
}
else // 当前页是最后一页 此时需要将第一页擦除掉
{
if (Flash_ErasePage(hr_record_start_page_num[record]) != SUCCESS) // 擦除第一页
{
RTT_LOG_I("Erase Page %d", hr_record_start_page_num[record]);
return ERROR;
}
}
}
}
{
if (Index_Frame.hr_num < hr_record_max_num[record])
{
Flash_Read_Record(&RecoderFrame, record, Index_Frame.hr_num + 1); // 读取刚才写入数据
}
else // 超了最大数后,每次读出来的数据都是最大数
{
Flash_Read_Record(&RecoderFrame, record, Index_Frame.hr_num); // 读取刚才写入数据
}
}
return SUCCESS;
}
static void TEST_Flash_Write_Record(int argc, char **argv)
{
if (argc == 3)
{
TeRecord record = (TeRecord)atoi(argv[1]);
int num = atoi(argv[2]);
for (uint8_t i = 0; i < num; i++)
{
Flash_Write_Record(record);
rt_thread_mdelay(100);
}
}
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_Read_Record(int argc, char **argv)
// {
// TuFlashHrRecordFrame RecoderFrame = {0};
// if (argc == 3)
// {
// TeRecord record = (TeRecord)atoi(argv[1]);
// int num = atoi(argv[2]);
// Flash_Read_Record(&RecoderFrame, record, num);
// }
// else
// {
// LOG_E("TEST_Flash_Read_Record --use _cmd_ [record(0~6)] [num]");
// }
// }
// MSH_CMD_EXPORT(TEST_Flash_Read_Record, "TEST_Flash_Read_Record");
/*获取当前项目记录数*/
uint8_t Flash_GetNum_Records(TeRecord record)
{
TsRecordIndex Index_Frame = Flash_GetIndex_Pos(record);
return Index_Frame.hr_num;
}
/**
* @description: 获取总记录数
* @param {TsTotalRecords} *pTotalRecords
* @return {*}
* @note:
*/
ErrorStatus Flash_GetTotalRecord(TsTotalRecords *pTotalRecords)
{
ErrorStatus flag = ERROR;
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(kRecordPowerFailure);
pTotalRecords->power_on = Flash_GetNum_Records(kRecordPowerOn);
pTotalRecords->sensor_failure = Flash_GetNum_Records(kRecordSensorFailure);
flag = SUCCESS;
return flag;
}
/**
* @brief 获取记录时间
* @param record_type
* @param index
* @param pRecordsTime
* @return ErrorStatus
*/
ErrorStatus Flash_GetRecord(TeFrameC2 record_type, uint8_t index, TsRecordsTime *pRecordsTime)
{
ErrorStatus flag = ERROR;
uint16_t years = 0;
if (kNumOfRecords < record_type && record_type < kGetCurrentTime)
{
TuFlashHrRecordFrame pHrReadRecord;
Flash_Read_Record(&pHrReadRecord, (TeRecord)(record_type - 1), index);
years = BASE_YEAR + pHrReadRecord.time.year;
LOG_D("(%d)Flash_GetRecord[%d]:%04d-%02d-%02d,%02d:%02d",
record_type - 1, index,
years, pHrReadRecord.time.month, pHrReadRecord.time.day,
pHrReadRecord.time.hour, pHrReadRecord.time.minute);
pRecordsTime->year_h = years / 256;
pRecordsTime->year_l = years % 256;
pRecordsTime->month = pHrReadRecord.time.month;
pRecordsTime->day = pHrReadRecord.time.day;
pRecordsTime->hour = pHrReadRecord.time.hour;
pRecordsTime->minute = pHrReadRecord.time.minute;
flag = SUCCESS;
}
return flag;
}
#endif