Хранение структур в EEPROM с использованием некоторой таблицы размещения файлов - PullRequest
1 голос
/ 25 августа 2011

У меня проблема с хранением данных в EEPROM на 16-битном микроконтроллере Fujitsu. Запись байтов в EEPROM не проблема, я могу записывать и считывать данные без проблем.

Мы используем перечисление dword s для хранения различных переменных в EEPROM, и все они имеют длину 4 байта. Для каждой переменной мы хотим сохранить до 4 байтов пространства. Это не очень хорошо, потому что, когда я хочу сохранить только флаг (один бит) или переменную, длина которой составляет всего один байт, он по-прежнему использует четыре байта.

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

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

Например, у меня есть структура, подобная

typedef struct {
    attenuator_whichone_t attenuator;
    char*                 attenuatorname;
    servo_whichone_t     associated_servo;
    ad_ad7683_whichone_t associated_adconverter;
    word                 item_control;
    word                 item_mode;
    word                 item_position;

} attenuator_info_t;

и инициализировать его следующим образом:

static attenuator_info_t constinfo[_NUM_ATTENUATOR_WHICHONE_] = {...}

С кодом, который мы используем сейчас, нам нужно было бы сохранять каждое значение отдельно. Следовательно, разрушая структуру. Я бы очень хотел сохранить эту структуру как есть. (и еще пара у нас в коде).

Из моего понимания мне понадобится файловая система для этого. Поиск Google дал мне несколько примеров, таких как microFAT ​​ и так далее. Это, на мой взгляд, излишество.

Сохранение структуры с помощью sizeof и повторение всех байтов было бы просто замечательно, но тогда, как мне решить проблему знания, где находятся структуры в EEPROM? Так что, возможно, нужна какая-то файловая система. Разве нет ничего меньшего? Или какая-то хитрость? В любом случае переменные имеют фиксированную длину. Вот почему мне было интересно, есть ли какой-нибудь хороший и простой способ сохранить эти структуры.

Надеюсь, я смогу уточнить мою проблему.

Ответы [ 2 ]

1 голос
/ 19 июля 2012

Если у вас есть массив структур, вы должны быть в состоянии записать данные в ЭСППЗУ и прочитать их позже довольно легко. Ключом здесь является точное знание , где в EEPROM, что данные хранятся.

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

#define ATTENUATOR_INFO_START 0x0100 // Indicates table starts at address 256
#define ATTENUATOR_INFO_SIZE (sizeof(constinfo)/sizeof(*constinfo))

// Store table in EEPROM
memcpy(EEPROM_START + ATTENUATOR_INFO_START, constinfo, ATTENUATOR_INFO_SIZE);

// Load table from EEPROM
memcpy(constinfo, EEPROM_START + ATTENUATOR_INFO_START, ATTENUATOR_INFO_SIZE);

Выше предполагается, что EEPROM отображается в память, а константа EEPROM_START представляет адрес памяти, сопоставленный с нулевым смещением EEPROM. Если в вашем проекте нет EEPROM, отображенного в память, ваша процедура будет немного другой, но общая идея та же.

Если вы не хотите хранить таблицу с фиксированным смещением, альтернативой является также запись смещения таблицы в EEPROM. Процесс в целом такой же:

// Offset/length information is stored in the first few bytes of the EEPROM
#define TABLE_INFO_LOCATION 0x0000

struct table_info {
    unsigned int offset;
    unsigned int num_entries;
} table_info;

// Retrieve table offset
memcpy(&table_info, EEPROM_START + TABLE_INFO_LOCATION, sizeof(table_info));

// Load table from EEPROM
memcpy(constinfo,
       EEPROM_START + table_info.offset,
       table_info.num_entries * sizeof(*constinfo));

Этот метод обеспечивает большую гибкость, поскольку таблица может быть расположена в любом месте EEPROM, но для хранения информации таблицы все еще требуется известное местоположение.

Если вы не можете хранить что-либо с заранее заданным смещением, вы можете создать подпись верхнего / нижнего колонтитула, чтобы обернуть структуру данных. Большинство устройств памяти по умолчанию 0x00 или 0xFF для байтов, которые не используются. Вы можете написать 32 байта шаблона 0xBE (для «до») непосредственно перед таблицей, а затем записать 32 байта шаблона 0xAF (для «после») сразу после таблицы. Это позволит вам сканировать память EEPROM и определять начало и конец таблицы, где бы она ни находилась. Недостатком является то, что вы рискуете искать неправильное место, если этот шаблон памяти появляется где-то еще в EEPROM, поэтому выбирайте шаблоны и размеры верхнего / нижнего колонтитула с умом.

0 голосов
/ 26 мая 2012

Из моего понимания мне понадобится файловая система для этого.Поиск в Google дал мне несколько примеров, таких как microFAT ​​и так далее.Это, на мой взгляд, излишнее.

Нет, файловая система не связана с задачей, которую вы описываете.Файловая система определяет соответствие между файлами names и files , которые могут быть произвольно созданы, доступны, удалены и изменены в размере.Вы не упомянули имена или требования для модификации во время выполнения.Это кажется излишним, потому что основные сервисы, которые определяют файловую систему, - вещи, которые вам не нужны.

Мы используем перечисление dword s для хранения различных переменных в EEPROM, и все ониДлина 4 байта.

Я думаю, что вы имеете в виду массив dword с.

Если это вызывает проблемы, почему бы не посмотреть на их изменение?

Похоже, вы знаете, как инициализировать EEPROM только с помощью определения формы

static attenuator_info_t constinfo[_NUM_ATTENUATOR_WHICHONE_] = {...}

Техническое ограничение EEPROM не требует, чтобы это было сделано.struct - это последовательность байтов, такая же, как array.Большинство встроенных компиляторов также позволяют вам обрабатывать последовательность struct, массив и другие определения как последовательность байтов, окружая их соответствующим #pragma.

Не зная ничего об EEPROM или о том, изменяется ли constinfo после сборки программы, я не могу сказать вам, как писать в нее.Но похоже, что вы хотите отобразить группу именованных переменных в последовательность байтов.Для этого может потребоваться файл формата , но не файловая система.

Если EEPROM отображен в памяти, вы можете просто скомпилировать в него указатели:

extern struct foo_info_type foo_info;
extern struct bar_info_type bar_info;

/* EEPROM table of contents */
struct foo_info_type *foo_ptr = & foo_info;
struct bar_info_type *bar_ptr = & bar_info;
/* ... more pointers ... */

/* Actual data in EEPROM, pointers point here */
struct foo_info_type foo_info;
struct bar_info_type bar_info;
...