STM32 | MCU错误代码自动追踪库的使用经验分享

发布者:云淡风轻2014最新更新时间:2021-08-10 来源: eefocus关键字:STM32  MCU  错误代码 手机看文章 扫描二维码
随时随地手机看文章

大家在用STM32的时候有没有遇到过HardFault的问题呢:

======001

下面针对这个问题做个小总结。


现象还原:在debug模式下进行仿真调试,全速运行再停止运行,程序会跑到 HardFault_Handler函数中,产生 HardFault,即硬错。其产生的原因大概有如下几类:

(1)数组越界操作;

(2)内存溢出,访问越界;

(3)堆栈溢出,程序跑飞;

(4)中断处理错误;


针对HardFault问题的定位,网上有几种方法,大概都是围绕着:在debug模式下,查看一些地址,分析寄存器、函数调用栈等,这是很让人头疼的事情。这里分享一种简单的、直观的HardFault错误定位的方法,使用开源库: CmBacktrace 。这个库之前已经有介绍过了,这篇笔记我们来实践一下。


CmBacktrace简介

 CmBacktrace (Cortex Microcontroller Backtrace)是一款针对 ARM Cortex-M 系列 MCU 的错误代码自动追踪、定位,错误原因自动分析的开源库。主要特性如下:

  • 支持的错误包括:

    • 断言(assert)

    • 故障(Hard Fault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault)

  • 故障原因 自动诊断 :可在故障发生时,自动分析出故障的原因,定位发生故障的代码位置,而无需再手动分析繁杂的故障寄存器;

  • 适配 Cortex-M0/M3/M4/M7 MCU;

  • 支持 IAR、KEIL、GCC 编译器;


移植及使用(keil)

 CmBacktrace 源码地址:

https://github.com/armink/CmBacktrace

======002

把cm_backtrace文件夹复制到我们的工程目录下,并添加至keil工程中,并添加头文件、勾选C99模式:

======003
======004

此时,编译会产生几个错误:
======005

那是因为有些预处理宏没有找到,打开、修改cmb_cfg.h文件的内容。cmb_cfg.h文件默认内容为:
======006

我们修改后的cmb_cfg.h内容变为:

======007

这时候编译还会有一个错误,cmb_fault.c与stm32f10x_it.c中的HardFault_Handler函数重定义:
======008

需要把stm32f10x_it.c中的HardFault_Handler函数屏蔽掉:

======009

这时候就可以编译通过了。下面我们来看看这个库的效果。

测试函数:

void fault_test_entry(fault_test_case_E _test_case)

{

switch (_test_case)

{

case FAULT_TEST_BY_DIV0: 

fault_test_by_div0();

break;

case FAULT_TEST_BY_UNALIGN: 

fault_test_by_unalign();

break;

default: 

printf("test case error!n");

break;

}

}


static void fault_test_by_div0(void) 

{

    volatile int * SCB_CCR = (volatile int *) 0xE000ED14; // SCB->CCR

    int x, y, z;


    *SCB_CCR |= (1 << 4); /* bit4: DIV_0_TRP. */


    x = 10;

    y = 0;

    z = x / y;

    printf("z:%dn", z);

}

然后在主函数中调用测试函数:

======010
======011

下载运行程序:
======012

可以看到,列出的信息很详细,包括出错原因。按照它的提示,我们运行命令:

addr2line -e stm32f10x_demo.axf -a -f 0800162a 080016b7 08001719


运行这个命令需要用到addr2line.exe工具,这个工具在 CmBacktrace源码目录下的tools文件夹中:
======013

有32bit和64bit两个版本,根据我们的环境选择,并拷贝到我们的keil工程目录下可执行文件.axf所在的文件夹中:
======014

在这个文件中进入到cmd窗口,方法:按下Shift键的同时点击鼠标右键:
======015

运行上面那条命令:
======016

可以看到addr2line.exe工具给我们定位出了错误相关的代码行号,我们看看对应行的代码是什么:
======017

对应的行号正是出错的地方。

可以看到,使用这个 CmBacktrace 库能帮助我们有效、快速地定位到HardFault之类的错误。addr2line命令后面跟着几个地址就是错误相关的地址,这几个地址可以牵扯的内容很深,如果我们不使用 CmBacktrace 库,我们可能就得自己去分析这些偏底层的内容了,相关知识可阅读:《Cortex-M3/M4权威指南》。

关键字:STM32  MCU  错误代码 引用地址:STM32 | MCU错误代码自动追踪库的使用经验分享

上一篇:STM32 | STM32F429的USB有坑?
下一篇:STM32 | 分享自定义协议的一些典型例子

推荐阅读最新更新时间:2024-11-17 11:19

STM32—SysTick使用方法
一、STM32的SysTick简介   SysTick是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一定的时间间隔。 systick的作用:    在单任务引用程序中,因为其架构就决定了它执行任务的串行性,这就引出一个问题:当某个任务出现问题时,就会牵连到后续的任务,进而导致整个系统崩溃。要解决这个问题,可以使用实时操作系统(RTOS).   因为RTOS以并行的架构处理任务,单一任务的崩溃并不会牵连到整个系统。这样用户出于可靠性的考虑可能就会基于RTOS来设计自己的应用程序。这样SYSTICK
[单片机]
<font color='red'>STM32</font>—SysTick使用方法
STM32】MDK5打开MDK4项目工程时出现的不兼容及解决方法
问题描述 最近在使用MDK5的时候发现了一个问题,先看一下现有的MDK的版本信息: 在用MDK5打开MDK4版本的项目工程的时候,通常会跳出一个窗口Using an MDK Version 4 Project: This is an MDK version 4 project ,require Device support for Cortex-M based devices. 解决方式 在这个窗口中提示了两种解决方法:Migrate to Device Pack(迁移到设备包) 和 Install Legacy Support(安装遗留支持)。 先尝试了第一种方式,进来之后,查看可以找的设备,但是一
[单片机]
【<font color='red'>STM32</font>】MDK5打开MDK4项目工程时出现的不兼容及解决方法
什么是指令 51单片机共有多少指令
所谓 指令 ,就是规定计算机进行某种操作的命令。 一条指令只能完成有限的功能,为使计算机完成一定的或者复杂的功能,就需要一系列指令。一般来说,一台计算机的指令越丰富,寻址方式越多,且每条指令的执行速度越快,则它的总体功能就越强。 我们学习的80C51单片机共有111条指令,这111条指令共有七种寻址方式。其中: 数据传送类指令 29条 算术运算类指令 24条 逻辑运算及移位类指令 24条 控制转移类指令 17条 位操作指令 17条 这111条指令的具体功能我们在后面的课程中将会逐条的与大家进行分析。
[单片机]
恩智浦ARM微控制器的以太网吞吐量三种不同测量方案的介绍
本文介绍了一种测量以太网吞吐量的方法,提供了良好的性能估计,并说明了影响性能的各种因素。 以太网是世界上安装最广泛的局域网(LAN)技术。它自20世纪80年代早期开始使用,并被IEEE Std 802.3所涵盖,它规定了许多速度等级。在嵌入式系统中,最常用的格式是10 Mbps和100 Mbps(通常称为10/100以太网)。 有20多个内置以太网的恩智浦ARM MCU,涵盖所有三种几代ARM(ARM7,ARM9和Cortex-M3)。恩智浦在三代产品中使用了基本相同的实现,因此设计人员可以在系统迁移到下一代ARM时重用其以太网功能,从而节省时间和资源。 本文讨论了测量LPC1700产品上以太网吞吐量的三种不同方案。详
[单片机]
恩智浦ARM<font color='red'>微控制器</font>的以太网吞吐量三种不同测量方案的介绍
51单片机定时器与中断的程序设计
P2.0~P2.2 分别接上了独立按键 K0、K1、K2。 P1 接上了 8 个 LED,输出低电平时发光。 要求: 按下 K1 键,P1.7 输出周期为 1s 的方波; 按下 K2 键,P1 输出循环流水灯,每 2 个灯亮 0.5s; 按下 K0 键,停止方波和流水灯的输出。 ;----------------------------------------- ; ORG 0000H JMP START ORG 000BH ; JMP T0_INT T0_INT: MOV TH0, #(65536 - 50000) / 256 MOV TL0, #(65536 - 50000) MOD 256 DJNZ
[单片机]
51<font color='red'>单片机</font>定时器与中断的程序设计
Microchip加倍LCD PIC18单片机闪存及RAM容量以降低成本
PIC18F85J90系列单片机可提供集成的LCD模块、32 KB闪存及内部电压控制器,瞄准成本敏感的嵌入式显示应用 全球领先的单片机和模拟半导体供应商——Microchip Technology Inc.(美国微芯科技公司)推出6款集成了液晶显示器(LCD)模块的8位PIC单片机系列新产品。PIC18F85J90系列的闪存及RAM存储器容量比现有的64及80引脚系列器件增加了1倍,适用于需要嵌入式控制的高成本效益的人机接口应用,包括恒温器、民用表具及医疗仪器。存储容量的增加有助于用户增加更多诸如语音回放的复杂功能,拥有更多的自编程存储器分配,同时利用3V PIC18 J系列的制造工艺技术节省了成本。 具有片上LCD模块的PI
[新品]
stm32 中bootloader、startup_stm32f10x_md.s的作用
一、启动文件的作用是: 1. 初始化堆栈指针 SP; 2. 初始化程序计数器指针 PC; 3. 设置堆、栈的大小; 4. 设置异常向量表的入口地址; 5. 配置外部 SRAM 作为数据存储器(这个由用户配置,一般的开发板可没 有外部 SRAM); 6. 设置 C 库的分支入口__main(最终用来调用 main 函数); 7. 在 3.5 版的启动文件还调用了在 system_stm32f10x.c 文件中的 SystemInit() 函数配置系统时钟,在旧版本的工程中要用户进入 main 函数自己调用 SystemInit() 函数。 二、关于启动文件的介绍,可以参考: 1、http://www.360doc.com/cont
[单片机]
<font color='red'>stm32</font> 中bootloader、startup_stm32f10x_md.s的作用
STM32使用HAL驱动USART详解及例程
HAL库串口驱动详解 STM32硬件串口收发数据过程 串口发送流程–TXD 配置步骤: 编程USARTx_CR1的M位来定义字长。 编程USARTx_CR2的STOP位来定义停止位位数。 编程USARTx_BRR寄存器确定波特率。 使能USARTx_CR1的UE位使能USARTx。 如果进行多缓冲通信,配置USARTx_CR3的DMA使能(DMAT)。 使能USARTx_CR1的TE位使能发送器。 /* 配置1~6步骤 */ HAL_UART_Init(UART_HandleTypeDef *huart) 发送数据: 向发送数据寄存器TDR写入要发送的数据(对于M3,发送和接收共用DR寄存器)。 向TRD寄存器写入最后
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved