1

我正在使用 Keil 的 ARM-MDK 4.11。我有一个静态分配的内存块,仅在启动时使用。它在调度程序初始化之前使用,并且由于 RL-RTX 控制堆管理的方式,不能动态分配(否则调度程序启动后的后续分配会导致硬故障)。

我想在调度程序初始化后将此静态块作为空闲块添加到系统堆中。似乎__Heap_ProvideMemory()可能会提供答案,这在初始化期间被调用以创建初始堆。但是,这需要了解堆描述符地址,并且我找不到任何记录的方法来获取它。

有任何想法吗?

我已经为此向 ARM/Keil 提出了支持请求,但他们更感兴趣的是质疑我为什么要这样做,并提供替代解决方案。我很清楚替代方案,但在这种情况下,如果可以做到这一点,那将是最干净的解决方案。

4

2 回答 2

1

我使用的一种方法是合并我自己的简单堆例程并从库中接管malloc()//函数calloc()free()

简单的自定义堆例程具有允许向堆中添加内存块的接口。

这样做的缺点(至少在我的情况下)是自定义堆例程远不如内置库例程复杂,并且可能比内置例程更容易产生碎片。在那个特定的应用程序中,这不是一个严重的问题。如果您想要内置库例程的功能,您可能会malloc()推迟到内置堆例程,直到它返回失败,然后尝试从您的自定义堆中分配。

另一个缺点是我发现确保自定义例程没有错误比我乍一看更痛苦,即使我并没有尝试做任何太花哨的事情(只是一个简单的空闲块列表可以在分配时拆分并在释放时合并)。

这种技术的一个好处是它非常可移植(只要您的自定义例程是可移植的)并且如果工具链改变它的内部结构也不会中断。唯一需要移植的部分是接管malloc()/free()接口并确保您足够早地初始化。

于 2010-12-02T15:46:20.003 回答
1

我们使用 Rowley Crossworks 编译器,但有一个类似的问题 - 在编译器 CRT 启动代码中设置了堆。不幸的是,直到 main() 开始,SDRAM 才被初始化,因此堆没有正确设置。在初始化 SDRAM 之后,我通过在 main() 开始时重新初始化堆来解决它。

我查看了编译器在启动时用来计算结构的汇编代码——这并不难。随后我还从 Rowley 获得了 malloc/free 源代码——也许你可以向 Keil 询问他们的版本?

于 2010-11-30T23:31:21.760 回答