Как заставить компоновщик хранить во флэш-памяти константный массив массивов строк (вместо оперативной памяти) - PullRequest
0 голосов
/ 01 февраля 2019

Недавно мне дали устаревший код, у которого есть пара проблем.В некотором коде я заметил, что большая часть отчетов о состоянии хранится в виде трехмерных массивов символов.Кикер в том, что МНОГО этого пространства фактически не используется.Например, это:

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...}
};

Однако теперь массивы (или любой другой правильный термин) записываются в ОЗУ, что приводит к их переполнению.

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

Эти 6888 байт НАМНОГО меньше, чем при исходном методе с удаленной частью сечения, но не желаемый результат.

Как я могу сказать (я думаю)компоновщик, который также записывает строки во флэш-память?

Все всегда неизменно, никаких изменений не произойдет, пусть это будет указатель или значения, на которые они указывают.

Редактировать:Я заметил, что мой заголовок, вероятно, не идеален, пожалуйста, скажите, на что его изменить.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Это один из тех случаев в C, где они изобрели излишне сложный синтаксис.

Компоновщик должен знать, что таблица указателей доступна только для чтения, а не только строкалитералы указали на.В противном случае строковые литералы заканчиваются флэш-памятью, как обычно, но указатели в ОЗУ.

const char ** означают (считывание справа налево) указатель на указатель на const char.Но для того, чтобы получить это внутри флэш-памяти, вам нужен указатель «только чтение», чтобы указатель «только чтение» указывал на const char.

Чтобы сам указатель был доступен только для чтения, а не на данные, на которые указывает указатель,Вы помещаете ключевое слово const справа от *.То есть:

const char *const *const txt;.

Снова, чтение справа налево: только для чтения, указатель на указатель только для чтения, на const char.

Глядя на ваш файл .map, txt теперь должен находиться в сегменте .rodata или аналогичном.

0 голосов
/ 01 февраля 2019

Вам нужно const char * const * const ...

...