diff --git a/LinkSetting_ForUsageFault_00.png b/LinkSetting_ForUsageFault_00.png new file mode 100644 index 0000000..9021e89 Binary files /dev/null and b/LinkSetting_ForUsageFault_00.png differ diff --git a/LinkSetting_ForUsageFault_01.png b/LinkSetting_ForUsageFault_01.png new file mode 100644 index 0000000..84a2638 Binary files /dev/null and b/LinkSetting_ForUsageFault_01.png differ diff --git a/LinkSetting_ForUsageFault_02.png b/LinkSetting_ForUsageFault_02.png new file mode 100644 index 0000000..40257c3 Binary files /dev/null and b/LinkSetting_ForUsageFault_02.png differ diff --git a/README.md b/README.md index 1d46f15..a4ca4d6 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,26 @@ S32K1xx 的 CAN 接 `周立功 USBCANFD-100U-mini`,使用 `ZCANPRO` 软件的 ![Pic_ZCANPRO_ECU_Refresh_Note_ProgramSession][Pic_ZCANPRO_ECU_Refresh_Note_ProgramSession] ![Pic_ZCANPRO_ECU_Refresh_Note_ResetECU][Pic_ZCANPRO_ECU_Refresh_Note_ResetECU] +--- + +### :warning: 特别注意 + +< :ok_hand: 已解决 > 关于 `S32K144 APP 工程` 调用 `Flash_EraseFlashDriverInRAM()` 会导致程序卡死的问题进行说明记录: + +- 根据 Ozone 调试得知,实际现象为出现 `HardFault` , `HFSR` 寄存器 `FORCED` 位被置 1,所以可以判断由其它 Fault 异常提升而来,实际为 `UsageFault` , `INVSTATE` 位被置 1,如下图所示: + - ![LinkSetting_ForUsageFault_00][LinkSetting_ForUsageFault_00] +- 由于程序卡死的位置并不是每次都在同一位置,故初期的排查非常困难。由于同样的代码,在 `S32K118 APP 工程` 中被调用时,并不会产生该问题,所以需要从两个不同芯片的工程的不同之处寻找原因。经过比对,初步判断与两芯片的链接文件空间分配有关联,具体为两个芯片的 `Flash Driver` 所占用的 RAM 地址空间不同。其中,在 `S32K144` 的 `Bootloader 工程` 中,`m_flash_driver` 地址空间在 `APP 工程` 中会与 `m_data` 地址空间合并,从 Bootloader 跳转至 APP 时,会先调用 `Reset_Handler` 汇编函数,此汇编函数会进行相关初始化之后再跳转到 `main` 函数,其中在初始化时,会调用 `init_data_bss()` 函数,此函数其中的一个工作就是将位于 ROM 中(即 `m_interrupts` 地址空间内)的中断向量表拷贝到 RAM 中(即 `m_data` 地址空间内)的起始地址处,此时,如若在 `APP 工程` 中尝试调用 `Flash_EraseFlashDriverInRAM()` ,会对 `0x1FFF8000` 起始地址处连续 `0x800` 个字节的内容进行清零操作,而 `0x1FFF8000` ~ `0x1FFF8800` 地址空间段已经完全属于 `m_data` ,如若再执行 `Flash_EraseFlashDriverInRAM()` 则会将 RAM 中的中断向量表擦除,导致中断响应出现异常,故最终会导致程序卡死,详细配合以下截图进行分析。 + - ![LinkSetting_ForUsageFault_01][LinkSetting_ForUsageFault_01] + - ![LinkSetting_ForUsageFault_02][LinkSetting_ForUsageFault_02] +- 解决方法有两种:APP 工程中一律不调用 `Flash_EraseFlashDriverInRAM()` 或将链接文件内 `m_flash_driver` 的地址空间从 `m_data_2` 地址空间的后半段进行划分。 + - 但经过评估,显然前者为更恰当的解决方法,因为在 APP 工程中,已不存在 `m_flash_driver` 地址空间,此时就算在 Bootloader 中将 `m_data_2` 的后半段空间划分给 `m_flash_driver` ,在 APP 工程中再对该片空间进行自行清零的操作是不妥的,因为 `m_data_2` 会用于存放 `customSectionBlock`、 `bss`、 `heap`、 `stack`, 此时如若再在 APP 中调用 `Flash_EraseFlashDriverInRAM()` ,同样有可能会将这些数据清零。 + [Pic_ZCANPRO_ECU_Refresh]: ./Pic_ZCANPRO_ECU_Refresh.png [Pic_ZCANPRO_ECU_Refresh_Note_ProgramSession]: ./Pic_ZCANPRO_ECU_Refresh_Note_ProgramSession.png [Pic_ZCANPRO_ECU_Refresh_Note_ResetECU]: ./Pic_ZCANPRO_ECU_Refresh_Note_ResetECU.png +[LinkSetting_ForUsageFault_00]: ./LinkSetting_ForUsageFault_00.png +[LinkSetting_ForUsageFault_01]: ./LinkSetting_ForUsageFault_01.png +[LinkSetting_ForUsageFault_02]: ./LinkSetting_ForUsageFault_02.png [UDS_SecurityAccess]: https://github.com/SummerFalls/UDS_SecurityAccess [UDS_S32K144_Bootloader]: https://github.com/SummerFalls/UDS_S32K144_Bootloader diff --git a/UDS_PortingFiles/UDS_alg_hal.c b/UDS_PortingFiles/UDS_alg_hal.c index 60caf96..5f45a1a 100644 --- a/UDS_PortingFiles/UDS_alg_hal.c +++ b/UDS_PortingFiles/UDS_alg_hal.c @@ -69,7 +69,7 @@ boolean UDS_ALG_HAL_DecryptData(const uint8 *i_pCipherText, const uint32 i_dataL deAes((sint8 *)i_pCipherText, i_dataLen, (sint8 *)&gs_aKey[0], (sint8 *)o_pPlainText); #endif #ifdef EN_ZLG_SA_ALGORITHM - /* TODO Bootloader: #02 Simple Security Access Algorithm Decryption function implemented by DTek */ + /* TODO Bootloader: #02 Simple Security Access Algorithm Decryption function */ deZLGKey((sint8 *)i_pCipherText, i_dataLen, (sint8 *)o_pPlainText); #endif return ret; diff --git a/UDS_PortingFiles/flash_hal_Cfg.c b/UDS_PortingFiles/flash_hal_Cfg.c index 398463a..cc789ab 100644 --- a/UDS_PortingFiles/flash_hal_Cfg.c +++ b/UDS_PortingFiles/flash_hal_Cfg.c @@ -321,20 +321,14 @@ boolean FLASH_HAL_GetFlashDriverInfo(uint32 *o_pFlashDriverAddrStart, uint32 *o_ } /* Get reset handler information */ -void FLASH_HAL_GetRestHanlderInfo(boolean *o_pIsEnableWriteResetHandlerInFlash, uint32 *o_pResetHanderOffset, uint32 *o_pResetHandlerLength) +void FLASH_HAL_GetResetHandlerInfo(boolean *o_pIsEnableWriteResetHandlerInFlash, uint32 *o_pResetHandlerOffset, uint32 *o_pResetHandlerLength) { ASSERT(NULL_PTR == o_pIsEnableWriteResetHandlerInFlash); - ASSERT(NULL_PTR == o_pResetHanderOffset); + ASSERT(NULL_PTR == o_pResetHandlerOffset); ASSERT(NULL_PTR == o_pResetHandlerLength); - *o_pIsEnableWriteResetHandlerInFlash = EN_WRITE_RESET_HANDLER_IN_FLASH; - *o_pResetHanderOffset = APP_VECTOR_TABLE_OFFSET + RESET_HANDLER_OFFSET; - *o_pResetHandlerLength = RESET_HANDLER_ADDR_LEN; -} - -/* Get storage reset handler information */ -uint32 FLASH_HAL_GetStorageRestHandlerAddr(void) -{ - return APP_VECTOR_TABLE_OFFSET + RESET_HANDLER_OFFSET; + *o_pIsEnableWriteResetHandlerInFlash = FLASH_HAL_IsEnableStorageResetHandlerInFlash(); + *o_pResetHandlerOffset = FLASH_HAL_GetStorageRestHandlerAddr(); + *o_pResetHandlerLength = FLASH_HAL_GetResetHandlerLen(); } /* Is enable write reset handler in flash? */ @@ -343,6 +337,12 @@ boolean FLASH_HAL_IsEnableStorageResetHandlerInFlash(void) return EN_WRITE_RESET_HANDLER_IN_FLASH; } +/* Get storage reset handler information */ +uint32 FLASH_HAL_GetStorageRestHandlerAddr(void) +{ + return APP_VECTOR_TABLE_OFFSET + RESET_HANDLER_OFFSET; +} + /* Get reset handler addr length */ uint32 FLASH_HAL_GetResetHandlerLen(void) { diff --git a/UDS_PortingFiles/flash_hal_Cfg.h b/UDS_PortingFiles/flash_hal_Cfg.h index 1222deb..fa1fd75 100644 --- a/UDS_PortingFiles/flash_hal_Cfg.h +++ b/UDS_PortingFiles/flash_hal_Cfg.h @@ -41,14 +41,14 @@ uint32 FLASH_HAL_GetFlashLengthToSectors(const uint32 i_startFlashAddr, const ui boolean FLASH_HAL_GetFlashDriverInfo(uint32 *o_pFlashDriverAddrStart, uint32 *o_pFlashDriverEndAddr); /* Get reset handler information */ -void FLASH_HAL_GetRestHanlderInfo(boolean *o_pIsEnableWriteResetHandlerInFlash, uint32 *o_pResetHanderOffset, uint32 *o_pResetHandlerLength); - -/* Get storage reset handler information */ -uint32 FLASH_HAL_GetStorageRestHandlerAddr(void); +void FLASH_HAL_GetResetHandlerInfo(boolean *o_pIsEnableWriteResetHandlerInFlash, uint32 *o_pResetHandlerOffset, uint32 *o_pResetHandlerLength); /* Is enable write reset handler in flash? */ boolean FLASH_HAL_IsEnableStorageResetHandlerInFlash(void); +/* Get storage reset handler information */ +uint32 FLASH_HAL_GetStorageRestHandlerAddr(void); + /* Get reset handler addr length */ uint32 FLASH_HAL_GetResetHandlerLen(void); diff --git a/UDS_PortingFiles/user_config.h b/UDS_PortingFiles/user_config.h index cf1cb61..dc379a5 100644 --- a/UDS_PortingFiles/user_config.h +++ b/UDS_PortingFiles/user_config.h @@ -222,7 +222,7 @@ typedef enum /* -------------------- Jump to APP delay time when have not received UDS message -------------------- */ #define EN_DELAY_TIME -#define DELAY_MAX_TIME_MS (5000u) +#define DELAY_MAX_TIME_MS (2000u) #endif /* USER_CONFIG_H_ */ diff --git a/UDS_ProtocolStack/bootloader_main.c b/UDS_ProtocolStack/bootloader_main.c index b86b347..c77d2a5 100644 --- a/UDS_ProtocolStack/bootloader_main.c +++ b/UDS_ProtocolStack/bootloader_main.c @@ -29,8 +29,12 @@ void UDS_MAIN_Init(void (*pfBSP_Init)(void), void (*pfAbortTxMsg)(void)) Boot_PowerONClearAllFlag(); } +#ifndef EN_DELAY_TIME + Boot_JumpToAppOrNot(); +#endif + #endif if (NULL_PTR != pfBSP_Init) diff --git a/UDS_ProtocolStack/fls_app.c b/UDS_ProtocolStack/fls_app.c index cbcc4c5..26382ae 100644 --- a/UDS_ProtocolStack/fls_app.c +++ b/UDS_ProtocolStack/fls_app.c @@ -256,9 +256,8 @@ void Flash_InitDowloadInfo(void) if (TRUE == IsFlashDriverDownload()) { -#if (defined UDS_PROJECT_FOR_APP) && (MCU_TYPE == MCU_S32K14x) -#else - /* TODO : #00 S32K144 ִбᵼ HardFaultS32K118 ޴⣬ */ +#ifdef UDS_PROJECT_FOR_BOOTLOADER + /* TODO : #00 ļַռ⣬APP вִбᵼ HardFault */ Flash_EraseFlashDriverInRAM(); #endif SetFlashDriverNotDonwload(); @@ -275,9 +274,8 @@ void Flash_InitDowloadInfo(void) void FLASH_APP_Init(void) { gs_stFlashDownloadInfo.isFingerPrintWritten = FALSE; -#if (defined UDS_PROJECT_FOR_APP) && (MCU_TYPE == MCU_S32K14x) -#else - /* TODO : #00 S32K144 ִбᵼ HardFaultS32K118 ޴⣬ */ +#ifdef UDS_PROJECT_FOR_BOOTLOADER + /* TODO : #00 ļַռ⣬APP вִбᵼ HardFault */ Flash_EraseFlashDriverInRAM(); #endif SetFlashDriverNotDonwload(); @@ -1050,9 +1048,9 @@ uint8 Flash_WriteFlashAppInfo(void) uint32 newestAPPInfoLen = 0u; tAppFlashStatus *pstNewestAPPFlashStatus = NULL_PTR; uint32 resetHandleAddr = 0u; - boolean bIsEnableWriteResetHandle = FALSE; - uint32 resetHandleOffset = 0u; - uint32 resetHandleLength = 0u; + boolean bIsEnableWriteResetHandlerInFlash = FALSE; + uint32 resetHandlerOffset = 0u; + uint32 resetHandlerLength = 0u; CreateAndSaveAppStatusCrc(&crc); oldAppType = Flash_GetOldAPPType(); newestAPPType = Flash_GetNewestAPPType(); @@ -1062,7 +1060,7 @@ uint8 Flash_WriteFlashAppInfo(void) { /* Write data information in flash */ pAppStatusPtr = GetAppStatusPtr(); - FLASH_HAL_GetRestHanlderInfo(&bIsEnableWriteResetHandle, &resetHandleOffset, &resetHandleLength); + FLASH_HAL_GetResetHandlerInfo(&bIsEnableWriteResetHandlerInFlash, &resetHandlerOffset, &resetHandlerLength); /* Update APP cnt */ if (TRUE == FLASH_HAL_GetAPPInfo(newestAPPType, &newestAPPInfoStartAddr, &newestAPPInfoLen)) @@ -1076,8 +1074,8 @@ uint8 Flash_WriteFlashAppInfo(void) } /* Get APP start address from flash. The address is the newest APP, because the APP info not write in flash, so the APP is old */ - resetHandleAddr = appInfoStartAddr + resetHandleOffset; - SaveAppResetHandlerAddr(*((uint32 *)resetHandleAddr), resetHandleLength); + resetHandleAddr = appInfoStartAddr + resetHandlerOffset; + SaveAppResetHandlerAddr(*((uint32 *)resetHandleAddr), resetHandlerLength); FLSDebugPrintf("APP type =%X, APP address=0x%X\n", oldAppType, *((uint32 *)resetHandleAddr)); crc = 0u; CreateAndSaveAppStatusCrc(&crc); diff --git a/UDS_ProtocolStack/uds_app.c b/UDS_ProtocolStack/uds_app.c index 171006e..e2b0206 100644 --- a/UDS_ProtocolStack/uds_app.c +++ b/UDS_ProtocolStack/uds_app.c @@ -15,6 +15,11 @@ #include "fls_app.h" #include "uds_alg_hal.h" +#ifdef UDS_PROJECT_FOR_BOOTLOADER +#ifdef EN_DELAY_TIME +extern tJumpAppDelayTimeInfo gs_stJumpAPPDelayTimeInfo; +#endif +#endif void UDS_Init(void) { diff --git a/UDS_ProtocolStack/uds_app_cfg.c b/UDS_ProtocolStack/uds_app_cfg.c index 2db7a05..ad1c963 100644 --- a/UDS_ProtocolStack/uds_app_cfg.c +++ b/UDS_ProtocolStack/uds_app_cfg.c @@ -867,7 +867,7 @@ tUDSService *GetUDSServiceInfo(uint8 *m_pSupServItem) #ifdef UDS_PROJECT_FOR_BOOTLOADER /* If RX UDS msg, set UDS layer received message TURE */ -void SetIsRxUdsMsg(const uint8 i_SetValue) +void SetIsRxUdsMsg(const boolean i_SetValue) { #ifdef EN_DELAY_TIME @@ -883,7 +883,7 @@ void SetIsRxUdsMsg(const uint8 i_SetValue) #endif } -uint8 IsRxUdsMsg(void) +boolean IsRxUdsMsg(void) { #ifdef EN_DELAY_TIME return gs_stJumpAPPDelayTimeInfo.isReceiveUDSMsg; @@ -1357,7 +1357,6 @@ void UDS_SystemTickCtl(void) } else { - /* Max timeout timeout */ Boot_JumpToAppOrNot(); } } diff --git a/UDS_ProtocolStack/uds_app_cfg.h b/UDS_ProtocolStack/uds_app_cfg.h index ae2b565..22b893e 100644 --- a/UDS_ProtocolStack/uds_app_cfg.h +++ b/UDS_ProtocolStack/uds_app_cfg.h @@ -96,8 +96,6 @@ typedef struct boolean isReceiveUDSMsg; uint32 jumpToAPPDelayTime; } tJumpAppDelayTimeInfo; - -extern tJumpAppDelayTimeInfo gs_stJumpAPPDelayTimeInfo; #endif #endif @@ -122,9 +120,9 @@ uint8 IsCurSecurityLevelRequet(uint8 i_SerSecurityLevel); tUDSService *GetUDSServiceInfo(uint8 *m_pSupServItem); #ifdef UDS_PROJECT_FOR_BOOTLOADER -void SetIsRxUdsMsg(const uint8 i_SetValue); +void SetIsRxUdsMsg(const boolean i_SetValue); -uint8 IsRxUdsMsg(void); +boolean IsRxUdsMsg(void); #endif void SetNegativeErroCode(const uint8 i_UDSServiceNum,