STM32程序进不了main函数奇葩现象---你不知道的原因

2023-05-16

1.现象

   在基于STM32开发一个项目过程中,遇到一个比较奇葩的现象:经常会时不时出现修改上层的应用代码导致程序运行不起来,进不去main函数。这个STM32程序是分为bootloader层和APP层,出现这个奇葩现象的时候,bootloader层是可以正常运行的,但是跳转到APP层的时候,就发现进不了main函数。

2.分析

   一开始也是找不到原因何在,通过网上搜索发现也有类似出现STM32进不去main函数的,原因多数是因为printf函数的应用导致的。但通过代码检查发现我遇到的这个奇葩现象,并非printf函数运用导致。这里也借此了解一下printf函数在stm32中使用注意事项,避免出现这个错误。

printf函数:

  printf之类的函数,使用了半主机模式,所以要利用目标ARM器件的输入输出设备,首先要关掉半主机机制,然后再将输入输出重定向到ARM器件上,如printf和scanf,需重写fputc和fgetc.

具体代码实现可参考如下(重写fputc):

#if 1
#pragma import(__use_no_semihosting)  //确保没有从C库链接使用半主机的函数
//标准库需要支持的函数
struct __FILE
{
    int handle;
};

FILE __stdout;
//以避免使用半主机模式
void _sys_exit(int x)
{
    x = x;
}

//重定义fputc函数
int fputc(int ch, FILE *f)
{
    while((USART1->ISR & 0X40) == 0); //循环发送,直到发送完毕

    USART1->TDR = (u8) ch;
    return ch;
}
#endif

如果不重写fputc等函数,也可直接勾选keil工具里面的Use MicroLIB.

3. 仿真调试

    当经过检查后,发现并非是printf函数使用不当导致程序进不去main函数,于是采用在线仿真的方式一步步查找原因。

第一步:先是全速运行,发现程序直接进入了HardFault_Handler。

接着分析启动文件startup_stm32xx.s:在执行进main函数之前,会先执行SystemInit函数,进行系统初始化。

在SystemInit函数里面打断点,单步执行调试,看程序能否执行进来:发现程序可以执行进来。

于是结合上面分析的printf函数原因, 于是尝试在fputc函数打一断点,看是否会跑进fputc函数:发现程序确实跑进了fputc函数

  通过SystemInit函数单步执行跑到fputc函数可以分析到,应该是程序哪里出错后,执行了打印输出,而此时串口并未初始化。发现从SystemInit到fputc这样顺序执行下来,不可能会出现打印的函数,那此时有可能就是发生了某种中断,导致在进入main函数之前,跑进了一个中断处理函数里面去了。

 那有可能是哪个中断导致的呢?: 像定时器、RTC这些中断,都是进入main函数初始化后才会开启的,排除了这类中断,那应该就是某种系统中断导致的。该stm32程序用到了FreeRtos系统,那可能中断就是systick中断,svc中断,pendsv中断。而svc、pendsv中断都是FreeRtos系统启动后才会执行的。那最大可能就是systick中断了。

接着在systick中断函数打断点,重新单步执行,看是否进入该中断:确实进入了该中断。

通过对这个中断函数一步步执行,发现最终在此处出错了:进入了HardFault_Handler。

定位到是系统滴答中断systick导致进不去main函数的原因了,那哪里开启了这个中断呢?通过代码分析发现是bootloader程序开启了这个中断,在跳转到main函数之前并未关闭这个中断,导致出现了这中异常错误。

4.解决办法

  既然是系统滴答中断导致的进不去main函数,那就要在进入main函数之前关闭这个滴答中断。

方法一: 在bootloader程序跳转到app层时就关闭系统滴答中断:SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;

方法二:在SystemInit函数关闭系统滴答中断:SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; (如下图所示)

5.总结

  在实际项目运用过程中,遇到类似这些奇葩现象,可以尝试通过仿真调试,一步步尝试可能出现错误的地方,进行打断点分析,找出根因所在,你的点赞是我最大的动力。  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32程序进不了main函数奇葩现象---你不知道的原因 的相关文章

  • 尚硅谷大数据项目之Flink实时数仓-踩坑记录和笔记记录

    这里写自定义目录标题 1 关于Slf4j注解配置文件logback xml不生效问题2 判断新老用户的时候 xff0c 什么时候会出问题 xff1a 3 为什么维度数据选择存储在Hbase中 xff0c 而不是Redis xff0c Mys
  • 【学习笔记】尚硅谷大数据项目之Flink实时数仓---数据可视化接口实现

    这里写自定义目录标题 第 1 章 数据可视化接口1 1 设计思路1 2 需求梳理1 2 1 最终显示效果图1 2 2 分析可视化大屏1 2 3 接口执行过程 第 2 章 Sugar 数据大屏2 1 产品介绍2 2 使用入口2 3 创建数据大
  • VR发展前景展望

    VR发展前景展望 引子 随着计算机技术的飞速发展 xff0c 虚拟现实也在短时间内经历了萌芽探索到飞速发展完善的转变 由于其独特的沉浸式体验 xff0c VR的前景被大多数人看好 xff0c 更多的VR相关技术也在为让人能更完美的融合到这个
  • Ubuntu18.04下C++分文件编写报错:对‘Class::Func()’未定义的引用解决办法

    源代码结构 如图所示 xff0c 编写一个员工管理系统 xff0c 在WorkerManager h中声明类和函数 xff0c 在WorkerManager cpp中写具体实现在staffManagementSystem cpp中实例化类
  • 人工智能是什么?

    人工智能是什么 xff1f 欢迎大家迈入人工智能的大门1 人工智能的定义2 人工智能的话题3 人工智能的四大技术分支4 人工智能的主要应用领域5 人工智能的三种形态5 1 弱人工智能到强人工智能有多难 xff1f 5 2 弱人工智能的前进方
  • 浏览器-基本认证(Basic Authentication)-摘要认证(digest authentication)=spring boot实现demo

    平时开发的 java web 网站登录 xff0c 都是通过表单提交登录信息 有时一些中间件登录是浏览器弹窗 xff0c 没有看到表单实现代码 故通过查询 xff0c 发现两种 HTTP 简单认证 xff1a 基本认证 Basic Auth
  • PX4 gazebo仿真 2023.4.13更新

    前言 想实现px4仿真 xff0c 考虑使用gazebo仿真 去PX4官网看一眼先 xff0c 官网提到后面如果要用ROS xff0c 直接配置ROS就好了 xff0c 不然会不兼容 xff0c 那么就按官网步骤走 官网步骤 结果第一步就失
  • PX4 & gazebo仿真 offboard模式无法起飞解决思路

    前言 我用最新版PX4固件 xff0c offboard模式飞机无法起飞 xff0c 网上有一种说法是固件版本的问题 xff0c 让用旧一点的版本 添加链接描述 这个链接描述的情况和我的一模一样 xff0c 所以我肯定是按这个方法尝试的 旧
  • 数字图传VS模拟图传 图传技术知识 2023.3.6更新

    引言 在研究无人机小半年了 xff0c 多次听到数字图传和模拟图传字眼 xff0c 一直都是一知半解 xff0c 这次整体了解一下并加以 整理 数字图传 数字图传 xff1a 指数字化的图像信号经信源编码和信道编码 xff0c 通过数字信道
  • 069-线性系统的可控性和可观测性

    对一个线性系统 xff0c 需要判定其可控性或者可观测性 xff0c 才能对其进行求解 或者说的狭义一点 xff0c 在一个卡尔曼滤波模型中 xff0c 只有判定了其可控性 xff0c 才能知晓状态向量X中多少个状态是可观测的 比如X中原有
  • 滴水石穿

    不积跬步 xff0c 无以至千里 xff1b 不积小流 xff0c 无以成江海 1 hashcode相等两个类一定相等吗 equals呢 相反呢 hashcode相等 xff0c 两个类不一定相等 xff1b equals相等 xff0c
  • C++编程——友元

    文章目录 1 友元的概念2 友元的三种实现2 1 全局函数做友元2 2 类做友元2 3 成员函数做友元 1 友元的概念 友元目的是让一个函数或者类访问另一个类中的私有成员 有一个非常生动的例子 xff0c 就是家中会有客厅和卧室 xff0c
  • C++编程——多态

    文章目录 1 多态的基本概念1 1 函数地址早绑定1 2 地址晚绑定 2 多态的原理3 多态的优点与案例3 1 多态的优点3 2 计算器实现案例 4 纯虚函数与抽象类5 虚析构与纯虚析构5 1 虚析构实现5 2 纯虚析构实现 多态的知识结构
  • 自动驾驶常用数据集KITTI使用指南之一——图像雷达数据融合

    对于自动驾驶环境感知算法的初学者而言 xff0c 一辆搭载各类传感器的自动驾驶汽车或者数据采集平台并没有那么重要 xff0c 甚至 xff0c 由于国外早期自动驾驶研究学者的严谨态度 xff0c 一些公开的数据集比自己采集的数据集在同步性
  • 笔试题

    杭州公交云笔试题 输入一个字符串用逗号隔开 xff0c 找出其中最大的连续递增个数 例如 xff1a 1 xff0c 2 xff0c 3 xff0c 1 xff0c 1 xff0c 1 返回3 import java util public
  • C++STL迭代器

    迭代器 1 迭代器 xff1a 类中类 xff0c 通过运算符的重载 xff0c 用类中类的对象遍历容器 2 迭代器分类 xff1a xff08 1 xff09 正向迭代器 xff1a iterator xff08 begin end xf
  • Dockerfile详细解析(四)——环境变量

    环境变量 xff08 Environment replacement xff09 环境变量 xff08 使用 ENV 表达式声明 xff09 也可以被用在某些确定的指令中作为变量被Dockerfile解释出来 Escapes 也被处理为类似
  • STM32 FreeRTOS系列教程(一)FreeRTOS简介

    参考资料 xff1a 正点原子STM32F4 FreeRTOS开发手册 V1 1 野火FreeRTOS 内核实现与应用开发实战 基于STM32 学习RTOS的意义 当我们进入嵌入式这个领域的时候 xff0c 往往首先接触的都是单片机编程 x
  • 关于句柄表的一些文章

    文章链接 1 gt Windows内核情景分析 3 4 1 Windows 进程的句柄表 2 gt Windows 句柄表格式 3 gt Windows句柄表分配算法分析 4 gt 浅谈Windows句柄表 5 gt 句柄啊 3层表啊 Ex
  • 一天实现ros环境搭建和yolov3tiny算法系列(一)之WIN10+Ubuntu20.04的双系统实现

    这几天因为参加无人机比赛 xff0c 我负责算法部分 xff0c 被搭建环境折磨的头都要秃了 xff0c 写这个文章 xff0c 只是想让大家只要按照步骤 xff0c 能够在最短的时间内搭建起环境 xff0c 愿天下没有再被搭建ros 43

随机推荐