【问题标题】:Unable to allocate memory on an embedded device无法在嵌入式设备上分配内存
【发布时间】:2019-08-03 03:37:23
【问题描述】:

我知道不鼓励在嵌入式环境中使用 malloc,但我发现使用它的示例与我需要的内容相关,并且对我来说效果很好。

这是代码,我觉得它的执行有点令人困惑:

    uint8_t * buffer;  // pointer to buffer                           
    uint8_t * buffer1; // pointer to buffer1 
    uint8_t * buffer2; // pointer to buffer2 

    buffer  = malloc(400 * sizeof(uint8_t));    // size of buffer
    buffer1 = malloc(400 * sizeof(uint8_t));    // size of buffer1
    buffer2 = malloc(400 * sizeof(uint8_t));    // size of buffer2  

这些是调试执行开始时指针值的监视窗口。

执行到位于上述代码sn-p结束后的断点之后。

当使用调试器单步执行时,在malloc 行之后,我可以看到第一行将为buffer 指针分配地址。它只会对buffer 这样做,而不是buffer1buffer2

在更改内存分配顺序时,如下代码所示:

    uint8_t * buffer;  // pointer to buffer                           
    uint8_t * buffer1; // pointer to buffer1 
    uint8_t * buffer2; // pointer to buffer2 

    buffer1 = malloc(400 * sizeof(uint8_t));    // size of buffer
    buffer  = malloc(400 * sizeof(uint8_t));    // size of buffer1
    buffer2 = malloc(400 * sizeof(uint8_t));    // size of buffer2  

在这种情况下,指针buffer1 将具有非零值,而其他指针将为空,如下面的手表所示。

像下面这样的测试代码会导致它为指针buffer1分配一个值,当再次为其分配内存时,它会再次将其设置为零。

    uint8_t * buffer;  // pointer to buffer
    uint8_t * buffer1; // pointer to buffer1 
    uint8_t * buffer2; // pointer to buffer2 

    buffer1 = malloc(400 * sizeof(uint8_t));    // size of buffer1
    buffer  = malloc(400 * sizeof(uint8_t));    // size of buffer
    buffer1 = malloc(400 * sizeof(uint8_t));    // size of buffer1  

当初始化具有缓冲区之一的结构时,如果对空指针值执行 assert(),则代码稍后会崩溃。

我开始使用 malloc 只是因为我在网上找到了这个 code for implementing circular buffer

虽然我对指针/内存相关的东西并不陌生,但它确实经常让我感到惊讶。我猜我从根本上误解了内存是如何分配(或不分配)的,或者调试器和监视窗口如何更新指针值。

感谢您的帮助。

【问题讨论】:

  • 一些嵌入式系统没有任何工作的malloc。并且malloc 允许失败,然后返回NULL
  • malloc 在出错时返回一个空指针。你确定你有足够的内存吗?如何为您的设备指定 malloc?
  • 我怀疑您是否有适当的malloc 实现和/或为您的环境中的堆分配空间。
  • @Govind Parmar 这听起来像是使用 SWD 做的事情,我认为我无法通过 MCU 所在的板访问它。
  • 您确保在调试时禁用所有优化?

标签: c pointers memory stm32 keil


【解决方案1】:

如果在 Keil ARM-MDK 中使用提供的项目模板,分配的堆大小通常相当小。您需要为您的应用程序适当地设置它的大小。

您的项目将包含名为 startup_stm32xxxxx.s 的启动汇编代码(其中 xxxxx 是特定于部件的)。此文件包含 uVision 编辑器可识别的标记 cmets,因此当您打开文件时,编辑器窗口底部有两个选项卡 - 一个用于源代码,一个用于配置。您可以通过任一方式修改堆栈和堆大小。

下面的示例(对于与您的不同的部分,因此参数可能会有所不同,但至少会存在堆栈和堆):

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 2014-01-15
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多