freeRTOS中堆栈问题

在freeRTOS中的内存泄漏问题

1、情景描述:

​ 在我的某个STM32项目当中,同时有三个采集任务在采集不同的传感器,采集到一定数量,就会通过消息队列的方式将数据传递到发送任务当中,发送任务接收后将数据写入到SD卡当中。传递的数据结构体如下所示:(暂且叫采集任务为TX,发送任务为RX,这里的TXRX是相对消息队列的走向而言)

typedef struct {
    uint8_t * data;
	uint32_t len;
}data_struct;

​ 显然,我传的是一个名为data的指针,所以需要在TX当中申请一片内存,接着在RX中处理并释放。

//TX采集任务
while(1)
{
    ......
    //申请内存
    msg_sd.data = pvPortMalloc(len_of_send);
    
    //写队列
	osStatus_t status_SD = osMessageQueuePut(SDquereHandle, &msg_sd, 0, osWaitForever);
}

//RX发送任务
//获取SD卡状态
while(1)
{
    ......
    //读队列
    osStatus_t status = osMessageQueueGet(SDquereHandle, &msg, NULL, osWaitForever);
    
    //写SD卡
	SDwrite(xxxx);
    
    //释放
	vPortFree(msg.data); // 释放内存
    ......
}

​ 已知我的堆内存大约是20000字节,且RX的任务优先级高于所有的采集任务TX。所以理论上来说这样子做是不会有什么问题的。

但是实际上,当我运行了7到8个小时后,我的堆内存会在某个时间点断崖式下降

请添加图片描述

2、分析

(一)是否存在持续的内存泄漏

显然,断崖式下降并不是长时间的泄漏引起的,所以排除。

(二)是否是释放不及时导致

从现象来看,确实可能是释放不及时,因为在RX中做了文件读写的操作,在7到8个小时连续读写的情况下,文件大小也到了600M左右,文件越大,写入的时间越长。那么在文件写入的函数(f_write)中阻塞的时间就越长。而在freeRTOS中,文件写入的阻塞是指挂起当前的任务,也就是挂起当前的发送任务,这时我们的采集任务就可以继续运行了,如果在这段时间内,采集任务又向消息队列中加入数据,而我们的发送任务来不及释放就会造成内存泄漏。

3、解决方法

文件写入到一定大小就创建一个新的文件继续写入,保证写消息队列的数据小于读消息队列的数据,这样内存就不会泄漏了。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值