防止为嵌入式项目编译 malloc/free

发布于 2024-11-28 08:42:58 字数 1981 浏览 0 评论 0原文

背景:我们正在使用 Keil 编译 NXP LPC2458 项目。 Keil 的 RealView RTOS 上运行着许多任务。创建了堆栈空间,并将其分配给每个任务。默认情况下没有创建堆,我想避免它,因为我们无法承担代码空间开销和“垃圾收集”的成本

目标:在嵌入式代码中使用 C++,而不使用堆。 Keil 提供了 #pragma (__use_no_heap),它可以防止链接 malloc() 和 free() 调用。

解决方案:我尝试使用私有静态指针创建单例。我希望 new() 不会被调用,因为我在 getDLMData() 中将 dlmData 声明为静态。由于某种原因,链接器仍然声明正在调用 malloc() 和 free()。我想到了私有运算符 new () 和私有运算符 delete() ,然后在重载函数中将 dlmData 声明为静态。由于某种原因它不起作用。我做错了什么?

    //class declaration
    class DataLogMaintenanceData
    {
    public:
      static DataLogMaintenanceData* getDLMData();
      ~DataLogMaintenanceData()
      { instanceFlag = FALSE; }
    protected:
      DataLogMaintenaceData(); //constructor declared protected to avoid poly
    private:
      static Boolean instanceFlag;
      static DataLogMaintenceData *DLMData;
    }

    //set these to NULL when the code is first started
    Boolean DataLogMaintenanceData::instanceFlag = FALSE;
    DataLogMaintenanceData *DataLogMaintenaceData::DLMData = NULL;    

    //class functions
    DataLogMaintenanceData *DataLogMaintenanceData::getDLMData()
    {
        if (FALSE == instanceFlag)
        {
            static DataLogMaintenanceData dlmData;
            DLMData = &dlmData;
            instanceFlag = TRUE;
            return DLMData;
        }
        else
        {
            return DLMData;
        }
    }

    void InitDataLog ( void )
    {
        DataLogMaintenanceData *dlmData;
        dlmData = DataLogMaintenanceData::getDLMData();
        // to avoid dlmData warning
        dlmData = dlmData;
    }

    //ACTUAL TASK
    __task DataLog()
    {
      .. .. .. code to initialize stuff

      InitDataLog();

      .. .. ..more stuff
    }

出于某种原因,我可以对其进行编译的唯一方法是创建一个堆空间,然后允许将 malloc() 和 free() 调用编译到项目中。正如预期的那样,“静态”定义的对象 dlmData 驻留在分配给 dataLog.o 模块的 RAM 空间中(即它不在 HEAP 中)。

我不明白,我查过谷歌,我错过了什么?在C++中编译纯对象时是否可以绕过malloc()和free()?我知道我可以替换 RTOS 的 malloc() 和 free() 实现而不执行任何操作,但我想避免编译我不会使用的代码。

Background: We are using Keil to compile our NXP LPC2458 project. There are numerous tasks that are being run on Keil’s RealView RTOS. There is stack space created, which is being allocated to each task. There is no HEAP created by default, and I want to avoid it since we can't afford the code-space overhead and the cost of "garbage collecting"

Objective: Use C++ in the embedded code without using the heap. Keil provides the #pragma (__use_no_heap) which prevents malloc() and free() calls to be linked.

Solution: I tried creating a Singleton with a private static pointer. My hopes were that the new() would not be called since I declared dlmData as static in the getDLMData(). For some reason, the linker still states that malloc() and free() are being called. I have thoughts of a private operator new () and a private operator delete() , and then declaring the dlmData as static within the overloaded function. It is not working for some reason. WHAT AM I DOING WRONG?

    //class declaration
    class DataLogMaintenanceData
    {
    public:
      static DataLogMaintenanceData* getDLMData();
      ~DataLogMaintenanceData()
      { instanceFlag = FALSE; }
    protected:
      DataLogMaintenaceData(); //constructor declared protected to avoid poly
    private:
      static Boolean instanceFlag;
      static DataLogMaintenceData *DLMData;
    }

    //set these to NULL when the code is first started
    Boolean DataLogMaintenanceData::instanceFlag = FALSE;
    DataLogMaintenanceData *DataLogMaintenaceData::DLMData = NULL;    

    //class functions
    DataLogMaintenanceData *DataLogMaintenanceData::getDLMData()
    {
        if (FALSE == instanceFlag)
        {
            static DataLogMaintenanceData dlmData;
            DLMData = &dlmData;
            instanceFlag = TRUE;
            return DLMData;
        }
        else
        {
            return DLMData;
        }
    }

    void InitDataLog ( void )
    {
        DataLogMaintenanceData *dlmData;
        dlmData = DataLogMaintenanceData::getDLMData();
        // to avoid dlmData warning
        dlmData = dlmData;
    }

    //ACTUAL TASK
    __task DataLog()
    {
      .. .. .. code to initialize stuff

      InitDataLog();

      .. .. ..more stuff
    }

For some reason, the only way I can get this to compile, is to create a heap space and then allow the malloc() and free() calls to be compiled into the project. As expected, the “static”ally defined object, dlmData, resides in the RAM space allocated to the dataLog.o module (i.e. it doesn’t live in the HEAP).

I can’t figure out, and I have checked Google, what am I missing? Is it possible in C++ to bypass malloc() and free() when compiling pure objects? I know I can replace the RTOS’s implementation of malloc() and free() to do nothing, but I want to avoid compiling in code that I won’t use.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自由如风 2024-12-05 08:42:59

可能我们没有看到的一些代码调用了一个在幕后调用 malloc 的函数。

来自 http://www.keil.com/support/man/docs/ armlib/armlib_CJAIJCJI.htm 您可以在链接行上使用 --verbose --list=out.txt 来获取有关 malloc 的详细信息来电者。

Probably some of the code we aren't seeing calls a function that calls malloc behind the scenes.

From http://www.keil.com/support/man/docs/armlib/armlib_CJAIJCJI.htm you can use --verbose --list=out.txt on the link line to get details about the malloc caller.

ゝ杯具 2024-12-05 08:42:59

Keil 安装中包含一组 PDF...其中一个文档(文档 ID DUI0475A)的标题为“使用 ARM C 和 C++ 库以及浮点支持”。它在几个地方讨论了堆的使用(以及阻止其使用)。

具体来说,请查看第 2.64 节“避免使用 ARM 提供的堆和使用堆的库函数”,那里有很多有用的信息。该部分中有趣的文字:

您可以在以下位置引用 __use_no_heap__use_no_heap_region 符号
您的代码以确保没有链接使用堆的函数
ARM 库。

__use_no_heap 防止使用 malloc()、realloc()、free()、
以及使用这些函数的任何函数。例如,calloc() 和
其他 stdio 功能。

__use_no_heap_region__use_no_heap 具有相同的属性,但在
此外,还可以防止其他事情使用堆内存区域。
例如,如果您将 main() 声明为带有参数的函数,则
堆区域用于收集argc和argv。

由于您的问题是关于如何防止 malloc() 被调用/使用,这可能会让您走上正确的轨道。

Included in the Keil installation is a set of PDFs... one of the documents (document ID DUI0475A) is titled "Using ARM C and C++ Libraries and Floating-Point Support". It discusses use of the heap (and preventing its use) in several places.

Specifically, check out section 2.64 "Avoiding the ARM-supplied heap and heap-using library functions", lots of good information there. The interesting text in that section:

You can reference the __use_no_heap or __use_no_heap_region symbols in
your code to guarantee that no heap-using functions are linked in from
the ARM library.

__use_no_heap guards against the use of malloc(), realloc(), free(),
and any function that uses those functions. For example, calloc() and
other stdio functions.

__use_no_heap_region has the same properties as __use_no_heap, but in
addition, guards against other things that use the heap memory region.
For example, if you declare main() as a function taking arguments, the
heap region is used for collecting argc and argv.

Since your question is about how prevent malloc() from being called / used, that might put you on the right track.

潜移默化 2024-12-05 08:42:59

从您发布的代码中,我看不到任何想要在堆上分配内存的内容。某处是否发生了隐式转换?如果你编译时根本没有这个类怎么办?

你可以做什么:

1)在调试器下运行(假设你可以构建一个可运行的图像,也许在模拟器上),在malloc中设置断点并检查堆栈

2)提供你自己的malloc和free以使链接器满意,然后重复步骤1.

您可能会发现需要链接不同版本的 C 运行时启动。在最坏的情况下,如果对 malloc/free 的调用次数受到限制,您可以推出自己的版本,这将为调用者提供一些预分配的内存 - 但希望这不是必需的。

From the code you've posted I cannot see anything that would like to allocate the memory on the heap. Are there any implicit conversions taking place somewhere? What if you compile without this class at all?

What you could do:

1) Run under debugger (assuming you can build a runnable image, maybe on an emulator), set a breakpoint in malloc and examine the stack

2) Provide your own malloc and free to make linker happy, then repeat step 1.

You may find that you need to link against a different version of C runtime startup. In the worst case if number of calls to malloc/free is limited you can roll out your own version which will give the callers some preallocated memory - but hopefully this will not be neccessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文