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

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

Мы используем перечисление dwords для хранения различных переменных в 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? Так что, вероятно, нужна какая-то файловая система. Нет ничего меньшего? Или какая-то уловка? В любом случае переменные имеют фиксированную длину. Вот почему мне было интересно, есть ли какой-нибудь хороший и простой способ хранить эти структуры.

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


person Fritjof    schedule 25.08.2011    source источник
comment
Думаю, я только что нашел ответ. Выбирая теги, я обнаружил следующее: stackoverflow.com/questions / 3551824 / Это может сработать для меня. Я попробую.   -  person Fritjof    schedule 25.08.2011
comment
Файловая система будет очень расточительной, если вы беспокоитесь о превращении 4 байтов в 1, файловая система, вероятно, захочет записать 2048 или 4096 или более байтов на блок в файле, редко у вас нет десятков и тысяч неиспользованных байтов. Использование структур в доменах компиляции также является плохой идеей (указание структуры на память / файл и т. Д.). фиксированные 4-байтовые объекты - это хорошо, хорошо разбивать структуры на отдельные 4-байтовые объекты, а затем добавлять теги вокруг них, которые вы нашли, - хорошо.   -  person old_timer    schedule 27.08.2011
comment
использование eeprom или flash в качестве файловой системы - это плохо, они изнашиваются (да, текущие коммерческие продукты одноразовые, вы должны постоянно покупать их по мере износа, mp3-плееры, флэш-накопители и т. д.). В идеале вы хотите запрограммировать их один раз, а затем читать вечно, возможно, иногда добавляя что-нибудь. Проектируйте свою систему так, чтобы знать, каков будет срок службы продукта. По мере их износа время записи увеличивается, так же как и ваша системная инженерия.   -  person old_timer    schedule 27.08.2011


Ответы (2)


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

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

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

Я думаю, вы имеете в виду массив dwords.

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

Похоже, вы знаете только, как инициализировать 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;
person Potatoswatter    schedule 26.05.2012

Если у вас есть массив структур, вы сможете записать данные в EEPROM и довольно легко прочитать их позже. Ключевым моментом здесь является знание того, где в 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, поэтому разумно выбирайте шаблоны и размеры верхнего / нижнего колонтитула.

person bta    schedule 18.07.2012