【沁恒蓝牙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

相关文章

GO语言实现串口简单通讯

《GO语言实现串口简单通讯》本文分享了使用Go语言进行串口通讯的实践过程,详细介绍了串口配置、数据发送与接收的代码实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录背景串口通讯代码代码块分解解析完整代码运行结果背景最近再学习 go 语言,在某宝用5块钱买了个

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

Oracle数据库在windows系统上重启步骤

《Oracle数据库在windows系统上重启步骤》有时候在服务中重启了oracle之后,数据库并不能正常访问,下面:本文主要介绍Oracle数据库在windows系统上重启的相关资料,文中通过代... oracle数据库在Windows上重启的方法我这里是使用oracle自带的sqlplus工具实现的方

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变