【沁恒蓝牙MESH】CH582串口中断内存溢出导致MCU频繁重启

本文主要是介绍【沁恒蓝牙MESH】CH582串口中断内存溢出导致MCU频繁重启,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文主要记录了【沁恒蓝牙mesh】CH582串口中断内存溢出导致MCU频繁重启
由于开发疏忽,导致的数组内存溢出,是入门嵌入式开发经常忽视的错误,用以记录,共勉!!

目录

  • 1. 遇到问题描述以及解决
    • 1.1 问题一:串口中断导致MCU频繁重启
      • 1.1.1【场景描述】
      • 1.1.2 【问题描述】
      • 1.1.3 【问题定位】
      • 1.1.4 【问题解决】

  • 💖 作者简介:大家好,我是喜欢记录零碎知识点的小菜鸟。😎
  • 📝 个人主页:欢迎访问我的 Ethernet_Comm 博客主页🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:沁恒蓝牙mesh二次开发🍁
  • 💬格言:写文档啊不是写文章,重要的还是直白!🔥

1. 遇到问题描述以及解决

1.1 问题一:串口中断导致MCU频繁重启

1.1.1【场景描述】

硬件:沁恒的 CH582F 单片机, 海凌科 24G 雷达模组

引脚:海凌科雷达模组5个引脚和 CH582F 连,单片机PB4引脚(普通GPIO,下拉输入,采用IO查询的方式判断电平)

CH582F雷达模组
5vvcc
gndgnd
PB4out
RX3—PA4tx
RX3—PA5rx

1.1.2 【问题描述】

烧录程序后,发现 单片机一直 周期性的重启。。。。下图左侧为串口3的接受中断
在这里插入图片描述

1.1.3 【问题定位】

雷达:每间隔100ms 从TX引脚输出的数据为

[2023-12-01 07:58:27.167]# RECV HEX>
F4 F3 F2 F1 0D 00 02 AA 03 1E 00 5A 1E 00 64 00 00 55 00 F8 F7 F6 F5 
[2023-12-01 07:58:27.267]# RECV HEX>
F4 F3 F2 F1 0D 00 02 AA 03 1E 00 64 1E 00 64 00 00 55 00 F8 F7 F6 F5 
[2023-12-01 07:58:27.367]# RECV HEX>
F4 F3 F2 F1 0D 00 02 AA 03 1E 00 64 1E 00 64 00 00 55 00 F8 F7 F6 F5 
[2023-12-01 07:58:27.469]# RECV HEX>
F4 F3 F2 F1 0D 00 02 AA 03 1E 00 64 1E 00 64 00 00 55 00 F8 F7 F6 F5 
[2023-12-01 07:58:27.562]# RECV HEX>
F4 F3 F2 F1 0D 00 02 AA 03 1E 00 64 1E 00 64 00 00 55 00 F8 F7 F6 F5 

将雷达模组拿掉,程序就正常了,因此一个个引脚查问题,最终定位问题为:

软件中开启了串口3的接收中断,雷达模组频繁的发送数据导致单片机频繁进入中断,造成重启

检查软件中的中断咋写的,,,,,

1.1.4 【问题解决】

曾经在ESP32 开发中翻过这样一个错误:【esp32】解决以太网+mqtt堆栈溢出问题 报错 no mem for receive buffer,这个是由于动态申请的内存没有是释放导致栈空间不足,MCU反复重启

数组溢出导致的栈内存被冲刷掉,导致内存溢出而使得MCU重启

问题定位如下, 我的软件串口接收中断竟然是这么写的::::::令人发指!!!!

串口中断将接收到的数据存储到 uart_rx_buffer[]数组中, 但是,,我定义了一个 100 大小的数组,却 user_rx_buffer_write_index & user_rx_buffer_length_mask 去接收数据。。。。

本意是这样的 定义一个 1024 大小的数组,每接收到一个自己 user_rx_buffer_write_index 自加1,然后通过 user_rx_buffer_write_index & user_rx_buffer_length_mask 将范围限制在 1-1024 范围内,防止数组溢出。。。。当时应该是担心占用内存太大,手动将uart_rx_buffer[1024]改为了 uart_rx_buffer[100],但是忘记修改 user_rx_buffer_length_mask变量的值了。。

造成的结果就是,我定义了100维的数组,缺往里边存了 最大1024个字节,那剩下的900字节空间就把其他栈空间占用了,,冲掉了哪些变量的值???不得而知,但是造成的结果就是单片机不断重启了。。。。。。。。

解决方式:

将数组改为 1024 维的,或者数组100维不变,将掩码的值改为99,别造成内存溢出,就可以了,

实测修改后,就不会重启了

uint8_t uart_rx_buffer[100]={0}; 
uint16_t user_rx_buffer_length_mask = 1024-1;
uint16_t user_rx_buffer_write_index = 0;
uint8_t trigB = 7 ;
uint8_t uart_rx_done = 0;__INTERRUPT
__HIGH_CODE
void UART3_IRQHandler(void)
{uint16_t error;int i = 0;switch(UART3_GetITFlag()){case UART_II_LINE_STAT:  // 线路状态错误UART3_GetLinSTA();break;case UART_II_RECV_RDY: // 数据达到设置触发点while( R8_UART3_RFC > 1) {  // 这个方式必须保证uart的接收触发中断是大于1字节的uart_rx_buffer[user_rx_buffer_write_index & user_rx_buffer_length_mask] = R8_UART3_RBR;user_rx_buffer_write_index += 1;}break;case UART_II_RECV_TOUT: // 接收超时,暂时一帧数据接收完成for(i = 0; i < R8_UART3_RFC; i++){iRxBuff[i] = UART3_RecvByte();//UART3_SendByte(iRxBuff[i]);}  break;case UART_II_THR_EMPTY:break;case UART_II_MODEM_CHG:break;default:break;}
}

知识点:

当 b = 2^n 的时候:a % b = a & (b-1)

这篇关于【沁恒蓝牙MESH】CH582串口中断内存溢出导致MCU频繁重启的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/444225

相关文章

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

沁恒CH32在MounRiver Studio上环境配置以及使用详细教程

目录 1.  RISC-V简介 2.  CPU架构现状 3.  MounRiver Studio软件下载 4.  MounRiver Studio软件安装 5.  MounRiver Studio软件介绍 6.  创建工程 7.  编译代码 1.  RISC-V简介         RISC就是精简指令集计算机(Reduced Instruction SetCom

JVM内存调优原则及几种JVM内存调优方法

JVM内存调优原则及几种JVM内存调优方法 1、堆大小设置。 2、回收器选择。   1、在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。   2、对JVM内存的系统级的调优主要的目的是减少

JVM 常见异常及内存诊断

栈内存溢出 栈内存大小设置:-Xss size 默认除了window以外的所有操作系统默认情况大小为 1MB,window 的默认大小依赖于虚拟机内存。 栈帧过多导致栈内存溢出 下述示例代码,由于递归深度没有限制且没有设置出口,每次方法的调用都会产生一个栈帧导致了创建的栈帧过多,而导致内存溢出(StackOverflowError)。 示例代码: 运行结果: 栈帧过大导致栈内存

理解java虚拟机内存收集

学习《深入理解Java虚拟机》时个人的理解笔记 1、为什么要去了解垃圾收集和内存回收技术? 当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些“自动化”的技术实施必要的监控和调节。 2、“哲学三问”内存收集 what?when?how? 那些内存需要回收?什么时候回收?如何回收? 这是一个整体的问题,确定了什么状态的内存可以

NGINX轻松管理10万长连接 --- 基于2GB内存的CentOS 6.5 x86-64

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=190176&id=4234854 一 前言 当管理大量连接时,特别是只有少量活跃连接,NGINX有比较好的CPU和RAM利用率,如今是多终端保持在线的时代,更能让NGINX发挥这个优点。本文做一个简单测试,NGINX在一个普通PC虚拟机上维护100k的HTTP

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

PHP原理之内存管理中难懂的几个点

PHP的内存管理, 分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理. 而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等. 另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法. 而在我们