2024-08-31 10:27:58 +08:00
/*
* @ Author : mbw
* @ Date : 2024 - 08 - 22 16 : 15 : 08
* @ LastEditors : mbw & & 1600520629 @ qq . com
2024-09-20 11:14:25 +08:00
* @ LastEditTime : 2024 - 09 - 20 10 : 39 : 08
2024-08-31 10:27:58 +08:00
* @ FilePath : \ USART1_Interrupt - RT - Thread \ bsp \ src \ bsp_flash . c
2024-09-04 09:01:05 +08:00
* @ Description :
*
* Copyright ( c ) 2024 by $ { git_name_email } , All Rights Reserved .
2024-08-31 10:27:58 +08:00
*/
2024-09-02 16:09:03 +08:00
2024-08-31 10:27:58 +08:00
# include "bsp_flash.h"
# include "bsp_rtc.h"
# include "rthw.h"
# include "stdlib.h"
# include "user_rtt.h"
# define LOG_TAG "bsp_flash" // 该模块对应的标签。不定义时, 默认: NO_TAG
# define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别
# include <ulog.h> // 必须在 LOG_TAG 与 LOG_LVL 下面
2024-09-04 09:01:05 +08:00
# define FSTPG_WORD_COUNT (0x40U)
2024-08-31 10:27:58 +08:00
// #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 ,
2024-09-18 14:03:55 +08:00
FLASH_HR_power_down_START_ADDR , FLASH_HR_POWER_ON_START_ADDR ,
2024-08-31 10:27:58 +08:00
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 ,
2024-09-18 14:03:55 +08:00
HR_power_down_MAX_NUM , HR_POWER_ON_MAX_NUM ,
2024-08-31 10:27:58 +08:00
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 ,
2024-09-18 14:03:55 +08:00
HR_power_down_PAGES , HR_POWER_ON_PAGES ,
2024-08-31 10:27:58 +08:00
HR_SENSOR_FAILURE_PAGES } ;
2024-08-31 14:50:41 +08:00
/*定义历史数据所在的真实起始页*/
2024-08-31 10:27:58 +08:00
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 ,
2024-09-18 14:03:55 +08:00
FLASH_HR_power_down_PAGE , FLASH_HR_POWER_ON_PAGE ,
2024-08-31 10:27:58 +08:00
FLASH_HR_SENSOR_FAILIRE_START_PAGE } ;
2024-09-02 15:12:26 +08:00
/*定义信息页的数据地址*/
const uint32_t hr_record_info_start_addr [ 9 ] = {
FLASH_CONFIG_INFO_INIT_FLAG_ADDR ,
FLASH_FACTORY_TIME_ADDR ,
FLASH_EXPIRATION_TIME_ADDR ,
FLASH_LOW_ALARM_VALUE_ADDR ,
FLASH_HIGH_ALARM_VALUE_ADDR ,
FLASH_SOFTWARE_VERSION_ADDR ,
FLASH_HARDWARE_VERSION_ADDR ,
FLASH_COMPANY_NAME_ADDR ,
FLASH_UPDATE_TIME_ADDR ,
} ;
2024-08-31 10:27:58 +08:00
2024-09-04 12:29:34 +08:00
rt_ubase_t level = 0 ;
2024-08-31 10:27:58 +08:00
static void BSP_Flash_UnLock ( void )
{
std_flash_unlock ( ) ;
}
static void BSP_Flash_Lock ( void )
{
std_flash_lock ( ) ;
2024-09-04 09:01:05 +08:00
// rt_hw_interrupt_enable(interrupt_value);
}
static void Flash_Interrupt_Disable ( void )
{
2024-09-04 12:29:34 +08:00
level = rt_hw_interrupt_disable ( ) ;
2024-09-04 09:01:05 +08:00
}
2024-08-31 10:27:58 +08:00
2024-09-04 09:01:05 +08:00
static void Flash_Interrupt_Enable ( void )
{
2024-09-04 12:29:34 +08:00
rt_hw_interrupt_enable ( level ) ;
2024-08-31 10:27:58 +08:00
}
2024-08-31 14:50:41 +08:00
// 计算校验和的函数
uint8_t Sum_Check ( TuFlashHrRecordFrame frame )
2024-08-31 10:27:58 +08:00
{
2024-08-31 14:50:41 +08:00
return ( frame . time . year + frame . time . month + frame . time . day + frame . time . hour + frame . time . minute ) & CHECKSUM_MASK ;
2024-08-31 10:27:58 +08:00
}
2024-09-02 15:12:26 +08:00
#if 0
2024-08-31 10:27:58 +08:00
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 ;
}
2024-09-02 15:12:26 +08:00
# endif
static size_t Flash_ReadWord ( uint32_t addr , uint32_t * buf , size_t len )
{
size_t read_len = 0 ;
if ( ( addr & 0x03 ) ! = 0 ) // 地址4字节对齐
{
RTT_LOG_E ( " addr %#X is not aligned \r \n " , addr ) ;
return ERROR ;
}
2024-09-04 12:29:34 +08:00
for ( size_t i = 0 ; i < len ; i + + , read_len + + )
2024-09-02 15:12:26 +08:00
{
2024-09-04 13:03:51 +08:00
buf [ i ] = ( ( uint32_t * ) addr ) [ i ] ; //
2024-09-04 12:29:34 +08:00
if ( buf [ i ] ! = ( ( uint32_t * ) addr ) [ i ] )
{
RTT_LOG_E ( " Flash_Read Data Mismatch at addr %#X, expected %d got %d " , addr , * ( uint32_t * ) buf , * ( uint32_t * ) addr ) ;
return ERROR ;
}
2024-09-02 15:12:26 +08:00
}
return read_len ;
}
2024-08-31 10:27:58 +08:00
/**
* @ 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 )
{
2024-09-02 15:12:26 +08:00
if ( ( addr & 0x03 ) ! = 0 ) // 地址4字节对齐
2024-08-31 10:27:58 +08:00
{
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 )
{
2024-09-04 09:01:05 +08:00
/* 进入编程模式 */
2024-09-04 12:29:34 +08:00
// std_flash_program_enable();
2024-09-04 09:01:05 +08:00
Flash_Interrupt_Disable ( ) ;
2024-08-31 10:27:58 +08:00
if ( std_flash_word_program ( addr , write_data ) ! = SUCCESS ) // 写入操作 字节写入
{
2024-09-04 09:01:05 +08:00
Flash_Interrupt_Enable ( ) ;
2024-08-31 10:27:58 +08:00
LOG_D ( " addr = %#X, read %d " , addr , * ( uint32_t * ) addr ) ;
2024-09-04 09:01:05 +08:00
2024-09-04 12:29:34 +08:00
// std_flash_program_disable();
2024-08-31 10:27:58 +08:00
BSP_Flash_Lock ( ) ;
return ERROR ;
}
2024-09-04 09:01:05 +08:00
Flash_Interrupt_Enable ( ) ;
2024-09-04 12:29:34 +08:00
// std_flash_program_disable();
2024-09-04 09:01:05 +08:00
BSP_Flash_Lock ( ) ;
2024-08-31 10:27:58 +08:00
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 ) ;
2024-09-04 09:01:05 +08:00
/* 退出编程模式 */
2024-08-31 10:27:58 +08:00
return ERROR ;
}
2024-08-31 14:50:41 +08:00
rt_thread_mdelay ( 2 ) ;
2024-08-31 10:27:58 +08:00
}
return SUCCESS ;
}
2024-09-04 09:01:05 +08:00
#if 0
# if defined(__CC_ARM)
# pragma arm section code = "FAST_PROGRAM"
# elif defined(__ICCARM__)
__ramfunc
# elif defined(__GNUC__)
__attribute__ ( ( section ( " .RamFunc " ) ) )
# endif
/**
* @ brief Flash快速编程 , 往 目 标 地 址 快 速 编 程 半 页 数 据
* @ param address 编 程 地 址
* @ param data_buf 编 程 数 据
* @ retval std_status_t 本 函 数 执 行 结 果
*/
std_status_t BSP_Flash_Fast_Write ( uint32_t address , uint32_t * data_buf )
{
std_status_t status = STD_OK ;
uint32_t prog_count = 0 ;
/* 启动快速编程模式 */
std_flash_fast_program_enable ( ) ;
/* 向目标地址写入数据 */
for ( prog_count = 0 ; prog_count < FSTPG_WORD_COUNT ; prog_count + + )
{
( ( uint32_t * ) address ) [ prog_count ] = data_buf [ prog_count ] ;
/* 查询等待BSY标志被清除 */
while ( ( FLASH - > SR & FLASH_FLAG_BSY ) = = FLASH_FLAG_BSY ) ;
/* 若出现错误,则退出编程循环 */
if ( FLASH - > SR & FLASH_FLAG_ALL_ERR )
{
RTT_LOG_E ( " FLASH_SR = %#X " , FLASH - > SR ) ;
RTT_LOG_E ( " Flash_Write Error at addr %#X, expected %X got %X " , address , data_buf [ prog_count ] , ( ( uint32_t * ) address ) [ prog_count ] ) ;
status = STD_ERR ;
break ;
}
}
/* 查询等待FSTPG_MODE状态被自动清零 */
while ( ( FLASH - > CR & FLASH_CR_FSTPG_MODE ) = = FLASH_CR_FSTPG_MODE ) ;
/* 清除Flash标志 */
FLASH - > SR = ( FLASH_FLAG_ALL_ERR | FLASH_SR_EOP ) ;
return ( status ) ;
}
# if defined(__CC_ARM)
# pragma arm section
# endif
/**
* @ brief Flash快速编程流程
* @ param address 编 程 地 址
* @ param data_buf 编 程 数 据
* @ retval std_status_t 本 函 数 执 行 结 果
*/
ErrorStatus BSP_Flash_Fast_Program ( uint32_t address , uint32_t * data_buf )
{
std_status_t status = STD_OK ;
uint32_t prog_count ;
/* 检查Flash上一次操作忙状态、错误状态 */
// status = std_flash_wait_for_last_operation(FLASH_WAIT_PROGRAM);
// if(status == STD_OK)
// {
/* 进入编程模式 */
std_flash_program_enable ( ) ;
/* 短时间屏蔽中断 */
Flash_Interrupt_Disable ( ) ;
/* 执行快速编程 */
if ( BSP_Flash_Fast_Write ( address , data_buf ) ! = STD_OK )
{
status = STD_ERR ;
RTT_LOG_E ( " Flash_Fast_Write status ERROR %d " , status ) ;
}
/* 恢复中断 */
Flash_Interrupt_Enable ( ) ;
/* 退出编程模式 */
std_flash_program_disable ( ) ;
rt_thread_mdelay ( 2 ) ;
/* 快速编程中无法对Flash执行读操作, 需在编程结束后统一校验数据 */
if ( status = = STD_OK )
{
for ( prog_count = 0 ; prog_count < FSTPG_WORD_COUNT ; prog_count + + )
{
if ( ( ( __IO uint32_t * ) address ) [ prog_count ] ! = data_buf [ prog_count ] )
{
RTT_LOG_E ( " Flash_Fast_Write Data Mismatch at addr %#X, expected %d got %d " , address + prog_count * 4 , data_buf [ prog_count ] , ( ( __IO uint32_t * ) address ) [ prog_count ] ) ;
status = STD_ERR ;
break ;
}
else
{
RTT_LOG_D ( " Flash_Fast_Write Data Match at addr %#X, expected %d got %d " , address + prog_count * 4 , data_buf [ prog_count ] , ( ( __IO uint32_t * ) address ) [ prog_count ] ) ;
}
}
}
// }
return ( status ) ;
}
ErrorStatus BSP_Flash_Program_Page ( uint32_t address , uint32_t * data_buf )
{
std_status_t status ;
/* 清除错误标志 */
std_flash_clear_flag ( FLASH_FLAG_ALL_ERR ) ;
/* Flash控制寄存器解锁 */
BSP_Flash_UnLock ( ) ;
if ( std_flash_get_lock_status ( ) = = false )
{
/* 页擦第48页 */
status = std_flash_page_erase ( FLASH_HR_INFO_PAGE ) ;
/* 擦除异常,加入自定义处理代码 */
while ( status ! = STD_OK )
{
RTT_LOG_E ( " Flash_Erase Page %d " , FLASH_HR_INFO_PAGE ) ;
return STD_ERR ;
}
/* 快速编程64个字: 前半页 */
status = BSP_Flash_Fast_Program ( address , data_buf ) ;
/* 快速编程异常,加入自定义处理代码 */
while ( status ! = STD_OK )
{
RTT_LOG_E ( " Flash_Fast_Write Page %d " , FLASH_HR_INFO_PAGE ) ;
return STD_ERR ;
}
/* 快速编程64个字: 后半页 */
status = BSP_Flash_Fast_Program ( ( address + ( FSTPG_WORD_COUNT < < 2 ) ) , data_buf ) ;
/* 快速编程异常,加入自定义处理代码 */
while ( status ! = STD_OK )
{
RTT_LOG_E ( " Flash_Fast_Write Page %d " , FLASH_HR_INFO_PAGE ) ;
return STD_ERR ;
}
/* Flash控制寄存器加锁 */
BSP_Flash_Lock ( ) ;
}
return STD_OK ;
}
# endif
#if 0
2024-09-02 15:12:26 +08:00
static std_status_t Flash_WritePage ( uint32_t addr , uint32_t * buf , size_t len )
2024-08-31 10:27:58 +08:00
{
std_status_t status = SUCCESS ;
2024-09-02 15:12:26 +08:00
if ( ( addr & 0x03 ) ! = 0 ) // 地址4字节对齐
2024-08-31 10:27:58 +08:00
{
LOG_E ( " addr %#X is not aligned \r \n " , addr ) ;
return ERROR ;
}
2024-09-02 15:12:26 +08:00
for ( int i = 0 ; i < len ; i + + ) // 页写入的WORD数
2024-08-31 10:27:58 +08:00
{
2024-09-04 09:01:05 +08:00
status = Flash_WriteWord ( ( addr + i * sizeof ( uint32_t ) ) , * ( buf + i * sizeof ( uint32_t ) ) ) ; // 注意: 地址增加应按uint32_t大小增加
2024-08-31 10:27:58 +08:00
if ( status ! = SUCCESS )
{
return status ; // 返回错误状态
}
}
return status ; // 如果所有写入成功, 返回SUCCESS
}
2024-09-04 09:01:05 +08:00
# endif
2024-08-31 10:27:58 +08:00
2024-09-04 12:29:34 +08:00
std_status_t Flash_ErasePage ( uint32_t index )
{
std_flash_unlock ( ) ;
RTT_LOG_D ( " ErasePage %d " , index ) ;
2024-09-04 13:03:51 +08:00
Flash_Interrupt_Disable ( ) ;
2024-09-04 12:29:34 +08:00
std_status_t status = std_flash_erase ( FLASH_ERASE_PAGE , index ) ;
2024-09-04 13:03:51 +08:00
Flash_Interrupt_Enable ( ) ;
2024-09-04 12:29:34 +08:00
std_flash_lock ( ) ;
return status ;
}
2024-08-31 10:27:58 +08:00
/**
* @ description : 擦 除 产 品 信 息 页
* @ return { * }
*/
void Flash_ErasePage_ConfigInfo ( void )
{
2024-09-04 12:29:34 +08:00
if ( Flash_ErasePage ( FLASH_HR_INFO_PAGE ) ! = SUCCESS )
2024-08-31 10:27:58 +08:00
{
2024-09-04 09:01:05 +08:00
RTT_LOG_E ( " error_page = %#x \r \n " ) ;
2024-08-31 10:27:58 +08:00
}
2024-09-04 09:01:05 +08:00
}
ErrorStatus BSP_Flash_Program_InfoPage ( uint32_t address , uint32_t * data_buf )
{
ErrorStatus ret = ERROR ;
for ( uint32_t i = 0 ; i < FLASH_PAGE_RECORD_WORD_NUM ; i + + )
{
ret = Flash_WriteWord ( address + i * 4 , data_buf [ i ] ) ;
if ( ret ! = SUCCESS )
{
LOG_E ( " BSP_Flash_Program_InfoPage failed " ) ;
return ERROR ;
}
}
return ret ;
2024-08-31 10:27:58 +08:00
}
/**
* @ description : 写 产 品 信 息 页 ( 最 后 一 页 )
* @ param { uint8_t * } frame
* @ return { * }
*/
2024-09-04 09:01:05 +08:00
ErrorStatus Flash_Write_ConfigInfo ( uint32_t * buf )
2024-08-31 10:27:58 +08:00
{
2024-09-04 09:01:05 +08:00
return BSP_Flash_Program_InfoPage ( FLASH_CONFIG_INFO_START_ADDR , buf ) ;
2024-08-31 10:27:58 +08:00
}
/*获取当前页号*/
uint32_t Flash_Get_Current_Page ( uint32_t addr )
{
return ( addr - FLASH_START_ADDR ) / FLASH_PAGE_BYTE_SIZE ;
}
/**
* @ description : 擦 除 历 史 记 录 区 的 页
2024-09-02 15:12:26 +08:00
* @ param { TeRecord } addr 需 要 擦 除 的 页 相 对 于 其 项 目 起 始 页 的 偏 移 量
2024-08-31 10:27:58 +08:00
* @ return { * }
*/
2024-09-04 09:01:05 +08:00
ErrorStatus Flash_ErasePage_Records ( TeRecord record , uint8_t page_offset )
2024-08-31 10:27:58 +08:00
{
ErrorStatus flag = SUCCESS ;
2024-09-02 15:12:26 +08:00
uint8_t erase_page = Flash_Get_Current_Page ( hr_start_addr [ record ] + page_offset * FLASH_PAGE_BYTE_SIZE ) ;
2024-08-31 10:27:58 +08:00
2024-09-02 15:12:26 +08:00
if ( erase_page ! = hr_record_start_page_num [ record ] + page_offset )
2024-08-31 10:27:58 +08:00
{
2024-09-02 15:12:26 +08:00
RTT_LOG_E ( " Flash_ErasePage_Records failed erase_page: %#X != %#X " ,
erase_page , hr_record_start_page_num [ record ] + page_offset ) ;
return ERROR ;
2024-08-31 10:27:58 +08:00
}
2024-09-02 15:12:26 +08:00
if ( Flash_ErasePage ( erase_page ) ! = SUCCESS )
2024-08-31 10:27:58 +08:00
{
2024-09-02 15:12:26 +08:00
RTT_LOG_E ( " Flash_ErasePage failed \r \n " ) ;
2024-08-31 10:27:58 +08:00
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 )
{
2024-09-02 15:12:26 +08:00
RTT_LOG_E ( " Flash_ErasePage failed \r \n " ) ;
return ERROR ;
2024-08-31 10:27:58 +08:00
}
}
return flag ;
}
/**
* @ description : 擦 除 数 据 记 录 区
* @ return { * }
*/
2024-09-02 15:12:26 +08:00
ErrorStatus BSP_Flash_EraseRecodrs ( void )
2024-08-31 10:27:58 +08:00
{
2024-09-04 09:01:05 +08:00
2024-08-31 10:27:58 +08:00
/*擦除所有的历史记录区*/
for ( TeRecord record = kRecordAlarm ; record < kRecordSensorFailure ; record + + )
{
for ( uint8_t i = 0 ; i < hr_record_pages [ record ] ; i + + )
{
2024-09-04 09:01:05 +08:00
if ( Flash_ErasePage ( hr_record_start_page_num [ record ] + i ) ! = SUCCESS )
2024-09-02 15:12:26 +08:00
{
RTT_LOG_E ( " Flash_ErasePage_Records failed \r \n " ) ;
return ERROR ;
}
2024-08-31 10:27:58 +08:00
}
}
2024-09-02 15:12:26 +08:00
return SUCCESS ;
2024-08-31 10:27:58 +08:00
}
/**
* @ description : 先 读 再 擦 , 以 确 保 原 有 数 据 不 会 被 擦 除
* @ param { uint8_t } * page_buf
* @ return { * }
*/
2024-09-02 15:12:26 +08:00
void Flash_ErasePage_ReadConfigInfo ( uint32_t * page_buf )
2024-08-31 10:27:58 +08:00
{
2024-09-02 15:12:26 +08:00
Flash_ReadWord ( FLASH_CONFIG_INFO_START_ADDR , page_buf , FLASH_PAGE_RECORD_WORD_NUM ) ;
2024-08-31 10:27:58 +08:00
Flash_ErasePage_ConfigInfo ( ) ;
}
2024-08-31 14:50:41 +08:00
# if 1
2024-08-31 10:27:58 +08:00
/**
* @ description : 获 取 产 品 的 出 厂 或 到 期 时 间
* @ return { * }
*/
2024-08-31 14:50:41 +08:00
ErrorStatus Flash_GetProductTimeLimit ( TuFlashHrRecordFrame * pLimitTime , TeFlashProductTimeLimitId id )
2024-08-31 10:27:58 +08:00
{
if ( id = = kFactoryTimeId )
{
2024-09-02 15:12:26 +08:00
pLimitTime - > hr_data = * ( uint32_t * ) FLASH_FACTORY_TIME_ADDR ;
2024-08-31 14:50:41 +08:00
2024-09-02 15:12:26 +08:00
if ( pLimitTime - > hr_data = = FLASH_DEFAULT_VALUE )
{
RTT_LOG_E ( " FactoryTime is not set \r \n " ) ;
return ERROR ;
}
if ( pLimitTime - > time . check_sum ! = Sum_Check ( * pLimitTime ) )
{
RTT_LOG_E ( " FactoryTime check_sum error \r \n " ) ;
return ERROR ;
}
RTT_LOG_D ( " Flash_Read_FactoryTime:%04d-%02d-%02d,%02d:%02d " ,
BASE_YEAR + pLimitTime - > time . year , pLimitTime - > time . month , pLimitTime - > time . day ,
pLimitTime - > time . hour , pLimitTime - > time . minute ) ;
return SUCCESS ;
2024-08-31 10:27:58 +08:00
}
else if ( id = = kExpirationTimeId )
{
2024-09-02 15:12:26 +08:00
pLimitTime - > hr_data = * ( uint32_t * ) FLASH_EXPIRATION_TIME_ADDR ;
if ( pLimitTime - > hr_data = = FLASH_DEFAULT_VALUE )
{
RTT_LOG_E ( " ExpirationTime is not set \r \n " ) ;
return ERROR ;
}
if ( pLimitTime - > time . check_sum ! = Sum_Check ( * pLimitTime ) )
{
RTT_LOG_E ( " ExpirationTime check_sum error \r \n " ) ;
return ERROR ;
}
RTT_LOG_D ( " Flash_Read_ExpirationTime:%04d-%02d-%02d,%02d:%02d " ,
BASE_YEAR + pLimitTime - > time . year , pLimitTime - > time . month , pLimitTime - > time . day ,
pLimitTime - > time . hour , pLimitTime - > time . minute ) ;
return SUCCESS ;
2024-08-31 10:27:58 +08:00
}
2024-09-02 15:12:26 +08:00
return ERROR ;
2024-08-31 10:27:58 +08:00
}
/**
* @ description : 设 置 产 品 的 出 厂 或 到 期 时 间
* @ param { uint16_t } year
* @ param { uint8_t } mon
* @ param { uint8_t } day
* @ param { uint8_t } hour
* @ param { uint8_t } min
* @ param { TeFlashProductTimeLimitId } id
* @ return { * }
*/
2024-09-02 15:12:26 +08:00
void Flash_SetProductTimeLimit ( uint16_t year , uint8_t mon , uint8_t day , uint8_t hour , uint8_t min , TeFlashProductTimeLimitId id )
2024-08-31 10:27:58 +08:00
{
2024-09-02 15:12:26 +08:00
TuFlashHrRecordFrame LimitTime ;
TuFlashHrRecordFrame ReadLimitTime ;
uint32_t page_buf [ FLASH_PAGE_RECORD_WORD_NUM ] = { 0 } ; // 暂存最后一页的值
2024-08-31 10:27:58 +08:00
Flash_ErasePage_ReadConfigInfo ( page_buf ) ;
2024-09-04 09:01:05 +08:00
2024-09-04 13:03:51 +08:00
// page_buf[kFlashInitFlag] = FLASH_FIRST_INIT_VALUE;
2024-09-02 15:12:26 +08:00
LimitTime . time . year = year - BASE_YEAR ;
LimitTime . time . month = mon ;
LimitTime . time . day = day ;
LimitTime . time . hour = hour ;
LimitTime . time . minute = min ;
LimitTime . time . check_sum = Sum_Check ( LimitTime ) ;
2024-08-31 10:27:58 +08:00
if ( id = = kFactoryTimeId )
{
2024-09-02 15:12:26 +08:00
page_buf [ kFlashFactoryTime ] = LimitTime . hr_data ;
2024-08-31 10:27:58 +08:00
}
else if ( id = = kExpirationTimeId )
{
2024-09-02 15:12:26 +08:00
page_buf [ kFlashExpirationTime ] = LimitTime . hr_data ;
2024-08-31 10:27:58 +08:00
}
2024-09-04 12:29:34 +08:00
// RTT_LOG_D("Flash_SetProductTimeLimit((%d)):%04d-%02d-%02d,%02d:%02d ", id, year, mon, day, hour, min);
2024-09-04 09:01:05 +08:00
Flash_Write_ConfigInfo ( & page_buf [ 0 ] ) ;
2024-08-31 10:27:58 +08:00
Flash_GetProductTimeLimit ( & ReadLimitTime , id ) ;
}
2024-09-04 12:29:34 +08:00
2024-08-31 10:27:58 +08:00
# endif
2024-09-04 13:03:51 +08:00
uint32_t ProductTimeLimit ( uint16_t year , uint8_t mon , uint8_t day , uint8_t hour , uint8_t min )
{
TuFlashHrRecordFrame LimitTime ;
LimitTime . time . year = year - BASE_YEAR ;
LimitTime . time . month = mon ;
LimitTime . time . day = day ;
LimitTime . time . hour = hour ;
LimitTime . time . minute = min ;
LimitTime . time . check_sum = Sum_Check ( LimitTime ) ;
return ( uint32_t ) LimitTime . hr_data ;
}
2024-08-31 10:27:58 +08:00
/**
* @ description : 产 品 信 息 初 始 化 ,
* @ return { * }
*/
2024-09-04 09:01:05 +08:00
int BSP_Flash_Init ( void )
2024-08-31 10:27:58 +08:00
{
2024-09-04 09:01:05 +08:00
2024-08-31 10:27:58 +08:00
if ( * ( uint32_t * ) FLASH_CONFIG_INFO_START_ADDR ! = FLASH_FIRST_INIT_VALUE )
{
2024-09-04 12:29:34 +08:00
uint32_t info_page_buf [ FLASH_PAGE_RECORD_WORD_NUM ] = { 0 } ;
2024-09-02 15:12:26 +08:00
// TODO: 此处需要完善,比如写入初始化标志位,写入产品信息,写入出厂时间,写入到期时间
2024-09-04 09:01:05 +08:00
2024-09-04 13:03:51 +08:00
info_page_buf [ kFlashInitFlag ] = FLASH_FIRST_INIT_VALUE ;
2024-09-18 14:03:55 +08:00
info_page_buf [ kFlashFactoryTime ] = ProductTimeLimit ( 2024 , 1 , 2 , 3 , 4 ) ;
info_page_buf [ kFlashExpirationTime ] = ProductTimeLimit ( 2024 + 10 , 1 , 2 , 3 , 4 ) ;
info_page_buf [ kFlashLowAlarmValue ] = 0x0A ; // 10%LEL
info_page_buf [ kFlashHighAlarmValue ] = 0x32 ; // 50%LEL
2024-09-04 13:03:51 +08:00
// info_page_buf[kFlashSoftwareVersion] = XXX;
// info_page_buf[kFlashHardwareVersion] = XXX;
// info_page_buf[kFlashCompanyName] = XXX;
// info_page_buf[kFlashUpdateTime] = XXX;
BSP_Flash_EraseRecodrs ( ) ; // 擦除历史数据区
Flash_ErasePage_ConfigInfo ( ) ; // 擦除配置信息
if ( Flash_Write_ConfigInfo ( info_page_buf ) ! = STD_OK )
{
2024-09-05 10:01:45 +08:00
RTT_LOG_E ( " Flash_Write_ConfigInfo failed " ) ;
2024-09-04 13:03:51 +08:00
return RT_ERROR ;
}
}
2024-09-04 09:01:05 +08:00
return RT_EOK ;
2024-08-31 10:27:58 +08:00
}
2024-09-04 13:03:51 +08:00
INIT_ENV_EXPORT ( BSP_Flash_Init ) ;
2024-08-31 10:27:58 +08:00
2024-08-31 14:50:41 +08:00
# if 1
2024-08-31 10:27:58 +08:00
/**
2024-09-02 15:12:26 +08:00
* @ description : 获 取 索 引 信 息
2024-08-31 10:27:58 +08:00
* @ param { TeRecord } record
* @ return { * }
*/
TsRecordIndex Flash_GetIndex_Pos ( TeRecord record )
{
2024-08-31 14:50:41 +08:00
uint32_t index_addr = RT_NULL ;
2024-08-31 10:27:58 +08:00
TsRecordIndex Index_Frame = { 0 } ;
2024-09-02 15:12:26 +08:00
uint32_t start_addr_default = hr_start_addr [ record ] ;
uint32_t hr_record_pages_default = hr_record_pages [ record ] ;
for ( uint8_t page = 1 ; page < = hr_record_pages_default ; page + + ) // 遍历对应项的历史数据扇区
2024-08-31 10:27:58 +08:00
{
for ( uint8_t i = 0 ; i < FLASH_HR_PAGE_RECORD_NUM ; i + + ) // 获取扇区偏移量
{
2024-09-02 15:12:26 +08:00
index_addr = ( start_addr_default + FLASH_PAGE_BYTE_SIZE * ( page - 1 ) + HR_RECORD_FRAME_LEN * i ) ;
2024-08-31 14:50:41 +08:00
if ( * ( uint32_t * ) index_addr = = FLASH_DEFAULT_VALUE )
2024-08-31 10:27:58 +08:00
{
/*获取最新的数据所在位置, 如果值为0xFFFFFFFF, 则表示该页有空位, 是最新的页*/
2024-09-02 15:12:26 +08:00
if ( page < hr_record_pages_default ) // 当前页不是最后一页
2024-08-31 10:27:58 +08:00
{
2024-08-31 14:50:41 +08:00
if ( * ( uint32_t * ) ( index_addr + FLASH_PAGE_BYTE_SIZE ) = = FLASH_DEFAULT_VALUE )
2024-08-31 10:27:58 +08:00
{
/* 没进行循环写入*/
2024-09-02 15:12:26 +08:00
Index_Frame . hr_start_addr = start_addr_default ;
2024-08-31 14:50:41 +08:00
Index_Frame . hr_index_addr = index_addr ;
2024-09-02 15:12:26 +08:00
Index_Frame . hr_num = ( index_addr - start_addr_default ) / HR_RECORD_FRAME_LEN ;
2024-08-31 10:27:58 +08:00
Index_Frame . hr_page = page ;
return Index_Frame ;
}
else // 已经开始循环了
{
2024-08-31 14:50:41 +08:00
Index_Frame . hr_start_addr = ( index_addr + FLASH_PAGE_BYTE_SIZE ) ;
Index_Frame . hr_index_addr = index_addr ;
2024-08-31 10:27:58 +08:00
Index_Frame . hr_num = hr_record_max_num [ record ] ;
Index_Frame . hr_page = page ;
return Index_Frame ;
}
}
else // 当前页是最后一页,那么首地址应该在第一页,其偏移量是最后一页的偏移量
{
2024-09-02 15:12:26 +08:00
Index_Frame . hr_start_addr = ( start_addr_default + HR_RECORD_FRAME_LEN * i ) ;
2024-08-31 14:50:41 +08:00
Index_Frame . hr_index_addr = index_addr ;
2024-08-31 10:27:58 +08:00
Index_Frame . hr_num = hr_record_max_num [ record ] ;
Index_Frame . hr_page = page ;
2024-08-31 14:50:41 +08:00
if ( page = = 1 ) // 只有一条数据,则索引地址应该在第一页
2024-08-31 10:27:58 +08:00
{
2024-09-02 15:12:26 +08:00
Index_Frame . hr_start_addr = start_addr_default ;
2024-08-31 14:50:41 +08:00
Index_Frame . hr_index_addr = Index_Frame . hr_start_addr ;
2024-09-02 16:09:03 +08:00
if ( * ( uint32_t * ) ( start_addr_default ) = = FLASH_DEFAULT_VALUE )
{
2024-09-04 09:01:05 +08:00
Index_Frame . hr_num = 0 ;
}
2024-08-31 10:27:58 +08:00
}
2024-08-31 14:50:41 +08:00
2024-08-31 10:27:58 +08:00
return Index_Frame ;
}
}
}
}
RTT_LOG_E ( " Flash_GetIndex_Pos Error! " ) ;
return Index_Frame ;
}
2024-08-31 14:50:41 +08:00
# endif
2024-08-31 10:27:58 +08:00
/**
* @ description :
* @ param { TuFlashHrRecordFrame } * pHrRecord
* @ param { TeRecord } record
* @ param { uint8_t } index
* @ return { * }
*/
ErrorStatus Flash_Read_Record ( TuFlashHrRecordFrame * pHrRecord , TeRecord record , size_t index )
{
2024-08-31 14:50:41 +08:00
uint32_t index_addr = 0 ;
TuFlashHrRecordFrame RecoderFrame = { 0 } ;
TsRecordIndex Index_Frame = Flash_GetIndex_Pos ( record ) ; // 已存储的数量
2024-08-31 10:27:58 +08:00
2024-09-02 15:12:26 +08:00
uint32_t start_addr_default = hr_start_addr [ record ] ;
uint32_t hr_record_pages_default = hr_record_pages [ record ] ;
uint8_t sum_check = 0 ;
2024-09-19 17:13:58 +08:00
if ( ( index < = hr_record_max_num [ record ] ) & & ( index > 0 ) )
2024-08-31 10:27:58 +08:00
{
2024-09-04 09:01:05 +08:00
if ( index < = Index_Frame . hr_num )
2024-08-31 10:27:58 +08:00
{
{
2024-09-02 15:12:26 +08:00
if ( Index_Frame . hr_start_addr = = start_addr_default ) // 是默认的起始地址,则读取数据就是对应的偏移量
2024-08-31 10:27:58 +08:00
{
2024-09-02 15:12:26 +08:00
index_addr = start_addr_default + ( index - 1 ) * HR_RECORD_FRAME_LEN ;
2024-08-31 10:27:58 +08:00
}
else
{
if ( ( Index_Frame . hr_start_addr + index * HR_RECORD_FRAME_LEN ) < =
2024-09-02 15:12:26 +08:00
hr_record_pages_default * FLASH_PAGE_BYTE_SIZE + start_addr_default ) // 没超过所在项目的页最大地址,正常读取,此时应该在缓存页
2024-08-31 10:27:58 +08:00
{
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 ;
}
2024-09-19 15:04:25 +08:00
else // 超过了所在项目的最大地址,此时应该循环了
2024-08-31 10:27:58 +08:00
{
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 ) ;
}
}
}
{
2024-08-31 14:50:41 +08:00
RecoderFrame . hr_data = ( * ( uint32_t * ) index_addr ) ;
2024-09-02 15:12:26 +08:00
sum_check = Sum_Check ( RecoderFrame ) ;
2024-08-31 10:27:58 +08:00
2024-09-02 16:09:03 +08:00
if ( RecoderFrame . time . check_sum = = sum_check )
2024-08-31 10:27:58 +08:00
{
2024-09-04 13:03:51 +08:00
pHrRecord - > hr_data = RecoderFrame . hr_data ; // 赋值后读出,看对不对
2024-08-31 14:50:41 +08:00
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 ) ;
2024-08-31 10:27:58 +08:00
2024-08-31 14:50:41 +08:00
RTT_LOG_D ( " read :hr_start_addr = %#x, index_addr: %#x, hr_num: %d, hr_page:%d, read_data : %#X \r \n " ,
2024-09-04 12:29:34 +08:00
Index_Frame . hr_start_addr , index_addr , Index_Frame . hr_num , Index_Frame . hr_page , pHrRecord - > hr_data ) ;
2024-09-04 13:03:51 +08:00
2024-08-31 10:27:58 +08:00
return SUCCESS ;
}
else
{
2024-08-31 14:50:41 +08:00
RTT_LOG_E ( " read :hr_start_addr = %#x, 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 , RecoderFrame . hr_data ) ;
2024-08-31 10:27:58 +08:00
RTT_LOG_E ( " Flash_GetMaxNum((%d)_Records(%d) Sum_Check(%#X) != check_sum(%#X),index_addr :%#X \r \n " ,
2024-09-02 15:12:26 +08:00
Index_Frame . hr_num , record , sum_check , RecoderFrame . time . check_sum , index_addr ) ;
pHrRecord - > hr_data = 0 ;
2024-08-31 10:27:58 +08:00
return ERROR ;
}
}
}
else
{
2024-09-04 09:01:05 +08:00
RTT_LOG_E ( " index num (%d) > Actual storage num %d " , index , Index_Frame . hr_num ) ;
2024-09-02 15:12:26 +08:00
pHrRecord - > hr_data = 0 ;
2024-08-31 10:27:58 +08:00
return ERROR ;
}
}
else
{
2024-09-02 15:12:26 +08:00
RTT_LOG_E ( " index num (%d) > hr record max num %d && index > 0 " , index , hr_record_max_num [ record ] ) ;
pHrRecord - > hr_data = 0 ;
2024-08-31 10:27:58 +08:00
return ERROR ;
}
}
/**
* @ description : 向 对 应 的 历 史 数 据 存 储 区 写 入 一 次 数 据
* @ param { TeRecord } record
* @ return { * }
*/
ErrorStatus Flash_Write_Record ( TeRecord record )
{
TsRecordIndex Index_Frame ;
2024-09-02 15:12:26 +08:00
TuFlashHrRecordFrame RecoderFrame = { 0 } ;
2024-09-04 09:01:05 +08:00
// uint8_t rtctime[3] = {0}, rtcdate[3] = {0};
2024-08-31 10:27:58 +08:00
2024-08-31 14:50:41 +08:00
if ( record = = kRecordSensorFailure & & * ( uint32_t * ) hr_start_addr [ record ] ! = FLASH_DEFAULT_VALUE ) // 传感器故障记录,且已经写入过数据,则不再写入
2024-08-31 10:27:58 +08:00
{
2024-08-31 14:50:41 +08:00
RecoderFrame . hr_data = * ( uint32_t * ) hr_start_addr [ record ] ;
RTT_LOG_E ( " Flash_Write_(%d)Record(%d) num >= recorded Max num(%d) " , record , Index_Frame . hr_num , hr_record_max_num [ record ] ) ;
Flash_Read_Record ( & RecoderFrame , record , Index_Frame . hr_num ) ; // 读取刚才写入数据
2024-08-31 10:27:58 +08:00
return ERROR ;
}
2024-09-02 15:12:26 +08:00
// __cycleof__("my algorithm")
// {
2024-09-04 09:01:05 +08:00
// BSP_Rtc_Get_Calendar(rtcdate, rtctime);
2024-09-02 15:12:26 +08:00
// }
Index_Frame = Flash_GetIndex_Pos ( record ) ;
2024-08-31 14:50:41 +08:00
/*这里可以使用RTC闹钟, 每分钟更新一次数据, 这样只需要从缓存读取数据就行, 降低了访问的时间*/
2024-09-04 09:01:05 +08:00
RecoderFrame . time . hour = std_rtc_convert_bcd2bin ( rtctime [ 0 ] ) ; // h
RecoderFrame . time . minute = std_rtc_convert_bcd2bin ( rtctime [ 1 ] ) ; // m
2024-09-02 15:12:26 +08:00
2024-09-04 09:01:05 +08:00
RecoderFrame . time . year = ( std_rtc_convert_bcd2bin ( rtcdate [ 0 ] ) - 24 ) ; // y
RecoderFrame . time . month = std_rtc_convert_bcd2bin ( rtcdate [ 1 ] ) ; // m
RecoderFrame . time . day = std_rtc_convert_bcd2bin ( rtcdate [ 2 ] ) ; // d
2024-09-02 16:09:03 +08:00
RecoderFrame . time . check_sum = Sum_Check ( RecoderFrame ) ;
2024-09-02 15:12:26 +08:00
// RTT_LOG_D("sizof TuFlashHrRecordFrame(%d)", sizeof(TuFlashHrRecordFrame));
2024-08-31 10:27:58 +08:00
2024-08-31 14:50:41 +08:00
RTT_LOG_D ( " write:hr_start_addr = %#x, index_addr: %#x, hr_num: %d, hr_page:%d, write_data : %#X " ,
2024-08-31 10:27:58 +08:00
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 ) ;
{
/*写入数据*/
2024-08-31 14:50:41 +08:00
2024-08-31 10:27:58 +08:00
if ( Flash_WriteWord ( Index_Frame . hr_index_addr , RecoderFrame . hr_data ) ! = SUCCESS )
{
RTT_LOG_E ( " hr_write_data_error " ) ;
2024-08-31 14:50:41 +08:00
RTT_LOG_E ( " hr_start_addr = %#x, index_addr: %#x, hr_num: %d, hr_page:%d, write_data : %#X " ,
2024-08-31 10:27:58 +08:00
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 ] )
{
2024-08-31 14:50:41 +08:00
Flash_Read_Record ( & RecoderFrame , record , Index_Frame . hr_num + 1 ) ; // 读取刚才写入数据,此时这个hr_num实际上是会+1的, 当到达最大计数之前, hr_num会+1, 到了以后, 就默认是最大数量条数据, 所以不用加
2024-08-31 10:27:58 +08:00
}
else // 超了最大数后,每次读出来的数据都是最大数
{
Flash_Read_Record ( & RecoderFrame , record , Index_Frame . hr_num ) ; // 读取刚才写入数据
}
}
return SUCCESS ;
}
2024-09-20 11:14:25 +08:00
// 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 (int i = 1; i <= num; i++)
// {
// RTT_LOG_I("Flash_Write_(%d)Record:%d", record, i);
// Flash_Write_Record(record);
// rt_thread_mdelay(200); // 1min
// }
// }
// 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");
2024-08-31 10:27:58 +08:00
/*获取当前项目记录数*/
2024-09-19 17:13:58 +08:00
uint16_t Flash_GetNum_Records ( TeRecord record )
2024-08-31 10:27:58 +08:00
{
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 ;
2024-09-19 17:13:58 +08:00
pTotalRecords - > alarm = Flash_GetNum_Records ( kRecordAlarm ) > = 256 ? 255 : Flash_GetNum_Records ( kRecordAlarm ) ;
pTotalRecords - > alarm_rcy = Flash_GetNum_Records ( kRecordAlarmRcy ) > = 256 ? 255 : Flash_GetNum_Records ( kRecordAlarmRcy ) ;
2024-08-31 10:27:58 +08:00
pTotalRecords - > fault = Flash_GetNum_Records ( kRecordFault ) ;
pTotalRecords - > fault_rcy = Flash_GetNum_Records ( kRecordFaultRcy ) ;
2024-09-18 14:03:55 +08:00
pTotalRecords - > power_down = Flash_GetNum_Records ( kRecordPowerDown ) ;
2024-08-31 10:27:58 +08:00
pTotalRecords - > power_on = Flash_GetNum_Records ( kRecordPowerOn ) ;
pTotalRecords - > sensor_failure = Flash_GetNum_Records ( kRecordSensorFailure ) ;
2024-09-19 14:14:59 +08:00
LOG_I ( " alarm:%d, alarm_rcy:%d, fault:%d, fault_rcy:%d, power_down:%d, power_on:%d, sensor_failure:%d " ,
2024-09-19 17:13:58 +08:00
pTotalRecords - > alarm , pTotalRecords - > alarm_rcy , pTotalRecords - > fault , pTotalRecords - > fault_rcy ,
pTotalRecords - > power_down , pTotalRecords - > power_on , pTotalRecords - > sensor_failure ) ;
2024-09-19 14:14:59 +08:00
2024-08-31 10:27:58 +08:00
flag = SUCCESS ;
return flag ;
}
/**
* @ brief 获 取 记 录 时 间
* @ param record_type
* @ param index
* @ param pRecordsTime
* @ return ErrorStatus
*/
2024-09-19 17:13:58 +08:00
ErrorStatus Flash_GetRecord ( TeFrameC2 record_type , uint16_t index , TsRecordsTime * pRecordsTime )
2024-08-31 10:27:58 +08:00
{
ErrorStatus flag = ERROR ;
uint16_t years = 0 ;
if ( kNumOfRecords < record_type & & record_type < kGetCurrentTime )
{
TuFlashHrRecordFrame pHrReadRecord ;
2024-09-02 15:12:26 +08:00
/*这里存在多种情况,其中最常见的就是没有记录,,所有情况的结果就是此基数年不存在*/
if ( Flash_Read_Record ( & pHrReadRecord , ( TeRecord ) ( record_type - 1 ) , index ) ! = SUCCESS )
{
years = pHrReadRecord . time . year ;
}
else
{
years = BASE_YEAR + pHrReadRecord . time . year ;
}
2024-08-31 10:27:58 +08:00
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 ;
}