Компоновщик Arm GCC: как поместить данные по абсолютному адресу в (rw)-энергонезависимую память

Я столкнулся со следующей проблемой. Я программирую микроконтроллер ARM cortex M4 и хотел бы, чтобы он имел значение по умолчанию для IP-адреса, сетевой маски, шлюза и т. д. Эти значения по умолчанию должны изменяться через последовательную связь, И эти изменения должны быть постоянными. Например: значение по умолчанию для IP-адреса и сетевой маски: 192.168.1.20 255.255.255.0 Пользователь изменяет адрес и сетевую маску на 192.168.2.10 255.255.255.0 Теперь после отключения и повторного подключения устройства к источнику питания значения «по умолчанию» должны быть введен пользователем (192.168.2.10/255.255.255.0)

Чтобы решить эту проблему, я подумал об использовании так называемой рабочей флэш-памяти моего УК. Это энергонезависимая память, которую можно записать с помощью специальных команд. Чего я пытаюсь добиться, так это определить значения по умолчанию в программном коде (как переменные в данный момент или, если это возможно, позже), которые выбираются компоновщиком и чье ЗНАЧЕНИЕ помещается в энергонезависимую память (рабочая флэш-память ) по адресу 0x200C000.

Прямо сейчас мой файл компоновщика выглядит так:

MEMORY
{
    rom  (rx)  : ORIGIN = 0x00000000, LENGTH = 0x100000 /* 1MB */
    ram  (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x10000 /* 64K  */
    ram1 (rwx) : ORIGIN = 0x20038000, LENGTH = 0x10000  /* 64K  */
    wofl (rwx) : ORIGIN = 0x200C0000, LENGTH = 0x8000   /* 32K  */
}

...

.wifi_defaults :
{
    KEEP(*(.wifi_defaults*));
} > wofl

...

и объявление переменной в исходном коде (просто для тестирования):

uint16_t __attribute__((section(".wifi_defaults"))) test= 0x00D0;

Файл .map показывает мне:

.wifi_defaults  0x200c0000        0x2
 *(.wifi_defaults*)
 .wifi_defaults
                0x200c0000        0x2 ..\obj\HSFirmware.o
                0x200c0000                test

Но при доступе к переменной я получаю не правильное значение, а только начальное значение 0xFFFF, которое было возвращено еще до того, как я начал возиться с компоновщиком.

Я также пытался использовать CONST перед объявлением переменной, но это не имело никакого значения.

Насколько я понимаю, мой код помещает неинициализированную переменную в указанный сегмент кода. Как я могу поместить инициализированную переменную по заданному адресу?


person Daniel    schedule 12.10.2016    source источник
comment
Незапрограммированная флэш-память читается как 0xffff. Как код/данные попадают на устройство? Кроме того, вам нужны подпрограммы для выполнения специальной последовательности, чтобы запрограммировать код для обновления. Я бы посоветовал вам не пытаться инициализировать данные во «флеш-памяти». Вместо этого сохраните копию ПЗУ по умолчанию (которая, похоже, работает/программируется). Если вы читаете 0xffff, то вызовите программу прошивки, чтобы сделать ее значением по умолчанию. Также вы можете предоставить возможность восстановить значения по умолчанию. Существуют проблемы с инструментами загрузки и двоичным форматом, которые необходимо решить иначе. Пожалуйста, прочитайте о VMA и LMA в документах LD.   -  person artless noise    schedule 12.10.2016
comment
Вероятно, вам следует выполнить контрольную сумму / CRC и т. Д. Данных конфигурации флэш-памяти. Если это плохо, вы можете использовать значения по умолчанию, которые будут находиться в ПЗУ (и могут быть установлены с помощью определения). Флэш-память может выйти из строя при обычном использовании (длится около 10 лет?), и у пользователя, по крайней мере, все еще будет полуфункциональное устройство, если оно выйдет из строя, и вы используете разумные значения по умолчанию (в отличие от случайного мусора).   -  person artless noise    schedule 12.10.2016
comment
Связано:stackoverflow.com/questions/39892860/ Ответ может быть ответом и на это   -  person tofro    schedule 12.10.2016
comment
Безыскусный нойз, это именно то, что я реализовал за это время. И при реализации я пришел к тому же решению, что было бы полезно иметь данные по умолчанию в ПЗУ и записывать их на флэш-память, чтобы иметь возможность восстановить заводские настройки по умолчанию. Спасибо за ваш комментарий.   -  person Daniel    schedule 14.10.2016
comment
Если вы прошиваете свое устройство с помощью инструментов, которые умеют записывать flash по адресу 0x200C0000, они сделают это за вас. В противном случае я бы рекомендовал 1-й комментарий @artless Noise.   -  person hesham_EE    schedule 14.10.2016