单片机卡死的几大原因、分析、解决

news2025/1/17 1:08:56

阅读引言: 本文我想给大家分享一下我在学习过程中遇到的以及了解到的一些导致单片机运行卡死(死锁)的一些常见原因和解决办法, 请注意, 只是列举,并不是全部, 因为导致单片机运行卡死的原因无穷无尽。

目录

一、裸机层面

1.死循环, 条件一直成立

2.中断问题

3.外设的初始化问题

4.堆栈溢出

4.1递归导致栈溢出

4.2访问非法的内存地址

4.3内存泄漏

5.时钟的配置问题

6.程序逻辑问题

二、RTOS层面

三、常见的调试办法

1.printf函数打印

2.使用keil的调试功能

四、学习资料


一、裸机层面


1.死循环, 条件一直成立

/* 伪代码 */
while(一直为真) 
{
    
}

比如按键的检测等待按键释放的操作

2.中断问题

/* 在执行某一个中断服务函数的时候, 没有清除中断标志位 */
void EXTI_IRQHandler(void)
{
    
    //没清除中断标志位, 导致cpu一直进入中断, 主逻辑没有执行, 导致程序出现卡死的现象
}

在标准库中, 执行完中断服务函数之后, 需要手动清除中断标志位, 不然会一直进入中断, hal库的大部分的中断服务函数执行完之后, 会自动的清除中断标志位。

3.外设的初始化问题

void main()
{
    //initialize code
    

    //某一个外设初始化失败, 导致程序卡在错误处理的那个函数
}

就会导致单片机看起来卡死了一样。

另一个列子: 

4.堆栈溢出

4.1递归导致栈溢出
void recursion()
{
    recursion();
}

void main()
{
    recursion();
}

递归函数没有结束条件, 导致栈空间空间溢出。

4.2访问非法的内存地址
int main()
{
    int arr[10] = {0};

    arr[10] = 100;        /* 写非法的内存空间 */
}
4.3内存泄漏
void Getmemery()
{
    char *p = (char *)malloc(10);
}

void main()
{

    for(;;)
        Getmemery();
}

这里我使用for循环来申请空间, 来模拟我们到处申请堆空间而没有释放导致的内存泄漏, 最后导致程序崩溃。

5.时钟的配置问题

void main()
{
    //外设的时钟配置不对, 导致程序卡死


    //无法执行到这里
    while(1) {
        //code    
    }

}

6.程序逻辑问题

假设你设计的程序需要等待每一个外设接收到数据, 或者发送数据才往下执行, 这个时候就需要你自己找到你自己的代码的每一句是在干嘛。

二、RTOS层面


当你的单片机上了实时操作相同, 或者mpu装linux操作系统, 面临死锁的常见原因如下:

在单片机系统中,死锁是指多个任务或线程由于彼此之间的资源竞争而陷入永久阻塞的状态。死锁可能发生在多任务或多线程系统中,其中每个任务或线程都在等待其他任务或线程释放它们占用的资源。 导致单片机死锁的情况通常与资源竞争和资源分配有关。以下是一些可能导致死锁的情况:

1. 互斥资源:多个任务或线程同时竞争同一个互斥资源,例如共享内存区域或硬件寄存器。如果没有适当地管理和同步资源的访问,就可能导致死锁。

2. 循环等待:多个任务或线程形成了一个循环等待资源的环路。每个任务都在等待下一个任务释放资源,但所有任务都被其他任务所占用,导致死锁。

3. 延迟分配:某个任务占用资源后,未能及时释放资源。其他任务需要该资源来继续运行,但由于该资源一直被占用,导致死锁。

为了避免单片机死锁的发生,可以采取以下策略:

1. 使用合适的同步机制:使用互斥锁、信号量或其他适当的同步机制来管理共享资源的访问,确保资源在同一时间只能被一个任务或线程使用。

2. 避免循环等待:设计任务或线程的执行顺序,避免出现循环等待资源的情况。

3. 及时释放资源:确保任务或线程在使用完资源后,及时释放资源,以便其他任务或线程可以继续执行。

4. 调整系统资源分配:合理规划系统资源的分配和调度,避免资源的过度分配或容量不足。 5. 使用死锁检测与恢复机制:实施死锁检测算法,当检测到死锁的发生,通过中断或其他手段恢复系统正常运行。

  • mutex

什么是死锁:线程1和线程2 都获得了自己的锁, 线程1的锁为锁1, 线程2的锁为锁2, 这是如果线程1或者线程2 想去获得对方的锁或资源就无法获得, 造成死锁.导致二者都拿不到锁, 导致任务阻塞。

任务或者线程在访问完临界资源后记得释放锁。

三、常见的调试办法


1.printf函数打印

将单片机的uart配置好之后, 重写fputc函数, 勾选上微小C库, 随时随地的打印。

printf函数的用途: 

查看函数有没有运行到, 定位出问题的地方

查看变量的值

打印调试的信息

生成单片机运行的日志信息

2.使用keil的调试功能

不太好用, 除非是真的真的特变需要知道每一个寄存器, 或者内存的值才使用这个模式, 个人觉得用这个调试程序怪怪的, 可能是不太熟练吧。

四、学习资料


链接
提取码:1234 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1519038.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三款内衣洗衣机的顶级较量:希亦、小吉、由利,谁才是性价比之王?

洗衣机在我们的生活中可谓是非常常见的了,几乎每家每户都具备着一台。即便是有洗衣机,也有不少人不会将自己我贴身衣物直接扔在洗衣机里清洗,而是会自己手工手洗。这跟我们传统上的观念有很大的关系,认为把内衣、内裤等贴身衣物放…

MongoDB实战面试指南:常见问题一网打尽

码到三十五 : 个人主页 心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 ! MongoDB是一款流行的非关系型数据库,以其高效、可扩展的特性受到开发者的青睐。了解MongoDB的架构、存储引擎和数据结…

【C++】手撕vector类(从会用到理解)

一、标准库中的vector类 1.1 vector类介绍 1.2 vector的常用接口 1.2.1 常用的构造函数 1.2.2 容量操作接口 (1)size (2)capacity (3)empty (4)resize (5&#…

ACM记忆化DFS与基于优先队列的BFS

基本概念--记忆化DFS 使用数组保存已经算出来的值,在后续的计算中减少大量的重复计算,提高效率。(用于dp不方便,但是搜索方便的情况,可以提升效率。) eg. 记忆化dfs求解斐波那契数列 int dfs(int n) {if…

常州不大创造神话!常州股票开户佣金最低多少!股票开户佣金最低是多少?

股票操作准则是指在进行股票交易时遵循的一些基本原则和规范。以下是一些常见的股票操作准则: 量力而行:要根据自己的经济实力和风险承受能力选择适合自己的股票操作方式,不要盲目追求高回报而忽视风险。 分散投资:将资金分散投资…

力扣46. 全排列

Problem: 46. 全排列 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 回溯可以理解为是在对一个多叉树的操作 1.回溯结束条件:当决策路径的长度等于nums数组的长度时,将当前的结果添加到二维结果集res中; 2.每一次决策的选择处…

市场广泛看好的LaunchPad 平台 PenPad,有望在牛市胜出?

随着 ETF 效应下,推动比特币不断突破前高,这也进一步推动市场走向牛市。事实上,在每一轮牛市行情中,都会涌现出大量的新项目,并伴随大量的资产面向市场,而如何帮助这些资产、项目实现更好的启动变得尤为关键…

【深度学习笔记】10_10 束搜索beam-search

注:本文为《动手学深度学习》开源内容,部分标注了个人理解,仅为个人学习记录,无抄袭搬运意图 10.10 束搜索 上一节介绍了如何训练输入和输出均为不定长序列的编码器—解码器。本节我们介绍如何使用编码器—解码器来预测不定长的序…

记一次Spring事务失效的发现与解决过程

一、事情起因是这样的 首先,我们是使用Spring mybatis 进行开发。 某功能在测试环境看到报错日志, 但是数据库里面的数据发生了变化,没有回滚。 执行数据库update 操作的方法上明确有 Transactional(rollbackFor Exception.class)的注解。…

使用nuclei扩充自己的武器库-nuclei3 sdk开发指南

一、nuclei是什么 Nuclei 是一个快速、灵活、可扩展的开源漏洞扫描工具,用于发现 Web 应用程序中的安全问题。它允许安全研究人员和渗透测试人员轻松地定义和执行定制的漏洞扫描任务。 Nuclei 使用模板来定义漏洞扫描任务。这些模板是基于 YAML 格式的&#xff0c…

什么是MVC三层结构

1.MVC(三层结构) MVC(Model-View-Controller)是一种常见的软件设计模式,用于将应用程序的逻辑和界面分离成三个不同的组件。每个组件负责特定的任务,从而提高代码的可维护性和可扩展性。 以前的模式。 遇到…

kettle 9.4和Pentoho 9.4下载及安装方法简介

kettle 9.4和Pentoho 9.4下载及安装方法简介 下载地址: https://sourceforge.net/projects/pentaho/files/ 下载步骤: #------------- 一、点击选项卡:summary/ 二、点击第一行链接 https://www.hitachivantara.com/en-us/products/pentaho…

姿态旋转的哥氏定理以及速度微分的推导

姿态旋转中涉及到坐标系的转换,在有相对旋转的两个坐标系中观察一个向量的变化,用到了哥氏定理。 例如在i系中观察e系下的运动,则 哥氏定理的公式 wie是e相对于i的角运动 注意符号i在前e在后。 wie是e相对于i的角运动 注意符号i在前e在…

WRF模型教程(ububtu系统)-WPS(WRF Pre-Processing System)概述

一、WPS简介 WRF 预处理系统 (WRF Pre-Processing System,WPS) ,集成了基于Fortran和C编写的程序,这些程序主要用于处理输入到real.exe的数据。WPS主要有三个程序和一些辅助程序。 二、各程序介绍 主要的程序为geogrid.exe、ungrib.exe、met…

一篇文章带你了解低保真与高保真原型图区别

在原型设计中,低保真原型和高保真原型的区别主要体现在细节和功能上。那么我们在设计原型的时候是用低保真原型还是高保真原型呢?两者最好的使用场景是什么?对此,即时设计做了相应的分析。让我们来看看! 1、低保真原型…

[蓝桥杯]-最大的通过数-CPP-二分查找、前缀和

目录 一、题目描述: 二、整体思路: 三、代码: 一、题目描述: 二、整体思路: 首先要知道不是他们同时选择序号一样的关卡通关,而是两人同时进行两个入口闯关。就是说两条通道存在相同关卡编号的的关卡被通…

3冠达成!原知因制药荣获2024年度JMR消费者评选三大No.1

近日,日本调查机构(JMR)公布了2024年度公众对品牌形象的调查结果,除了人们熟知的资生堂、CPB、POLA、小林制药、DHC等品牌依然获得不错的口碑外,日本高端健康品牌原知因制药凭借优秀的产品实力及良好的社会口碑&#x…

Python新手必学:输入输出全攻略

初学Python编程时,其中一个最基础、也是最重要的部分就是如何处理输入和输出。无论是简单的用户输入,还是程序输出结果,都很重要。现在,我们将一起学习Python输入输出的各种技巧和方法,让你在编写代码时得心应手。 目…

HTML5:七天学会基础动画网页11

CSS3动画 CSS3过渡的基本用法: CSS3过渡是元素从一种样式逐渐改变为另一种样式的效果。 过渡属性-transition 值与说明 transition-property 必需,指定CSS属性的name,transition效果即哪个属性发生过渡。 transition-duration 必需,t…

YOLOv9改进策略:注意力机制 |通道注意力和空间注意力CBAM | GAM超越CBAM,不计成本提高精度

💡💡💡本文改进内容:通道注意力和空间注意力CBAM,全新注意力GAM:超越CBAM,不计成本提高精度 改进结构图如下: YOLOv9魔术师专栏 ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️…