跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
折叠
品牌标识

YunTu Forum

YTMicro.com
  1. 主页
  2. Announcements
  3. MCAL Release Notes
  4. MCAL Public Issues
  5. YTM32B1HA0 执行A/B SWAP后Fls Ecc测试失败问题

YTM32B1HA0 执行A/B SWAP后Fls Ecc测试失败问题

已定时 已固定 已锁定 已移动 MCAL Public Issues
2 帖子 2 发布者 37 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • houjun_xiaoH 离线
    houjun_xiaoH 离线
    houjun_xiao YunTu
    编写于 最后由 编辑
    #1

    问题描述

    YTM32B1HA0 EccTst 代码,在执行 A/B SWAP 前(代码运行于原 A 面)可正常运行且测试通过;执行 A/B SWAP 切换至原 B 面后,运行相同的 EccTst 测试代码,出现Fls Ecc测试失败。

    • A/B Swap前Fls Ecc测试成功
      eb30d6a9-511a-413a-af4e-6c778a696bc7-image.png

    • A/B Swap后Fls Ecc测试失败
      6bf9eca2-0270-4620-8f0b-5b7cb17d0c8f-image.png

    复现方法

    使用云途提供的EccTst_Demo程序,在工程中增加Nvr Fls操作驱动,并在Demo的main函数中增加A/B SWAP代码执行A/B面切换,然后复位MCU,并重新烧录代码到MCU原B面中,然后再次运行EccTest_Demo 代码,此次运行结果中Fls Ecc测试结果显示为失败。
    增加的测试代码如下所示:

    int main(void)
    {
        /* USER CODE BEGIN 1 */
        Mcu_Init(&Mcu_Config);
        Mcu_InitClock(0);
    #if (MCU_NO_PLL == STD_OFF)
        while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
        {
            /* Busy wait until the System PLL is locked */
        }
        Mcu_DistributePllClock();
    #endif
        /* USER CODE END 1 */ 
        Board_Init();
        /* USER CODE BEGIN 2 */
        Fls_ReadSwap(&info);
        if (info == 0u)
    	{
          Fls_WriteSwap();
          Mcu_Lld_SystemReset();
    	}
        EccTst_Start();
        EccTst_TestSummerResult = EccTst_GetResult();
        EccTst_GetDetailsResult(&EccTst_TestDetailResult);
        EccTst_DeInit();
        /* USER CODE END 2 */
    
        /* Infinite loop */
        /* USER CODE BEGIN WHILE */
        while (1)
        {
            /* USER CODE END WHILE */
            /* USER CODE BEGIN 3 */
        }
        /* USER CODE END 3 */
    }
    

    原因分析

    经与 IP 确认:当STS[BOOT_INFO] = 1时,通过ECCERR_INJECT_ADDR进行 ECC 错误注入,所配置的地址为存储器物理地址,不受 Flash A/B SWAP 切换逻辑影响。

    以地址0x2000400为例:A/B SWAP 切换前,该地址归属 A 面存储区间,向ECCERR_INJECT_ADDR配置0x2000400注入错误时,实际作用地址与 EccTst 测试所用地址一致,测试可正常通过。完成 A/B SWAP 切换后,逻辑地址0x2000400映射为 B 面存储地址;但由于错误注入机制不感知 A/B SWAP,此时仍对0x2000400配置注入时,实际会作用于A 面物理地址 0x2100400。测试代码读取逻辑地址0x2000400(B 面)时,无法命中已注入 ECC 错误的存储单元,不会触发 ECC 异常,最终造成 Fls Ecc 测试失败。

    进一步验证该现象,在A/B SWAP之后,对0x2000400地址注入错误,实际读取0x2100400能够触发ECC错误,且EFM ECC_ERR_ADDR寄存器捕获到地址为0x2100400
    74805f65-ca8a-46a9-be1e-5118ebcea7bf-image.png

    修复方案

    根据上述原因分析,可采用如下方案修复该问题:在执行错误注入测试时,若检测到STS[BOOT_INFO] = 1,需由代码对写入ECCERR_INJECT_ADDR的地址执行手动 A/B SWAP 映射处理。

    #if defined (CPU_YTM32B1HA0)
    #define FLASH_PFLASH0_BASE   0x2000000U
    #define FLASH_PFLASH1_BASE   0x2100000U
    #define FLASH_PFLASH_BANK_SIZE     0x100000U
    #endif
    ECCTST_FUNC static void EccTst_Lld_Fls_TestEnable(uint32 InjectAddr, uint32 InjectData0, uint32 InkectData1)
    {
        volatile uint32 TempData = 0;
        uint32 TempAddr = 0;
        /*enable the error injection,the one bit ECC error will happen when read data in test address*/
        EccTst_Lld_Fls_EnInjectErr();
        /*Inject error data and address*/
        EccTst_Lld_Fls_InjectData(InjectData0, InkectData1);
        /*The inject address does not swap with the A/B SWAP*/
        if (((EFM->STS & EFM_STS_BOOT_INFO_MASK) >> EFM_STS_BOOT_INFO_SHIFT) == 1U)
        {
            if ((InjectAddr >= FLASH_PFLASH0_BASE) && (InjectAddr < FLASH_PFLASH0_BASE + FLASH_PFLASH_BANK_SIZE))
            {
                TempAddr =InjectAddr + FLASH_PFLASH_BANK_SIZE;
            }
            else if ((InjectAddr >= FLASH_PFLASH1_BASE) && (InjectAddr < FLASH_PFLASH1_BASE + FLASH_PFLASH_BANK_SIZE))
            {
                TempAddr =InjectAddr - FLASH_PFLASH_BANK_SIZE;
            }
            else
            {
                TempAddr = InjectAddr;
            }
        }
        else
        {
            TempAddr = InjectAddr;
        }
        EccTst_Lld_Fls_InjectAddr(TempAddr);
        __ASM("ISB");
        __ASM("DSB");
    #if (PLATFORM_ENABLE_CACHE == STD_ON)
        /* MR12 Rule 11.4 VIOLATION: In this specific case, need to clear the DCACHE for ECC error injection,
        * and couldn't adhere to M3CM Rule-11.4.
        */
        SCB_InvalidateDCache_by_Addr((uint32 *)InjectAddr, 64); /*PRQA S 0306*/
    #endif
        /*Trigger fls ECC error*/
        /* MR12 Rule 11.4 VIOLATION: In this specific case, need to read the InjectAddr to trigger ECC error,
        * and couldn't adhere to M3CM Rule-11.4.
        */
        TempData = *((uint32 *)InjectAddr); /*PRQA S 0306*/
        /*The purpose of the following code is simply to keep the previous line of code from being optimized by the compiler.*/
        TempData += 1U;
        if (TempData != 1U)
        {
            __ASM("nop");
        }
        EccTst_Lld_Fls_DisInjectErr();
    }
    
    

    影响版本及临时解决方案

    本次问题影响的版本如下:

    • YTM32B1HA0_SafLib_2_0_0及之前版本。

    在本次问题修复版本正式发布前,可按照前文所述修复方案,修改EccTst_Lld_Fls.c文件中的对应函数,作为临时解决方案。

    1 条回复 最后回复
    0
    • YuntuAIY 离线
      YuntuAIY 离线
      YuntuAI YunTu
      编写于 最后由 编辑
      #2
      此主題已被删除!
      1 条回复 最后回复
      0
      • yt0069Y yt0069 从 MCAL Private Issues 移动了该主题

    • 云途开发生态介绍

      快速上手云途开发生态

    • 云途论坛规则/Yuntu Forum Rules

      发帖前请查看

    • YT CONFIG TOOL调查问卷

      帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...

    • can
      24
      demo
      22
      lin stack
      13
      uds
      13
      md14
      6
      yt-link
      6
      fbl
      5
      adc模块
      4
      Online Users
      chriskikiC
      chriskiki
      NooBN
      NooB
      • 登录

      • 登录或注册以进行搜索。
      • 第一个帖子
        最后一个帖子
      0
      • 版块
      • 最新
      • 标签
      • 热门