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

标签 c memory-management malloc rtos micrium

我们使用的是 Micrium 的 uC/OS-III 实时操作系统。 我们正在尝试在 RTOS 上返回 malloc 的值。 当我们在 RTOS 启动之前执行 99999 的 malloc(对于 RAM 来说太多)时,我们得到一个空指针,这正是我们所期望的。

当我们在 RTOS 启动时和在任务中执行相同的 malloc 时,我们没有得到空指针,这是我们不希望的。 不过,此时系统确实卡住了。

有人对此有解释吗?

提前致谢

编辑:

信息:我们使用的是 Renesas 的 RX62N 微 Controller 和 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

提前致谢

最佳答案

除了示例中的第二种情况,R7 似乎都包含分配的大小(请求的大小 + 对齐方式 + 堆管理数据)。直觉上 R7=0x2718 对应于 999 字节的分配,所以我怀疑这可能是一个错字。

我猜 R1 包含将分配内存的堆 block 的大小,从那时起 CMP 就有意义了。如果 block 不够大,它将失败。

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

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

关于c - Micrium 的 uC/OS-III RTOS 中的 Malloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10600942/

相关文章:

c++ - 为什么 malloc() 分配的内存比要求的多,我如何禁止 malloc 在 Mac OS X 中执行此操作?

c - 在客户端-服务器程序中如何传递十六进制值

c - 内存在二维数组中的位置?

c - TCP/IP : message got by recv() in order without keep buffer

c++ - 通过引用传递与通过指针传递时对象的范围

c - c中malloc之后的默认值是多少?

c - XML -> C 解析器生成器

iphone - 我必须在 Instruments 应用程序和 ObjectAlloc 中查看哪些指标,才能确定我的应用程序中是否存在内存泄漏?

objective-c - -performSelector :onThread:withObject:waitUntilDone: 的内存问题

c - 如何在 C 中迭代内存块(使用 malloc 创建)?