在Micrium的uC / OS-III RTOS中的Malloc

时间:2012-05-15 12:44:35

标签: c memory-management malloc rtos micrium

我们正在使用Micrium的uC / OS-III RTOS。 我们正在尝试在RTOS上返回malloc的值。 当我们在RTOS启动之前做一个99999的malloc(太多的RAM)时,我们得到一个空指针,这是我们所期望的。

当我们在启动RTOS和任务时执行相同的malloc时,我们不会返回空指针,这是我们不期望的。 尽管如此,系统确实会冻结。

有没有人对此有解释?

提前致谢

编辑:

有关信息:我们正在使用Renesas的RX62N微控制器和GNURX编译器

该程序实际上并未冻结。程序'认为'它获得一个有用的指针(不是NULL指针),并继续运行。在某一点上,程序将其程序计数器更改为00000000并停止。所以它没有进入异常,因此我们无法抓住它。

但是,在RTOS启动之前和启动RTOS时调用 malloc 会有所不同。区别在于 malloc 的真正深度汇编代码。

在某一点上执行以下指令

CMP         R1,R7
BGTU.B      0FFF802C0H
ADD         R14,R7

当我们尝试分配太多RAM时, BGTU.B 指令不应该分支,然后程序继续执行 ADD 指令。这在启动RTOS之前执行 malloc 时非常有效,而在之后执行时则失败。

These are the values I get in several cases

Outside RTOS (allocable number: 10)
R1: 00008348
R7: 00000014

Outside RTOS (not allocable number: 9999)
R1: 00008348
R7: 00002718

Inside RTOS (allocable number: 10)
R1: FFFFF9D0
R7: 00000014

Inside RTOS (not allocable number: 9999)
R1: FFFFF9D0
R7: 00002718

我希望整个情况都很明确,我试着尽可能地解释它:P

提前致谢

2 个答案:

答案 0 :(得分:0)

除了插图案例中的第二种情况外,R7似乎包含分配的大小(请求的大小+对齐+堆管理数据)。直观地,R7 = 0x2718将对应于999字节的分配,因此我怀疑这可能是一个错字。

R1我猜想包含内存将被分配的堆块的大小,因为那样CMP就有意义了。如果块不够大,它将失败。

然而,当RTOS运行时,R1中的值变得非常大,显然不正确。如果您的堆损坏,可能会发生这种情况。如果超出堆上分配的缓冲区,则会发生这种情况。如果从堆中分配线程堆栈,并且堆栈太小,则会产生相同的效果。您的线程堆栈必须足够大,以适应最坏情况的调用堆栈,以及RTOS支持上下文切换所需的任何内容。即使您没有从堆中分配堆栈,如果线程堆栈与堆内存相邻,堆栈溢出也可能具有相同的效果。

堆可能被破坏的另一种方法是在多个线程中同时执行分配或释放,而不强制执行互斥或关键部分。标准库堆管理不太可能是线程安全的,除非您已经进行了必要的修改以将其与RTOS集成 - 如果RTOS和标准库来自同一供应商(例如,如果两者都提供的话)可能就是这种情况用编译器。)

答案 1 :(得分:0)

我们发现在UCOS-III操作系统启动之前调用malloc时工作正常。从线程调用时,它会失败并返回NULL指针。我怀疑这是由于对堆栈的检查,当在一个可以任意放置堆栈的线程中运行时当然无效。 我可以在地图文件中看到该库指的是特定的sbrk(lib_a-sbrk.o)函数,我无法找到该函数的任何来源。 众所周知,默认的GNU sbrk函数将检查当前堆栈指针,以查看当前中断是否超出SP并失败。

不幸的是我们必须依赖malloc,因为我们使用复杂的C ++库,因为我们有几兆字节的内存而不关心碎片,我们只想让malloc工作。我们实际上甚至不关心重入,因为我们只在单个线程中使用malloc。

是否有可能阐明如何在库中实现堆函数。我们正在使用ARM-9芯片。