OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7379|回复: 25

freertos内存管理问题,使用heap4的pvPortMalloc分配空间,两次过后出错

[复制链接]

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
发表于 2019-12-5 20:55:27 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 Moose 于 2019-12-5 21:24 编辑

是这样的,前面有个任务接收串口的信息,通过任务通知发送数据长度后再通过消息队列发送数据过来这个任务,这个任务能够接收到通知值,消息队列数据正常,但是使用pvPortMalloc分配空间,两次过后出错,有使用vPortFree函数释放内存了啊,怎么前两次正常打印,后面出错了。
Error:..\FreeRTOS\portable\MemMang\heap_4.c,320
Error:..\FreeRTOS\portable\MemMang\heap_4.c,321
void msgdel_task(void *pvParameters)
{
    static u8 *sendbuffer;
    static u8 len=0;
    BaseType_t err;
    while(1)
    {   //接收数据长度
        err = xTaskNotifyWait((uint32_t   ) 0x00,               //进入函数的时候不清除任务BIT
                        (uint32_t   ) ULONG_MAX,                //推出任务时清除所有BIT
                        (uint32_t * ) &len,                     //保存任务通知值
                        (TickType_t ) portMAX_DELAY );          //等待通知信息时间
        if(err==pdTRUE)
        {   
            sendbuffer=pvPortMalloc(len);                       //申请空间
            if(xQueueReceive( USART1_QUEUE, sendbuffer, portMAX_DELAY )!=pdTRUE)
            printf("消息队列接受失败!\r\n");
            printf("sendbuffer:%s\r\n",sendbuffer);
            vPortFree(sendbuffer);
        }


    }
}

最佳答案

查看完整内容[请看2#楼]

sendbuffer=pvPortMalloc(len); //申请空间 修改如下 sendbuffer=pvPortMalloc(USART_REC_LEN); //申请空间 不过你这又任务通知又队列 直接队列不就行了,多此一举
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-12-5 20:55:28 | 显示全部楼层
本帖最后由 nashui_sx 于 2019-12-14 16:53 编辑
Moose 发表于 2019-12-9 20:26
/* Check the block is actually allocated. */
                configASSERT( ( pxLink->xBlockSize & xBlockAllocat ...

            sendbuffer=pvPortMalloc(len);                       //申请空间
修改如下
           sendbuffer=pvPortMalloc(USART_REC_LEN);                       //申请空间

不过你这又任务通知又队列 直接队列不就行了,多此一举
回复

使用道具 举报

1

主题

882

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3071
金钱
3071
注册时间
2018-2-7
在线时间
285 小时
发表于 2019-12-6 11:14:38 | 显示全部楼层
是不是任务堆栈设置太小了
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-6 11:30:37 | 显示全部楼层
HXYDJ 发表于 2019-12-6 11:14
是不是任务堆栈设置太小了

不应该啊,它是前两次正常,那我申请了有释放啊,而且设置为256了,我串口发送就那十几个字节,不管我发多少都是前两次正常,后面出错,出错提示我没有申请空间。
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-6 11:31:27 | 显示全部楼层
HXYDJ 发表于 2019-12-6 11:14
是不是任务堆栈设置太小了

是我申请和释放的逻辑错了吗
回复

使用道具 举报

1

主题

882

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3071
金钱
3071
注册时间
2018-2-7
在线时间
285 小时
发表于 2019-12-6 11:36:34 | 显示全部楼层
Moose 发表于 2019-12-6 11:30
不应该啊,它是前两次正常,那我申请了有释放啊,而且设置为256了,我串口发送就那十几个字节,不管我发 ...

把任务中定义的静态变量改成动态变量看看
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-6 11:58:10 | 显示全部楼层
HXYDJ 发表于 2019-12-6 11:36
把任务中定义的静态变量改成动态变量看看

不行,还是一样,前两次正常打印出来,第三次出错了
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-12-6 18:12:13 | 显示全部楼层
最起码养成习惯,申请了判断一下吧  你这都不判断申请失败就用不太好
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-9 14:10:34 | 显示全部楼层
nashui_sx 发表于 2019-12-6 18:12
最起码养成习惯,申请了判断一下吧  你这都不判断申请失败就用不太好

void msgdel_task(void *pvParameters)
{
    u8 *sendbuffer;
    u8 len=0;
    BaseType_t err;
    while(1)
    {   //接收数据长度
        err = xTaskNotifyWait((uint32_t   ) 0x00,               //进入函数的时候不清除任务BIT
                        (uint32_t   ) ULONG_MAX,                //推出任务时清除所有BIT
                        (uint32_t * ) &len,                     //保存任务通知值
                        (TickType_t ) portMAX_DELAY );          //等待通知信息时间
        if(err==pdTRUE)
        {   
            sendbuffer=pvPortMalloc(len);                       //申请空间
            if(sendbuffer==NULL)
                printf("申请内存失败!\r\n");
            else
            {
                if(xQueueReceive( USART1_QUEUE, sendbuffer, portMAX_DELAY )!=pdTRUE)
                    printf("消息队列接受失败!\r\n");
                printf("sendbuffer:%s\r\n",sendbuffer);
                vPortFree(sendbuffer);
                sendbuffer=NULL;
            }
            
        }
        
    }
}
补了判断,没有提示申请失败,是我判断做错了吗?没有的话到底哪里出问题了

出错提示:
qwert                              //第一次发送
sendbuffer:qwert
           
qwerteryey                     //第二次发送
sendbuffer:qwerteryey

qwerteryeywetrwet        //第三次出错
sendbuffer:?
Error:..\FreeRTOS\portable\MemMang\heap_4.c,320
Error:..\FreeRTOS\portable\MemMang\heap_4.c,321
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-12-9 17:33:03 | 显示全部楼层
Moose 发表于 2019-12-9 14:10
void msgdel_task(void *pvParameters)
{
    u8 *sendbuffer;

贴出来你的版本的320  321 是哪个函数吧  这种情况不遇到过就看这是看不出来的
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-9 20:15:49 | 显示全部楼层
nashui_sx 发表于 2019-12-9 17:33
贴出来你的版本的320  321 是哪个函数吧  这种情况不遇到过就看这是看不出来的

/* Check the block is actually allocated. */
                configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
                configASSERT( pxLink->pxNextFreeBlock == NULL );

这两句,好像是检查内存空间有没被申请过的?     
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-9 20:20:24 | 显示全部楼层
贴上工程把,

练习项目.zip

13.8 MB, 下载次数: 35

回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-9 20:26:24 | 显示全部楼层
nashui_sx 发表于 2019-12-9 17:33
贴出来你的版本的320  321 是哪个函数吧  这种情况不遇到过就看这是看不出来的

/* Check the block is actually allocated. */
                configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
                configASSERT( pxLink->pxNextFreeBlock == NULL );
这两句呀,检查是否已经申请了空间的把,明明应该没申请失败的呀
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
11922
金钱
11922
注册时间
2015-11-5
在线时间
2086 小时
发表于 2019-12-14 14:02:32 | 显示全部楼层
申请内存的时候记下内存起始地址,看释放的时候是否也是这个地址,不是的话内存应该是溢出了
拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-14 17:49:43 | 显示全部楼层
nashui_sx 发表于 2019-12-14 15:52
sendbuffer=pvPortMalloc(len);                       //申请空间
修改如下
           s ...

想着能多用就多用嘛,练习函数嘛
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-12-14 17:53:05 | 显示全部楼层
本帖最后由 nashui_sx 于 2019-12-14 18:00 编辑
Moose 发表于 2019-12-14 17:49
想着能多用就多用嘛,练习函数嘛

好吧,别练入歧途以后也这么写就好了  队列想带长度传结构体到队列就好了,结构体包含长度和数据
或者xMessageBuffer最好

你那个按我说的改下就好了
还有你的freertos优先级最大值应该是16个吧  不是32


回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-15 14:41:20 | 显示全部楼层
nashui_sx 发表于 2019-12-14 17:53
好吧,别练入歧途以后也这么写就好了  队列想带长度传结构体到队列就好了,结构体包含长度和数据
或者xM ...

好的谢谢       我的是中断优先是16嘛,任务优先有32嘛
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-15 14:42:01 | 显示全部楼层
FreeRTOS 发表于 2019-12-14 14:02
申请内存的时候记下内存起始地址,看释放的时候是否也是这个地址,不是的话内存应该是溢出了

好的好的
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2019-12-19
在线时间
2 小时
发表于 2019-12-19 15:47:49 | 显示全部楼层
申请,你的len变量定义是有问题的,传数据的指针是32位的,你定义的是8位的变量,那么程序的空间就会有字节被擦写,你要查一下,被擦写的内容就知道了。你这个问题就好像数据越界一样。
回复

使用道具 举报

14

主题

57

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-11-15
在线时间
40 小时
 楼主| 发表于 2019-12-19 16:09:18 | 显示全部楼层
chenyang601 发表于 2019-12-19 15:47
申请,你的len变量定义是有问题的,传数据的指针是32位的,你定义的是8位的变量,那么程序的空间就会有字节 ...

哇    一语中的    我还以为之前是什么问题,谢谢大佬
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-12-19 22:20:45 | 显示全部楼层
Moose 发表于 2019-12-19 16:09
哇    一语中的    我还以为之前是什么问题,谢谢大佬

u8强制u16没问题


你的队列单个长度是USART_REC_LEN  你用len<=USART_REC_LEN 去装队列肯定装不下
sendbuffer=pvPortMalloc(len);                       //申请空间
修改如下
sendbuffer=pvPortMalloc(USART_REC_LEN);                       //申请空间

不信你每次发送USART_REC_LEN长度个数据就没问题吧
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-12-19 22:37:46 | 显示全部楼层
Moose 发表于 2019-12-19 16:09
哇    一语中的    我还以为之前是什么问题,谢谢大佬

xQueueReceive必须一次把设定的队列长度全部读出来你要想变长度读取 用MessageBuffer就好了
回复

使用道具 举报

2

主题

474

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6077
金钱
6077
注册时间
2018-6-27
在线时间
524 小时
发表于 2021-5-27 18:05:19 | 显示全部楼层
学习学习,学习学习。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表