Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
dfs_elm.c 的严重问题
发布于 2016-06-14 09:56:55 浏览:3288
订阅该版
先使用: ```dfs_elm_open dfs_elm_read dfs_elm_close``` 打开,读取文件都正常。 然后再次使用: dfs_elm_open 就出错, 在dfs_elm_open函数中的: ``` /* allocate a fd */ fd = (FIL *)rt_malloc(sizeof(FIL)); if (fd == RT_NULL) { #if _VOLUMES > 1 rt_free(drivers_fn); #endif return -DFS_STATUS_ENOMEM; //调试发现,打开失败,跳转到了这里 }``` 出现了错误 如果不使用下面这个组合: 先使用: ```dfs_elm_open dfs_elm_read dfs_elm_close``` 则dfs_elm_open和dfs_elm_write都正常。 这个是什么问题,大家有遇到过吗?
查看更多
9
个回答
默认排序
按发布时间排序
aozima
2016-06-14
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
``` dfs_elm_open dfs_elm_read dfs_elm_close ``` 都不是给用户使用的,给用户使用的是 dfs_file_open等。 或封装后posix兼容的open/read/close malloc失败先检查可用内存及内存泄露问题。
pigeon0411
2016-06-14
这家伙很懒,什么也没写!
>``` >dfs_elm_open >dfs_elm_read >dfs_elm_close >``` > > > >都不是给用户使用的,给用户使用的是 dfs_file_open等。 >或封装后posix兼容的open/read/close > >malloc失败先检查可用内存及内存泄露问题。 --- 我实际使用的是封装后posix兼容的open/read/close,为了方便说明问题,就把实际调用的上面的函数列出来了。 我最初也怀疑是内存不够的问题,换了大内存的芯片测试还是一样的问题,查看可用内存还有30多KB。
pigeon0411
2016-06-14
这家伙很懒,什么也没写!
另外针对rt_malloc这个函数,我发现在mem.c 和 Slab.c还有Memheap.c文件中都有定义,到底哪个文件里面的更稳定呢? dfs系统调用的是mem.c中的rt_malloc函数。 dfs_elm_open在第二次调用下面的函数时,出现了指针值异常。 ``` void *rt_malloc(rt_size_t size) { rt_size_t ptr, ptr2; struct heap_mem *mem, *mem2; RT_DEBUG_NOT_IN_INTERRUPT; if (size == 0) return RT_NULL; if (size != RT_ALIGN(size, RT_ALIGN_SIZE)) RT_DEBUG_LOG(RT_DEBUG_MEM, ("malloc size %d, but align to %d ", size, RT_ALIGN(size, RT_ALIGN_SIZE))); else RT_DEBUG_LOG(RT_DEBUG_MEM, ("malloc size %d ", size)); /* alignment size */ size = RT_ALIGN(size, RT_ALIGN_SIZE); if (size > mem_size_aligned) { RT_DEBUG_LOG(RT_DEBUG_MEM, ("no memory ")); return RT_NULL; } /* every data block must be at least MIN_SIZE_ALIGNED long */ if (size < MIN_SIZE_ALIGNED) size = MIN_SIZE_ALIGNED; /* take memory semaphore */ rt_sem_take(&heap_sem, RT_WAITING_FOREVER); for (ptr = (rt_uint8_t *)lfree - heap_ptr; ptr < mem_size_aligned - size; ptr = ((struct heap_mem *)&heap_ptr[ptr])->next) //********** 这个地方出现了ptr异常,超出了有效范围******* { mem = (struct heap_mem *)&heap_ptr[ptr]; if ((!mem->used) && (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { /* mem is not used and at least perfect fit is possible: * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { /* (in addition to the above, we test if another struct heap_mem (SIZEOF_STRUCT_MEM) containing * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') * -> split large block, create empty remainder, * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, * struct heap_mem would fit in but no data between mem2 and mem2->next * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty * region that couldn't hold data, but when mem->next gets freed, * the 2 regions would be combined, resulting in more free memory */ ptr2 = ptr + SIZEOF_STRUCT_MEM + size; /* create mem2 struct */ mem2 = (struct heap_mem *)&heap_ptr[ptr2]; mem2->used = 0; mem2->next = mem->next; mem2->prev = ptr; /* and insert it between mem and mem->next */ mem->next = ptr2; mem->used = 1; if (mem2->next != mem_size_aligned + SIZEOF_STRUCT_MEM) { ((struct heap_mem *)&heap_ptr[mem2->next])->prev = ptr2; } #ifdef RT_MEM_STATS used_mem += (size + SIZEOF_STRUCT_MEM); if (max_mem < used_mem) max_mem = used_mem; #endif } else { /* (a mem2 struct does no fit into the user data space of mem and mem->next will always * be used at this point: if not we have 2 unused structs in a row, plug_holes should have * take care of this). * -> near fit or excact fit: do not split, no mem2 creation * also can't move mem->next directly behind mem, since mem->next * will always be used at this point! */ mem->used = 1; #ifdef RT_MEM_STATS used_mem += mem->next - ((rt_uint8_t*)mem - heap_ptr); if (max_mem < used_mem) max_mem = used_mem; #endif } /* set memory block magic */ mem->magic = HEAP_MAGIC; if (mem == lfree) { /* Find next free block after mem and update lowest free pointer */ while (lfree->used && lfree != heap_end) lfree = (struct heap_mem *)&heap_ptr[lfree->next]; RT_ASSERT(((lfree == heap_end) || (!lfree->used))); } rt_sem_release(&heap_sem); RT_ASSERT((rt_uint32_t)mem + SIZEOF_STRUCT_MEM + size <= (rt_uint32_t)heap_end); RT_ASSERT((rt_uint32_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM) % RT_ALIGN_SIZE == 0); RT_ASSERT((((rt_uint32_t)mem) & (RT_ALIGN_SIZE-1)) == 0); RT_DEBUG_LOG(RT_DEBUG_MEM, ("allocate memory at 0x%x, size: %d ", (rt_uint32_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM), (rt_uint32_t)(mem->next - ((rt_uint8_t *)mem - heap_ptr)))); RT_OBJECT_HOOK_CALL(rt_malloc_hook, (((void *)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM)), size)); /* return the memory data except mem struct */ return (rt_uint8_t *)mem + SIZEOF_STRUCT_MEM; } } rt_sem_release(&heap_sem); return RT_NULL; } ```
bernard
2016-06-14
这家伙很懒,什么也没写!
这个是一个常用的序列,出问题的可能性很小。 所以如果是这样,需要你先把自己的使用情况说明白: 1. 芯片;编译器; 2. 内存分布; 3. 使用用法。
grissiom
2016-06-14
这家伙很懒,什么也没写!
缓冲区溢出把内存写坏了,检查自己的代码~
aozima
2016-06-15
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
不会是使用了4K扇区的FLASH作文件系统,而没有改大配置吧 ``` #define RT_DFS_ELM_MAX_SECTOR_SIZE (4096) ```
bernard
2016-06-15
这家伙很懒,什么也没写!
这种就是各种猜,而且还是大家下面帮楼主猜谜
pigeon0411
2016-06-15
这家伙很懒,什么也没写!
问题已经解决了:增加了线程初始时的堆栈空间大小。 一般情况下,如果线程的堆栈空间不够时,在finsh中会有警告等提示,而调试这个文件系统时,不知道为什么刚好没有提示,所以理所当然地认为堆栈大小应该没问题。 结果最后还是修改了堆栈大小,然后就没出现内存分配的问题了。
撰写答案
登录
注册新账号
关注者
0
被浏览
3.3k
关于作者
pigeon0411
这家伙很懒,什么也没写!
提问
18
回答
25
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【RT-Thread】【ci】【scons】将ci.attachconfig.yml和scons结合使用
2
Rt-thread中OTA下载后,bootloader不搬程序
3
ulog 日志 LOG_HEX 输出时间改为本地日期时间
4
在RT-Thread Studio中构建前执行python命令
5
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1518
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
5
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部