Как получить флэш-адрес глобальной переменной в Arduino - PullRequest
0 голосов
/ 09 декабря 2018

У меня есть статическая глобальная переменная в моем Arduino (например, ATmega328P), которая, как и любое другое статическое хранилище без PROGMEM, автоматически загружается в SRAM после запуска.Я установил значение по умолчанию, которое заменяется сохраненным значением из EEPROM в setup().Я хотел бы предложить возможность сброса переменной к ее первоначальному значению по умолчанию без повторного определения значения в моем коде.
Можно ли получить флэш-адрес статической глобальной переменной в Arduino для загрузки ее исходных данных из флэш-памяти?к SRAM через pgm_read_byte() например?Если да, то как?

PS Рассматриваемая статическая глобальная переменная представляет собой довольно большую структуру.Переопределение этого не подлежит обсуждению.

1 Ответ

0 голосов
/ 09 декабря 2018

Постоянные данные можно сделать адресуемыми, объявив их PROGMEM.Поскольку память программы AVR организована в виде 16-битных слов в отдельном адресном пространстве, для чтения необходимо использовать специальные функции .

#include <assert.h>
#include <string.h>                        // memcpy
#include <avr/pgmspace.h>                  // AVR PROGMEM, memcpy_P

#define SIZE 1000
struct large {                             // arbitrary large data structure
  unsigned char data[SIZE];
};

struct large l;                            // global variable (in SRAM)

const struct large l_default PROGMEM = {   // default value (in PROGMEM)
  { 0xaa, 0xab, 0x0ac, 0xad, 0xae, 0xaf }
};

void setup(void)                           // load values from EEPROM
{
  memset(&l, 1, SIZE);                     // simulate reading from real EEPROM
}

int main(void)
{
  setup();                                 // initialize from EEPROM
  assert(l.data[0] == 1);

  memcpy_P(l.data, &l_default, SIZE);      // reset to defaults (from PROGMEM)
  assert(l.data[0] == 0xaa);

  return 0;
}

Подтверждение того, что размеры из приведенного выше примераожидается: 1000 дополнительных байтов в Program для данных по умолчанию, всего 1000 байтов в Data для глобальной переменной.

$ avr-size -C -x main.bin
AVR Memory Usage
----------------
Device: Unknown

Program:    1252 bytes
(.text + .data + .bootloader)

Data:       1000 bytes
(.data + .bss + .noinit)

Данные по умолчанию (начиная с aaabacadaeaf и заканчивая 994 нулями) были помещены в память программы сразу после векторов прерывания.Доступ к нему можно получить во время выполнения с помощью семейства функций pgm_read_.

$ avr-objdump -s main.bin

main.bin:     file format elf32-avr

Contents of section .text:
0000 0c942802 0c943a02 0c943a02 0c943a02  ..(...:...:...:.
0010 0c943a02 0c943a02 0c943a02 0c943a02  ..:...:...:...:.
0020 0c943a02 0c943a02 0c943a02 0c943a02  ..:...:...:...:.
0030 0c943a02 0c943a02 0c943a02 0c943a02  ..:...:...:...:.
0040 0c943a02 0c943a02 0c943a02 0c943a02  ..:...:...:...:.
0050 0c943a02 0c943a02 0c943a02 0c943a02  ..:...:...:...:.
0060 0c943a02 0c943a02 aaabacad aeaf0000  ..:...:.........
0070 00000000 00000000 00000000 00000000  ................
0080 00000000 00000000 00000000 00000000  ................
0090 00000000 00000000 00000000 00000000  ................
[...]
...