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

YunTu Forum

YTMicro.com
  1. 主页
  2. Discussion & Question
  3. YT MCAL
  4. YTM32B1ME15 MCAL 0.8.0:EEPROM ECC 错误处理

YTM32B1ME15 MCAL 0.8.0:EEPROM ECC 错误处理

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

    环境:
    YTM32B1ME15;
    Yuntu MCAL 0.8.0;

    1、问题

    EEPROM 单比特 ECC 错误可由硬件纠正;双比特错误不可纠正,实测读取时会触发精确 BusFault,且先于 EEPROM 中断处理。仅在 EEPROM_IRQHandler 中处理,会因故障指令反复执行而升级为 HardFault。

    MCAL 0.8.0 的 Eep 驱动提供 ECC 中断使能接口,但未实现完整的错误处理和日志记录。

    2、处理方案

    示例在应用层实现:

    • 单比特:在 EEPROM 中断中记录错误地址、计数等信息并清除标志,数据由硬件纠正。
    • 双比特:通过 RAM 向量表接管 BusFault,识别 EEPROM 不可纠正错误,按 Thumb-2 指令长度跳过故障读取指令,记录错误,并将错误地址按 4 字节对齐后擦除对应字。
    • 前提:启动代码已将向量表复制到 RAM;示例在初始化时安装 BusFault 处理函数。

    3、验证结果

    实板测试中,正常读写、单比特纠错、双比特检测及后续重写恢复四步均通过:Eep_EccStepResult=0x01010101,Eep_EccTestFailCnt=0。双比特错误地址为 0x02000040,程序未再出现 BusFault 升级为 HardFault。
    99d327fa-a27f-4ed0-9f2c-f750d5bfa25b-image.png
    c455d210-b380-4896-a820-67683f11b28c-image.png

    5、注意事项

    • 跳过故障加载指令不会产生有效读取值。实测 Eep 作业仍可能返回 MEMIF_JOB_OK,不能仅凭作业结果判断数据有效。
    • 擦除会破坏整个 4 字节字的数据,需由应用恢复;示例未向上层报告擦除超时或命令失败,且异常上下文操作 EEPROM 可能与 Eep 作业竞争。量产前须结合芯片手册验证失败处理及数据恢复。
    • 错误注入仅用于测试,测试会写入并擦除 EEPROM 测试区域。

    6、代码实现

    6.1 初始化

    main.c 初始化 MCU 时钟,随后 Board_Init 调用 Platform_Init、Fls_Init、Eep_Init 和 Eep_EccDemoInit。启动代码须先将向量表复制到 RAM 并设置 VTOR。

    IVT_RAM_start[5U] = (uint32)Eep_BusFault_Handler;
    __DSB(); __ISB();
    SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk;
    SCB->CCR |= SCB_CCR_BFHFNMIGN_Msk;
    EEPROM->STS = EEPROM_STS_UNRECOVERR_MASK | EEPROM_STS_RECOVERR_MASK |
                  EEPROM_STS_CMD_FAIL_MASK | EEPROM_STS_ACCERR_MASK;
    EEPROM->CTRL |= EEPROM_CTRL_RECOVERRIE_MASK | EEPROM_CTRL_UNRECOVERRIE_MASK;
    (void)Platform_SetIrq(EEPROM_IRQn, TRUE);
    

    6.2 注入与读取

    源码使用偏移 0x40、长度 8 字节,先写入测试数据。单比特模式为 1,双比特模式为 2,模式 0 关闭注入;Eep_EccReadJob 通过 Eep_MainFunction 等待作业完成。

    EEPROM->ERR_INJECT_CTRL = EEPROM_ERR_INJECT_CTRL_ECCERR_INJ_EN(Mode) |
                              EEPROM_ERR_INJECT_CTRL_ECCERR_INJ_ADDR(Offset);
    Eep_EccInject(EEP_ECC_INJ_MULTI_BIT, EEP_ECC_TEST_ADDR);
    Eep_EccJobResultAfterMulti = (uint32)Eep_EccReadJob(
        EEP_ECC_TEST_ADDR, ReadBuffer, EEP_ECC_TEST_LEN);
    Eep_EccInject(EEP_ECC_INJ_DISABLE, 0U);
    Eep_EccPollMultiBit();
    

    上述寄存器赋值为非零模式分支摘录。注入仅供测试,示例会写入并擦除 EEPROM 测试区域。

    6.3 BusFault 处理

    应用的 naked 异常入口根据 EXC_RETURN 位 2 选择 MSP 或 PSP,将堆栈指针传给 Eep_BusFaultHandlerC。当前实现使用 pStack[6] 作为保存的 PC,下面为对应 C 代码摘录。

    FaultPc = pStack[6];
    if (0U != (EEPROM->STS & EEPROM_STS_UNRECOVERR_MASK))
    {
        if (0x1DU <= (*(volatile uint16 *)(FaultPc) >> 11U))
            InsnLen = 4U;
        else
            InsnLen = 2U;
        pStack[6] = FaultPc + InsnLen;
        Eep_EccHandleBusFault();
    }
    else if (TRUE == Fls_Lld_GetTwoBitEccErrFlag())
    {
        pStack[6] = FaultPc + 2U;
    }
    SCB->CFSR = SCB_CFSR_BUSFAULTSR_Msk | SCB_CFSR_PRECISERR_Msk;
    

    重要限制:跳过加载指令不会生成有效读取值,也不保证 Eep 作业失败。

    6,4 错误记录与对齐擦除

    Eep_EccHandleBusFault 读取错误地址与计数,更新日志,关闭注入并清状态后调用 Eep_EccEraseWord。以下摘录省略地址范围校验及状态清理。

    ErrAddr = EEPROM->ECCERR_ADDR;
    Eep_EccLog.MultiBitErrCnt++;
    Eep_EccLog.LastErrAddr = ErrAddr;
    Eep_EccLog.LastErrCnt = EEPROM->ECCERR_CNT & EEPROM_ECCERR_CNT_ECCERR_CNT_MASK;
    Eep_EccLog.LastErrType = EEP_ECC_ERR_TYPE_MULTI;
    Eep_EccLog.NotifyCnt++;
    EEPROM->ERR_INJECT_CTRL = 0U;
    EEPROM->STS = EEPROM_STS_UNRECOVERR_MASK;
    Eep_EccEraseWord(ErrAddr);
    WordAddr = HwAddr & (uint32)(~0x3U);
    WordPtr = (volatile uint32 *)WordAddr;
    EEPROM->CTRL |= EEPROM_CTRL_WE_MASK;
    /* 源码在写入前后执行 ISB 和 DSB */
    *WordPtr = 0x00000000U;
    EEPROM->CTRL &= (uint32)(~EEPROM_CTRL_WE_MASK);
    EEPROM->CMD_UNLOCK = EEP_ECC_CMD_UNLOCK_KEY;
    EEPROM->CMD = EEP_ECC_ERASE_SECTOR_CMD;
    /* 轮询 DONE 或等待超时,然后清状态 */
    

    擦除会破坏整个对齐字的数据。当前代码未向上层报告擦除超时或命令失败,且在异常上下文直接操作 EEPROM,可能与正在进行的 Eep 作业竞争;产品化前须核对芯片手册并验证失败处理和数据恢复,不能仅凭日志认定擦除成功。

    6.5 EEPROM ECC 中断

    EEPROM_IRQHandler 根据 STS 处理:单比特分支记录 RECOVERR 并清标志;双比特分支临时关闭 UNRECOVERRIE,记录并调用 Eep_EccEraseWord,最后清状态并重开。双比特读取可能先进入 BusFault。
    6b63415c-6681-4394-8366-8aae3e5fef6d-ME15_ECC_EccErrorHandling_Demo.zip

    1 条回复 最后回复
    0

  • 云途开发生态介绍

    快速上手云途开发生态

  • 云途论坛规则/Yuntu Forum Rules

    发帖前请查看

  • YT CONFIG TOOL调查问卷

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

  • can
    29
    demo
    26
    uds
    15
    lin stack
    13
    fbl
    6
    md14
    6
    yt-link
    6
    adc模块
    4
    Online Users
    • 登录

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