首页 > 解决方案 > 如何强制链接器将字符串数组的 const 数组存储到闪存中(而不是 RAM)

问题描述

最近,我收到了一些遗留代码,这些代码有几个问题。在一些代码中,我注意到很多状态报告都存储为 3d 字符数组。更重要的是,这个空间中有很多实际上是未使用的。例如这个:

const char txt[<60>][6][150] =
{
    {"This is a very very long string of text", "The others are empty", "", "", "", ""},
    {"The text is different, but similarly a lot of unused space", etc...}
};

(60 不存在,但有 60 个条目)。

然后使用声明上方的以下代码通过 QSPI 将此代码放入闪存中

__attribute__((section(".ExtQSPIFlashSection")))

这部分在链接器中是这样定义的:

QSPI (rx)       : ORIGIN = 0x90000000, LENGTH = 64M
.ExtQSPIFlashSection : { *(.ExtQSPIFlashSection) } >QSPI

作为一种内存效率更高的方法,我想这样重写它:

const char **txt[] =
{
    (const char*[]) {"This is a very very long string of text", "The others are empty", "", "", "", ""},
    (const char*[]){"The text is different, but similarly a lot of unused space", etc...}
};

但是,现在数组(或任何正确的术语)被写入 RAM,这导致它溢出。

'._user_heap_stack' will not fit in region RAM  
region 'RAM' overflowed by 6888 bytes

这 6888 个字节比删除部分部分的原始方法要少得多,但不是所需的结果。

我怎样才能告诉(我认为)链接器也将字符串写入闪存?

一切都是不可变的,永远不会改变,让它成为指针或它们指向的值。

编辑:我注意到我的标题可能并不完美,请告诉我要改成什么。

标签: clinkerarmembeddedstm32

解决方案


这是 C 语言中的一种情况,他们发明了不必要的复杂语法。

链接器需要知道指针表是只读的,而不仅仅是指向的字符串文字。否则字符串文字像往常一样最终在闪存中,但在 RAM 中的指针。

const char **表示(从右到左读取),指向指针的指针const char。但是为了在 Flash 中得到这个,你需要只读指针指向 const char.

要将指针本身设为只读,而不是指向的数据,请将const关键字放在*. 那是:

const char *const *const txt;.

同样,从右到左阅读:只读,指向只读指针的指针,指向const char.

查看您的 .map 文件,txt现在应该是分段.rodata或类似的。


推荐阅读