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

YunTu Forum

YTMicro.com
  1. 主页
  2. Discussion & Question
  3. YT SDK
  4. I2C 异步通讯导致 HardFault 问题

I2C 异步通讯导致 HardFault 问题

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

    1. 问题背景

    1. 软件:ME0 SDK1_3_1 I2c_Master_Demo
    2. 硬件:客户板子 or ME05 EVB
    3. 问题描述:
    • 客户调用 I2C_DRV_MasterReceiveData 函数发送会触发 HardFault。
    • 客户代码逻辑是当识别到芯片有报 fault 持续 1-3s 然后重新走上下电时序(处 MCU 外,其他外设芯片执行上下电逻辑),I2C 4.7K 上拉电阻的电源也会重新上下电,此时 I2C 总线 SDK 和 SDA 也会同步拉低再拉高,拉低持续时间有 800ms 左右。
    • I2C 外设芯片上下电后,MCU 会调用 I2C_DRV_MasterReceiveData 函数,此时若使用 I2C_DRV_MasterGetTransferStatus + while,需要获取返回值为 STATUS_SUCCESS 才能跳出循环,但此时由于 SDK 和 SDA 拉低时间超过寄存器 TOCFG -> LOW 设置的最大时间,寄存器 MSTS -> TOIF 标志位会置 1,I2C_DRV_MasterIRQHandler 函数里会将 master->status = STATUS_I2C_LINE_LOW_TIMEOUT,此时会一直卡在 while 函数里出不来。
    • 如果把调用 I2C_DRV_MasterReceiveData 函数后,I2C_DRV_MasterGetTransferStatus + while 等待接收完成去掉,则会触发 HardFault。但当 RXBUFF 数组由局部变量改为静态局部变量或全局变量后,不会触发 HardFault。

    2. 问题分析

    2.1.1 Line low timeout detected 超时分析

    1. 先确定 TOCFG -> LOW 设置的最大时间是多久,是否真的是拉低时间超时后,导致的 MSTS -> TOIF 标志位置 1。
    2. 在 I2C 初始化的时候,I2C_Set_MasterLineLowTimeoutPeriod 函数会将 LOW 的值设为 0xFFF。

    9ee02551-35ae-4b04-9bba-81aa137f1b7a-image.png

    1. 时钟为 8M,LOW 值为 0xFFF,根据公式计算,(4096 * 256)* (1 / 8M) = 131ms,而实际拉低时间是 800ms,确实触发超时,MSTS -> TOIF 标志位置 1,理论与实践现象一致。

    375c9480-42ca-4ca5-91f6-b53a79ea1109-image.png

    2.2 HardFault 原因分析

    1. 使用 I2c_Master_Demo 例程,模仿客户代码调用方式对问题进行复现

    1039cc8a-d408-45fd-ae82-0f45fba727b3-image.png

    1. 实际 Debug 确定可以看到,当出现 HardFault 时,I2C 未接收完成

    6efa2f84-3a91-463d-b83e-072daf4ae7d9-image.png

    1c1d7221-a043-49f3-b655-ac9467f5b130-image.png

    1. 当更改 RXBUFF 为静态局部变量后,就不会出现 HardFault ,其 I2C 通讯波形是完整的,有起始位和停止位。

    0692b417-fdf7-40f1-b3e2-b9ee7fae7f2c-image.png

    3e2712aa-bfb1-41e7-bbde-6d5e7037e0cb-image.png

    1. 出现 HardFault 后观察栈空间以及修改栈空间大小均无效果,可以推断堆栈未出现溢出。RXBUFF 数组仅修改变量存储位置,即可避免 HardFault 出现,推测跟变量的存储位置及生命周期有关系,由于局部变量在函数执行结束后就释放了,可能是 i2c_Read 函数已经执行结束了,将 RXBUFF 数组释放了,但由于 I2C 接收还未完成,但接收 BUFF 已经被释放了,但此时还在给 RXBUFF 收数据,所以触发了 HardFault 。
    2. 在 i2c_Read 函数里和函数执行完成后分别设一个标志位,当出现 HardFault 的情况时 asd[1] 已经置 1 了,此时 i2c_Read 函数执行完毕 RXBUFF 数组已经被释放了,但此时 I2C 通讯还未结束,还在给 FIFO 写数据,所以触发了 HardFault 。

    614f878d-7414-44e1-9f1a-c6217d339793-image.png

    3. 问题总结

    1. 使用 I2C_DRV_MasterReceiveData 函数时,必须使用 I2C_DRV_MasterGetTransferStatus 获取 I2C 状态,同时记得 I2C_DRV_MasterGetTransferStatus + while 等待的时候记得加上超时机制。

    9187f2f8-2da6-43e5-ae5b-a780d563a5d0-image.png

    1. 也可以将 RXBUFF 设置为全局变量或静态变量。
    1 条回复 最后回复
    0

  • 云途开发生态介绍

    快速上手云途开发生态

  • 云途论坛规则/Yuntu Forum Rules

    发帖前请查看

  • YT CONFIG TOOL调查问卷

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

  • can
    23
    demo
    20
    uds
    13
    lin stack
    12
    md14
    6
    fbl
    5
    yt-link
    5
    adc模块
    4
    Online Users
    zhaodong1Z
    zhaodong1
    FrankieF
    Frankie
    番茄+两个蛋番
    番茄+两个蛋
    mcM
    mc
    Tiger987T
    Tiger987
    EkkoE
    Ekko
    xiangyuX
    xiangyu
    D
    Derrick
    彭希哲彭
    彭希哲
    abcbillA
    abcbill
    xianghanX
    xianghan
    YQHY
    YQH
    swordsS
    swords
    • 登录

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