程序设计要求:
程序逻辑图:
详细设计过程如下:
1、查看TLE9843-2QX的芯片手册,详细的芯片手册名字为:《Infineon-TLE984xQX-UM-01_00-EN.pdf》。
找到手册关于芯片复位的章节,即Reset Management Unit(RMU)
6.7 复位管理单元(RMU)
RMU控制着整个设备的复位行为。设备复位主要是PMU自己上电复位。复位是电压下降引起的,并且会在电池电压Vs达到激活模式的最小供应电压时退出。然后PMU开始一个序列操作,这个序列操作会让电源支撑模块上电,而这个序列操作会在复位操作完成之后结束。如果上诉状态达到了,则嵌入式系统会工作在激活模式。这个情景会被PMU_1V5DidPOR标志在PMU_RESET_STS寄存器中。
确认ECU的复位信息存储在PMU_RESET_STS寄存器,使用时读取该寄存器。
2、查看芯片手册,查看PMU_RESET_STS寄存器信息
复位状态寄存器
PMU_RESET_STS寄存器显示了每次执行的复位请求。每次复位执行时,PMU写相应的寄存器位。想要清除PMU_RESET_STS寄存器的信息,用户必须将相应位用逻辑零覆盖。PMU_RESET_STS寄存器用RESET_TYPE_1来复位。
PMU_RESET_STS寄存器显示了每次执行的复位请求。PMU使用触发电路的异步输入设置来写相应的寄存器位。想要清除PMU_RESET_STS寄存器的信息,用户必须将相应位用逻辑零覆盖。
注:PMU_RESET_STS.PMU_LPR寄存器被清除时,PMU_RESET_STS寄存器也被清除。
PMU_RESET_STS寄存器位信息:
查看Keil的一个工程中查看Device模块的pmu部分
打开pmu.h文件
/** \brief Reads out the Reset Status register
*
* \param[in] None
* \return or'ed combination of reset status bits
*
* \ingroup pmu_api
*/
__STATIC_INLINE uint32_t PMU_Get_Reset_Status(void)
{
return ((uint32_t) PMU->RESET_STS.reg);
}
/** \brief Clears the Reset Status register
*
* \param[in] None
* \return None
*
* \ingroup pmu_api
*/
__STATIC_INLINE void PMU_Clear_Reset_Status(void)
{
PMU->RESET_STS.reg = (uint32_t) 0;
}
PMU_Get_Reset_Status()函数用来获取PMU_RESET_STS寄存器信息,
PMU_Clear_Reset_Status()函数用来清除PMU_RESET_STS寄存器信息。
/* Typedef Reset Status */
#define PMU_RESET_STS_LOCKUP (0x0400u)
#define PMU_RESET_STS_PMU_SOFT (0x0200u)
#define PMU_RESET_STS_IntWDT (0x0100u)
#define PMU_RESET_STS_POR (0x0080u)
#define PMU_RESET_STS_PIN (0x0040u)
#define PMU_RESET_STS_ExtWDT1 (0x0020u)
#define PMU_RESET_STS_ClkWDT (0x0010u)
#define PMU_RESET_STS_LPR (0x0008u)
#define PMU_RESET_STS_SleepEx (0x0004u)
#define PMU_RESET_STS_WAKE (0x0002u)
#define PMU_RESET_STS_SYS_FAIL (0x0001u)
以及tle984x.h文件中的
/* ======================================================= RESET_STS ======================================================= */
#define PMU_RESET_STS_LOCKUP_Pos (10UL)
/*!< PMU RESET_STS: LOCKUP (Bit 10) */
#define PMU_RESET_STS_LOCKUP_Msk (0x400UL)
/*!< PMU RESET_STS: LOCKUP (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_SOFT_Pos (9UL)
/*!< PMU RESET_STS: PMU_SOFT (Bit 9) */
#define PMU_RESET_STS_PMU_SOFT_Msk (0x200UL)
/*!< PMU RESET_STS: PMU_SOFT (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_VS_POR_Pos (7UL)
/*!< PMU RESET_STS: PMU_VS_POR (Bit 7) */
#define PMU_RESET_STS_PMU_VS_POR_Msk (0x80UL)
/*!< PMU RESET_STS: PMU_VS_POR (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_PIN_Pos (6UL)
/*!< PMU RESET_STS: PMU_PIN (Bit 6) */
#define PMU_RESET_STS_PMU_PIN_Msk (0x40UL)
/*!< PMU RESET_STS: PMU_PIN (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_ExtWDT_Pos (5UL)
/*!< PMU RESET_STS: PMU_ExtWDT (Bit 5) */
#define PMU_RESET_STS_PMU_ExtWDT_Msk (0x20UL)
/*!< PMU RESET_STS: PMU_ExtWDT (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_ClkWDT_Pos (4UL)
/*!< PMU RESET_STS: PMU_ClkWDT (Bit 4) */
#define PMU_RESET_STS_PMU_ClkWDT_Msk (0x10UL)
/*!< PMU RESET_STS: PMU_ClkWDT (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_LPR_Pos (3UL)
/*!< PMU RESET_STS: PMU_LPR (Bit 3) */
#define PMU_RESET_STS_PMU_LPR_Msk (0x8UL)
/*!< PMU RESET_STS: PMU_LPR (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_SleepEX_Pos (2UL)
/*!< PMU RESET_STS: PMU_SleepEX (Bit 2) */
#define PMU_RESET_STS_PMU_SleepEX_Msk (0x4UL)
/*!< PMU RESET_STS: PMU_SleepEX (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_PMU_WAKE_Pos (1UL)
/*!< PMU RESET_STS: PMU_WAKE (Bit 1) */
#define PMU_RESET_STS_PMU_WAKE_Msk (0x2UL)
/*!< PMU RESET_STS: PMU_WAKE (Bitfield-Mask: 0x01) */
#define PMU_RESET_STS_SYS_FAIL_Pos (0UL)
/*!< PMU RESET_STS: SYS_FAIL (Bit 0) */
#define PMU_RESET_STS_SYS_FAIL_Msk (0x1UL)
/*!< PMU RESET_STS: SYS_FAIL (Bitfield-Mask: 0x01) */
定义了PMU_RESET_STS寄存器内部位的信息和位置分布
3、获取PMU_RESET_STS寄存器的值
uwMcuResetStatus = PMU_Get_Reset_Status();
4、判断PMU_RESET_STS寄存器的值是否非零,如果非零,则将值存入Flash,如果是零,表明没有触发复位,则不进行存储。
if(uwMcuResetStatus)
{
……
……
……
……
}
5、在写Flash之前,需要先擦除Flash
在擦除Flash之前,需要先保存上次Flash中的值
for(n= 0; n < 16; n++)
ResetLastdataArray[n] = resetloggerEepAddress[n];
//erase the eep
eepEraseResult = FlashPageErase(INIT_DATA_IN_EEP_ADDRESS);
FlashPageErase函数的定义为:
int32_t FlashPageErase(uint32_t address)
{
int32_t errorLog;
// disable interrupts
__disable_irq();
// service WDT1 short open window
WDT1_SOW_Service(1);
// program NVM page
errorLog = user_nvm_page_erase(address); //9843的固件手册中的擦除Flash函数
// close short open window and reenable window wachdog
WDT1_Service();
// enable interrupts
__enable_irq();
//return
return errorLog;
}
6、擦除完Flash之后,将PMU_RESET_STS寄存器的值写入Flash
需要先判断PMU_RESET_STS寄存器的值与上次Flash中的末尾值是否相等,如果相等,则无需处理,直接将上次Flash中的值再次存入Flash中即可。如果不相等,则将上次Flash中的值先左移,然后再将PMU_RESET_STS寄存器的值替换为上次Flash中的末尾值,然后再将上次Flash中的值再次存入Flash中。
ResetdataArray = (UINT16)((ResetLastdataArray[14] << 8) + ResetLastdataArray[15]);
if(uwMcuResetStatus != ResetdataArray)
{
for(n = 0;n < 13;)
{
ResetLastdataArray[n] = ResetLastdataArray[n + 2];
n += 2;
}
for(n = 1;n < 14;)
{
ResetLastdataArray[n] = ResetLastdataArray[n + 2];
n += 2;
}
ResetLastdataArray[14] = (uwMcuResetStatus & 0xFF00) >> 8;
ResetLastdataArray[15] = uwMcuResetStatus & 0x00FF;
}
options = NVM_PROG_CORR_ACT|NVM_PROG_NO_FAILPAGE_ERASE;
errorLog = FlashSaveData(RESET_LOGGER_EEP_ADDR , ResetLastdataArray, 16,options);
FlashSaveData函数定义:
int32_t FlashSaveData(uint32_t flashAddress, const void *data, uint8_t dataCnt,uint8_t options)
{
int32_t errorLog;
// disable interrupts
__disable_irq();
// service WDT1 short open window
WDT1_SOW_Service(1);
// program NVM page
errorLog = user_nvm_write(flashAddress,data,dataCnt,options); //9843的固件手册中的写Flash函数
// close short open window and reenable window wachdog
WDT1_Service();
// enable interrupts
__enable_irq();
//return
return errorLog;
}
7、在写完Flash数据之后,清除PMU_RESET_STS寄存器的值,以免反复写Flash
PMU_Clear_Reset_Status();
uwMcuResetStatus = PMU_Get_Reset_Status();