错误[Lp001]我不应该耗尽内存

时间:2015-03-25 07:42:44

标签: c++ memory arm embedded iar

我目前正在开发一个使用不同语言设置的项目。为了解决这个问题,一个表用于存储程序中使用的不同语言的所有文本。因此,每当要在屏幕上写入文本时,将调用此表,并根据当前语言设置返回文本字符串。我最近加入了这个项目,我注意到存储它的方式并没有得到很好的优化,并且每增加一个新语言,查找正确字符串所需的时间就会增加。因此,我想出了一个(在我看来)更好的解决方案。但是,当我尝试实现它时,我遇到了一个错误,即使用了太多内存的问题,我不明白为什么。我正在使用IAR嵌入式工作台。

伪/ c ++代码中的原始解决方案:

typedef struct
{
    enum textId;
    enum language;
    string textString;
} Text;

static const Text s_TextMap[] = 
{
     { TextId::RESTORE_DATA_Q                ,Language::ENGLISH        ,"Restore Data?"                          },
     { TextId::RESTORE_DATA_Q                ,Language::SWEDISH        ,"Återställa data?"                       },
     { TextId::RESTORE_DATA_Q                ,Language::GERMAN         ,"Wiederherstellen von Daten?"            },
     { TextId::CHANGE_LANGUAGE               ,Language::ENGLISH        ,"Change Language"                        },
     { TextId::CHANGE_LANGUAGE               ,Language::SWEDISH        ,"Välj språk"                             },
     { TextId::CHANGE_LANGUAGE               ,Language::GERMAN         ,"Sprache wählen"                         },
};

我的伪/ c ++代码解决方案:

typedef struct
{
    const char* pEngText;
    const char* pSweText;
    const char* pGerText;
} Texts;

static Texts addTexts(const char* pEngText, const char* pSweText, const char* pGerText)
{
    Texts t;
    t.pEngText = pEngText;
    t.pSweText = pSweText;
    t.pGerText = pGerText;
    return t;
}

typedef struct
{
    enum textId;
    Texts texts;
} Text;

static const TextTest s_TextMapTest[] =
{
     {TextId::RESTORE_DATA_Q,        addTexts("Restore Data?","Återställa data?","Wiederherstellen von Daten?")},
     {TextId::CHANGE_LANGUAGE,        addTexts("Change Language","Välj språk","Sprache wählen")},
};

我的解决方案显然在平均情况下查找速度更快,根据我的计算,它也应该使用更少的内存。当使用完整的表时,我已经计算出原始解决方案需要7668个字节,而我的解决方案需要4248个字节。我这样做的方法是在一个小的测试程序中实现完整的表并使用sizeof(s_TextMap)。但是,当我尝试编译代码时,我得到链接错误:

  

错误[Lp011]:部分放置失败   无法为< [0x0000a000-0x0007ffff]>中的总估计最小大小为0x130301字节(最大对齐0x1000)的段/块分配空间(总未提交空间0x757eb)。

     

错误[Lp011]:部分放置失败   无法为< [0x1fff0000-0x2000fff0]>中的总估计最小大小为0x47de4字节(最大对齐0x20)的段/块分配空间(未提交的总空间0x1fff1)。

     

错误[Lp021]:压缩初始化程序批处理“USER_DEFAULT_MEMORY-1”的目标位于一个地址,该地址取决于批处理的大小,使用lz77压缩时不允许这样做。请考虑使用“使用packing = zeros复制初始化”(或无)。

     

错误[Lp021]:压缩初始化程序批处理“USER_DEFAULT_MEMORY-1”的目标位于一个地址,该地址取决于批处理的大小,使用lz77压缩时不允许这样做。请考虑使用“使用packing = zeros复制初始化”(或无)。

我最困惑的错误是第一个声明我的代码估计占用内存为0x130301字节的错误,我认为这是不可能的。这可能是IAR中的一些错误还是我错过了什么?

2 个答案:

答案 0 :(得分:2)

在你的解决方案中s_TextMapTest[]必然位于RAM而不是ROM中,因为指针是在运行时设置的 - 尽管不清楚你是如何设法使用函数调用作为数组元素初始化器的。在大多数微控制器上,RAM是一种非常有限的资源。您没有提供有关目标或其内存映射的信息。

无论哪种方式,您都应检查链接器的内存映射输出,以验证数据是否位于适当位置以及预期位置。

您在自己的答案中提出的原始代码和解决方案是ROMable。

在保持ROMable状态的同时保持原始提案形式的解决方案是将addTexts()写为宏而不是函数:

#define addTexts( eng, swe, ger, fin ) {eng, swe, ger, fin}

虽然我看不出它的优点是什么,但你并没有真正“添加”文本 - 文本总是在初始化时出现。

答案 1 :(得分:0)

好的,所以我设法让它发挥作用。我提供了额外的结构和功能,并将其简化为:

typedef struct
{
    TextId::e textId;
    const char* pEngText;
    const char* pSweText;
    const char* pGerText;
    const char* pFinText;
} Text;

对我来说看起来并不好,但至少它起作用