0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

S32K146的hard fault问题解决方案

CHANBAEK 来源:Auto FAE进阶之路 作者: Yingming 2023-11-22 11:35 次阅读

1案例背景

最近有个客户使用S32K146的产品在量产之后出现了三个售后件,ABBA测试之后的结果表明失效现象跟着S32K146走;同时客户反馈说试着将其中一个售后件重新烧录程序,S32K146又正常工作了。结合这两种情况,S32K146应该是没有损坏的,那就需要从软件程序方面排查了。

然后和客户的软件工程师交流了一下,使用Attaching to Running Target的方式发现程序卡死在HardFault。因为是量产产品出问题,客户强烈要求去现场处理问题,特地记录下这次处理S32K146的hard fault问题的过程,希望对读者有帮助。

2方案准备

在这之前,笔者还没有处理过S32K1系列发生HardFault的问题,所以需要先对S32K1系列发生HardFault的原因进行了解。推荐如下这篇文章,讲得非常细致。

结合上面这篇文章以及ARM官方的M4内核文档Cortex -M4 Devices Generic User Guide ^[1]^ ,笔者简要整理了下S32K1发生HardFault的可能原因以及排查方式,如下文所述。

2.1 HardFault(硬件错误异常)

  • HardFault的可能原因
    1. 停止调试关闭时发生了调试事件;
    2. UsageFault、BusFault、MemManage Fault未使能(Coretex-M4F内核默认状态)时发生了相应的错误导致错误升级到HardFault;
    3. 异常处理过程中取内核中断向量表读操作错误。
  • HardFault的原因排查 造成HardFault的原因,可通过SCB模块的硬件错误状态寄存器(HFSR)进行排查,如下所示:
    • 原因1引起的,DEBUGEVT bit置1;
    • 原因2引起的,FORCED bit置1;
    • 原因3引起的,VECTTBL bit置1。

图片
HFSR寄存器

2.2 UsageFault(用法错误异常)

  • UsageFault的可能原因
    1. 执行未定义指令,即非法指令;
    2. 指令执行状态错误;
    3. 异常返回错误;
    4. 尝试访问关闭或者不可用的协处理器
    5. 非对齐地址访问(需要先通过SCB模块的CCR寄存器进行使能);
    6. 除零操作(需要先通过SCB模块的CCR寄存器进行使能)。
  • UsageFault的原因排查 造成UsageFault的原因,可通过SCB模块的用法错误状态寄存器(UFSR)进行排查,如下所示:
    • 原因1引起的,UNDEFINSTR bit置1;
    • 原因2引起的,INVSTATE bit置1;
    • 原因3引起的,INVPC bit置1;
    • 原因4引起的,NOCP bit置1;
    • 原因5引起的,UNALIGNED bit置1;
    • 原因6引起的,DIVBYZERO bit置1。

图片
UFSR寄存器

2.3 BusFault(总线错误异常)

  • BusFault的可能原因

    • a. 异常/中断入口压栈;
    • b. 异常/中断返回出栈;
    • c. 预取指;
    • d. FPU lazy state现场保护;
    1. Crossbar总线矩阵slave端口返回错误响应,当:
    2. 精确总线错误;
    3. 不精确总线错误。
  • BusFault的原因排查 造成BusFault的原因,可通过SCB模块的总线错误状态寄存器(BFSR)进行排查,如下所示:

    • 原因1.a引起的,STKERR bit置1;
    • 原因1.b引起的,UNSTKERR bit置1;
    • 原因1.c引起的,IBUSERR bit置1;
    • 原因1.d引起的,LSPERR bit置1;
    • 原因2引起的,PRECISERR bit置1;
    • 原因3引起的,IMPRECISERR bit置1。

图片
BFSR寄存器

2.4 MemManage Fault(存储器管理错误异常)

  • MemManage Fault的可能原因
    1. 尝试加载和储存内核MPU保护的地址;
    2. 从内核MPU保护的地址取指;
    3. 由MPU违规引起的压栈和出栈(函数调用或者中断/异常处理)错误;
    4. 硬件FPU lazy state保护触发的MPU存储器保护违规。
  • MemManage Fault的原因排查 造成MemManage Fault的原因,可通过SCB模块的存储器管理错误状态寄存器(MMFSR)进行排查,如下所示:
    • 原因1引起的,DACCVIOL bit置1;
    • 原因2引起的,IACCVIOL bit置1;
    • 原因3引起的,MSTKERR或MUNSTKERR bit置1;
    • 原因4引起的,MLSPERR bit置1;

图片
MMFSR寄存器

UFSR、BFSR、MMFSR寄存器都是SCB模块中CFSR寄存器的子寄存器,包含关系如下,实际调试时查看CFSR寄存器即可。

图片
CFSR寄存器

如果要访问UFSR、BFSR、MMFSR这些子寄存器,可以按照如下的地址进行访问:

图片
CFSR子寄存器地址

3现场支持

了解了引起HardFault的可能原因以及排查方式之后,就是按照该方法协助客户进行原因排查。

3.1 现场环境

客户的现场环境如下:

  • 开发环境:IAR 8.30.1
  • 调试器:Jlink V9
  • MCU:S32K146
  • SDK:EAR0.8.6

3.2 排查过程

  1. 打开和异常件对应的软件工程,使用Attach方式连接上第一个异常件的主控S32K146,如下图所示:图片
  2. 进入仿真界面后,暂停之后发现程序卡死在hard fault。
  3. 查看S32的SCB模块,HFSR寄存器的FORCED bit置1,说明是其它错误上升到hard fault,需要查看CFSR寄存器了解更多信息图片
  4. CFSR寄存器的BFARVALID bit 和PRECISERR bit都置1,说明是精确总线错误造成bus fault并且捕捉保存了精确总线错误发生时的数据访问地址;再去查看BFAR寄存器,发生错误时数据访问的地址是0x100010E8。图片
  5. 使用同样的方法排查第二个异常件的主控MCU,也是精确总线错误造成的bus fault,发生错误时数据访问的地址是0x10001128。图片
  6. 接着通过IAR查看下S32K146的memory,从地址0x10001128起始的8个字节长度的flash区域数据无法查看。图片
  7. 翻阅S32K1的memory相关的应用笔记AN11983: Using the S32K1xx EEPROM Functionality – Application Note ^[2]^ ,发生错误的地址属于D-Flash,如下图所示:

图片
S32K1xx Memory Map

  1. 查阅软件代码中读写DFlash中这块地址的函数,发现在写DFLASH之前虽然进行了擦写操作,但是并没有设置擦写成功之后才能写DFlash的条件,有概率出现擦写不完全的情况下写D-Flash。同时,客户查看了其他组未出问题的产品的软件代码,在写D-Flash之前添加了比较多的条件判断,包含对擦写状态的判断。至此,该问题初步得到解决,剩下的就是优化代码并跟进后续产品的表现了。

4异常模拟

客户的问题虽然解决了,但是笔者还是不确定连续两次对同一块区域的Flash写不同的值,中间没有擦除动作,是否会让MCU卡在HardFault,所以使用手上的S32K144开发板进行了该情况的模拟。

4.1 测试环境

  • 开发环境:S32 Design Studio for ARM 2.2
  • SDK:RTM 3.0.0
  • 开发板:S32K144EVB-Q100

4.2 测试过程

  1. 打开S32DS 2.2,选择自带的例程 flash_partitioning_s32k144图片
  2. 将初始化模拟EEPROM的部分注释掉,避免D-Flash被用作模拟EEPROM的备份区从而无法进行读写测试。图片
  3. 定义一套新数组并储存新的数据用于测试。图片
  4. 在正常的D-Flash写之后增加写入不同数据的操作。图片
  5. 编译之后进行debug,单步调试发现如果只进行写不同数据进入D-Flash,S32K144不会进入HardFault,需要再执行读D-Flash的操作,才会进入HardFault。图片

如果想要了解读取Flash地址的数据才会发生HardFault的原因。

  1. S32DS之所以能在控制台显示比较多的MCU异常信息,是因为在调试器界面使能了异常捕捉功能,这部分功能依赖的是DEMCR寄存器,如下图所示。

图片
异常捕捉配置

图片
DEMCR寄存器

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8658

    浏览量

    361934
  • 寄存器
    +关注

    关注

    30

    文章

    5042

    浏览量

    117769
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39862
  • 软件
    +关注

    关注

    67

    文章

    4351

    浏览量

    85663
  • 烧录程序
    +关注

    关注

    0

    文章

    14

    浏览量

    9255
收藏 人收藏

    评论

    相关推荐

    s32k146如何初始化RAM?

    我在当前项目中使用 s32k146。因为我需要初始化 RAM,除了上电复位之外的每次复位的特定部分。(On Power On Reset 应初始化所有数据)。有什么办法可以做到这一点吗?
    发表于 03-31 07:36

    S32K146 UART DMA使用问题求解

    项目简介:1.采用S32K146单片机;2. 使用了很多MCU外设,比如UART(BR: 230000bps), CAN, I2C, GPIO, LPIT, LPTMR, FTM(2 modules
    发表于 04-04 06:29

    S32K146是否支持HSM(Hardware Security Module) Medium?

    S32K146是否支持HSM(Hardware Security Module) Medium?
    发表于 04-07 08:07

    S32K146微控制器的启动时钟配置在哪个文件中?

    S32K146 微控制器的启动时钟配置在哪个文件中?如果可能,请提供配置代码示例。
    发表于 04-10 06:53

    使用S32K146时想添加SCST内核自检代码进行内核检测,要怎么实现?

    使用S32K146时想添加SCST内核自检代码进行内核检测,现在使用IDE S32DS,使用API​​调用测试函数时发现测试中m4_scst_exception_hard_fault1出现异常导致
    发表于 04-14 07:42

    请问S32K146使用的SDK可以集成FreeRTOS10.5.1吗?

    我们使用的芯片是S32K146,我们使用的SDK是RTM4.0.3版本。集成的 FreeRTOS 版本为 10.2.1。在Free RTOS官网上,Free RTOS Kernel的最新版
    发表于 04-14 07:16

    将处理器类型从S32K144更改为S32K146,无法更改SDK是为什么?

    在我的项目中,我将处理器类型从 S32K144 更改为 S32K146。 这一切都有效,直到我无法更改 SDK。在工程树中的SDK路径中就是右边的S32K146 MCU。我还更改了预处理器的定义符号
    发表于 04-19 11:39

    S32K146评估板上是否有可用的外部振荡器?

    S32K146评估板上是否有可用的外部振荡器。
    发表于 04-20 07:44

    S32K146 ECC初始化器,为什么不初始化堆栈空间?

    S32K146 ECC初始化器,为什么不初始化堆栈空间?
    发表于 04-20 12:55

    s32k146如何识别硬故障源?

    我已经添加了以下链接中提到的调试例程: 我正在使用 s32k146 ARM 的 S32 设计工作室 版本:2018.R1 内部版本号:180815 我得到固定值 r1
    发表于 04-25 06:48

    如何在S32K146微控制器中切换PORTA第11个引脚?

    我想在 S32K146 微控制器中切换 PORTA 第 11 个引脚所以我编写了如下代码 -------------------------------------- PORT_PCR_MUX(1
    发表于 05-09 07:57

    S32K146的SWD引脚和reset_b引脚配置为普通IO,如何恢复?

    S32K146的SWD引脚和reset_b引脚配置为普通IO,如何恢复?
    发表于 05-09 06:32

    如何使用S32K146定期对单个ADC通道进行采样?

    我正在使用 S32K146 微控制器,并希望设置单个 ADC 通道的定期采样。有没有一种方法可以在此微控制器上实现定期采样,也许使用 PDB?我回顾了使用PDB触发ADC转换的ADC硬件触发方法
    发表于 05-30 12:30

    S32K146如何用中断唤醒VLPS模式?

    S32K146的模式设置为VLPS后,触发外部中断后CLOCK_SYS_GetFreq获取的频率没有变化,如何使用中断将电源模式从VLPS恢复为RUN?
    发表于 06-01 08:13

    记录一次hard fault on handler的解决过程

    最近在做一个OTA的功能时,遇到一个hard fault on handler的问题,前前后后排查了将近2天,才将此问题解决,因此做一个记录,方便其它工程师,遇到此类问题的时候有个参考。
    的头像 发表于 10-12 16:45 1675次阅读
    记录一次<b class='flag-5'>hard</b> <b class='flag-5'>fault</b> on handler的解决过程