OpenEdv-开源电子网

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

FreeRTOS vPortFree() 内存释放异常 求助

[复制链接]

6

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
146
金钱
146
注册时间
2016-11-4
在线时间
27 小时
发表于 2017-8-29 11:13:54 | 显示全部楼层 |阅读模式
10金钱
STM32F103VC 移植FreeRTOS+FATFS一直运行都挺正常的,由于需要使用文件系统和字库.所以移植了原子哥的SPI flash 代码;
SPI Flash  W25QXX_Write() 写函数因为需要使用到一个 4k 的buf做数据暂存;为了使用方便引用了FreeRTOS 的 heap_4 内存管理方式;
pvPortMalloc(); 申请内存
vPortFree(); 释放内存
问题描述:
    初始化过程中从SD卡拷贝字库到SPI flash 前段都顺利通过,字库文件顺利写入也成功正常;退出字库更新函数的时候问题来了,此时还没有开始创建FreeRTOS任务.
FreeRTOS 断言函数  configASSERT(x)  通过串口输出:
FreeRTOS Error:..\FreeRTOS\portable\MemMang\heap_4.c,320
FreeRTOS Error:..\FreeRTOS\portable\MemMang\heap_4.c,321


红色部分; 琢磨了好久硬是不知道那里出错了;希望有高手指点一下.

void vPortFree( void *pv )   //heap_4 内存释放函数
{
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;

        if( pv != NULL )
        {
                /* The memory being freed will have an BlockLink_t structure immediately
                before it. */
                puc -= xHeapStructSize;

                /* This casting is to keep the compiler from issuing warnings. */
                pxLink = ( void * ) puc;

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



最佳答案

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

确实如你所说; //更新字体文件,UNIGBK,GBK12,GBK16,GBK24一起更新 //x,y:提示信息的显示地址 //size:字体大小 //src:字库来源磁盘."0:",SD卡;"1:",FLASH盘,"2:",U盘. //提示信息字体大小 //返回值:0,更新成功; // 其他,错误代码. u8 update_font(u16 x,u16 y,u8 size,u8* src) { u8 *p ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
146
金钱
146
注册时间
2016-11-4
在线时间
27 小时
 楼主| 发表于 2017-8-29 11:13:55 | 显示全部楼层
本帖最后由 wuhuigps 于 2017-8-29 13:59 编辑
zuozhongkai 发表于 2017-8-29 11:41
有可能释放了一个没有申请的内存块

确实如你所说;
//更新字体文件,UNIGBK,GBK12,GBK16,GBK24一起更新
//x,y:提示信息的显示地址
//size:字体大小
//src:字库来源磁盘."0:",SD卡;"1:",FLASH盘,"2:",U盘.
//提示信息字体大小                                                                                 
//返回值:0,更新成功;
//                 其他,错误代码.         
u8 update_font(u16 x,u16 y,u8 size,u8* src)
{        
        u8 *pname;
        u32 *buf;
        u8 res=0;                  
         u16 i,j;
        FIL *fftemp;
        u8 rval=0;
        res=0XFF;               
        ftinfo.fontok=0XFF;
        pname=mymalloc(SRAMIN,100);        //申请100字节内存  
        buf=mymalloc(SRAMIN,4096);        //申请4K字节内存  
        fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL));        //分配内存        
        if(buf==NULL||pname==NULL||fftemp==NULL)
        {
                myfree(SRAMIN,fftemp);
                myfree(SRAMIN,pname);
                myfree(SRAMIN,buf);
                return 5;        //内存申请失败
        }
        //先查找文件是否正常
        strcpy((char*)pname,(char*)src);        //copy src内容到pname
        strcat((char*)pname,(char*)UNIGBK_PATH);
         res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
         if(res)rval|=1<<4;//打开文件失败  
        strcpy((char*)pname,(char*)src);        //copy src内容到pname
        strcat((char*)pname,(char*)GBK12_PATH);
         res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
         if(res)rval|=1<<5;//打开文件失败  
        strcpy((char*)pname,(char*)src);        //copy src内容到pname
        strcat((char*)pname,(char*)GBK16_PATH);
         res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
         if(res)rval|=1<<6;//打开文件失败  
        strcpy((char*)pname,(char*)src);        //copy src内容到pname
        strcat((char*)pname,(char*)GBK24_PATH);
         res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
         if(res)rval|=1<<7;//打开文件失败   
        myfree(SRAMIN,fftemp);//释放内存
        if(rval==0)//字库文件都存在.
        {  
                LCD_ShowString(x,y,240,320,size,"Erasing sectors... ");//提示正在擦除扇区        
                for(i=0;i<FONTSECSIZE;i++)        //先擦除字库区域,提高写入速度
                {
                        fupd_prog(x+20*size/2,y,size,FONTSECSIZE,i);//进度显示
                        W25QXX_Read((u8*)buf,((FONTINFOADDR/4096)+i)*4096,4096);//读出整个扇区的内容
                        for(j=0;j<1024;j++)//校验数据
                        {
                                if(buf[j]!=0XFFFFFFFF)break;//需要擦除            
                        }
                        if(j!=1024)W25QXX_Erase_Sector((FONTINFOADDR/4096)+i);        //需要擦除的扇区
                }
                myfree(SRAMIN,buf);
                LCD_ShowString(x,y,240,320,size,"Updating UNIGBK.BIN");               
                strcpy((char*)pname,(char*)src);                                //copy src内容到pname
                strcat((char*)pname,(char*)UNIGBK_PATH);
                res=updata_fontx(x+20*size/2,y,size,pname,0);        //更新UNIGBK.BIN
                if(res){myfree(SRAMIN,pname);return 1;}
                LCD_ShowString(x,y,240,320,size,"Updating GBK12.BIN  ");
                strcpy((char*)pname,(char*)src);                                //copy src内容到pname
                strcat((char*)pname,(char*)GBK12_PATH);
                res=updata_fontx(x+20*size/2,y,size,pname,1);        //更新GBK12.FON
                if(res){myfree(SRAMIN,pname);return 2;}
                LCD_ShowString(x,y,240,320,size,"Updating GBK16.BIN  ");
                strcpy((char*)pname,(char*)src);                                //copy src内容到pname
                strcat((char*)pname,(char*)GBK16_PATH);
                res=updata_fontx(x+20*size/2,y,size,pname,2);        //更新GBK16.FON
                if(res){myfree(SRAMIN,pname);return 3;}
                LCD_ShowString(x,y,240,320,size,"Updating GBK24.BIN  ");
                strcpy((char*)pname,(char*)src);                                //copy src内容到pname
                strcat((char*)pname,(char*)GBK24_PATH);
                res=updata_fontx(x+20*size/2,y,size,pname,3);        //更新GBK24.FON
                if(res){myfree(SRAMIN,pname);return 4;}
                //全部更新好了
                ftinfo.fontok=0XAA;
                W25QXX_Write((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo));        //保存字库信息
        }
        myfree(SRAMIN,pname);//释放内存
        myfree(SRAMIN,buf);
        return rval;//无错误.                        
}
原子哥的代码 buf 被释放了2次.移植到FreeRTOS的时候正好出现更新完字库后提示错误
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2017-8-29 11:41:34 | 显示全部楼层
有可能释放了一个没有申请的内存块
回复

使用道具 举报

2

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2018-4-29
在线时间
21 小时
发表于 2018-7-27 21:02:23 | 显示全部楼层
我也遇到了这个问题,我的内存是申请过的
[mw_shl_code=c,true]t = pvPortMalloc(256);
                                printf("point(t) = %p\r\n", t);
                                sprintf(t, "%s:%s", serverhost, serverport);                                                                                        // Cache Host
                                content = pvPortMalloc(256);
                                sprintf(content, GET, p, t);
                                printf("%s\r\n", content);
                                esp8266_send_data((u8*)content, (u8*)"200 OK", 400);
                                // printf("%s\r\n", USART3_RX_BUF);
                                t = strstr((char*)USART3_RX_BUF, "{");
                                switchUtf8ToGbk(t, content);
                                vPortFree(t);
                                t = NULL;[/mw_shl_code]
1.PNG
回复

使用道具 举报

2

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2018-4-29
在线时间
21 小时
发表于 2018-7-27 21:03:19 | 显示全部楼层
现在还不知道是什么原因
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2019-7-17
在线时间
5 小时
发表于 2020-9-30 16:20:17 | 显示全部楼层
轩辕文 发表于 2018-7-27 21:03
现在还不知道是什么原因

最后解决了嘛?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

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

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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