Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вычислить офсет в памяти.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Jenya7
Есть внешняя память. 512 страниц. каждая страница 64 байт.
на каждой странице первые 4 байта - метка и потом 5 записей по 12 байт.
у меня есть структура в которой я записываю номер текущей страницы и номер текущей записи на странице.
нужно считать например N-ю запись от текущей. сижу думаю над алгоритмом. ничего красивого в голову не приходит. может кто подскажет интересное решение?
Сергей Борщ
В чем затык?
CODE
typedef struct
{
    uint8_t Raw_data[12];
} record_t;

typedef struct
{
    uint32_t Identifier;
    record_t Record[5];
} page_t;

extern page_t Ext_storage[512]; // разместить Ext_storage где надо средствами линкера.

record_t * get_record(uint_fast16_t page, uint_fast8_t record)
{
    return Ext_storage[page].Record[record];
}
На плюсах можно сделать красивее.
Jenya7
Цитата(Сергей Борщ @ Apr 21 2016, 13:26) *
В чем затык?

ой... сейчас попробую.

а page то мы не знаем. мы знаем текущую страницу а страницу требуемой записи надо вычислять.

а что в линкере можно указать область памяти? у меня память 24LC256. я пишу по I2C.
Сергей Борщ
QUOTE (Jenya7 @ Apr 21 2016, 10:13) *
а page то мы не знаем. мы знаем текущую страницу а страницу требуемой записи надо вычислять.
Мне кажется это арифметика за первый класс начальной школы.
QUOTE (Jenya7 @ Apr 21 2016, 10:13) *
а что в линкере можно указать область памяти? у меня память 24LC256. я пишу по I2C.
Я не телепат.
С учетом новых исходных данных можно идти двумя путями:
1) как было сделано в avr-gcc для eeprom: В свободном месте адресного пространства (скажем, с адреса 0xA0000000) объявить регион памяти, сложить в него все относящиеся к внешней памяти секции данных. Работать с этими данными через адреса, т.е. I2C_read(&Ext_storage[page].Record[record]), старшую тетраду (байт, полуслово) адреса игнорировать. Если где-то забыли & или обратились напрямую к Ext_storage[page].Record[record] - получили исключение. Чаще всего это будет происходить во время или после сдачи изделия заказчику.

2) Освоить С++, написать класс, для которого переопределить operator=, operator[] и скрыть все обращения к внешней памяти в этих двух операторах.
Jenya7
Цитата(Сергей Борщ @ Apr 21 2016, 15:19) *
Мне кажется это арифметика за первый класс начальной школы.

мне не очень нравиться первый вариант.
второй вариан - лучше уж С# я его уже хорошо освоил.

jcxz
Цитата(Jenya7 @ Apr 21 2016, 15:28) *
второй вариан - лучше уж С# я его уже хорошо освоил.

Интересно - как Вы представляете работу C#, с его компиляцией кода на лету, на embedded платформе?
Jenya7
Цитата(jcxz @ Apr 21 2016, 16:21) *
Интересно - как Вы представляете работу C#, с его компиляцией кода на лету, на embedded платформе?

это была завуалированная ирония. Сергей меня понял.
Lagman
Цитата(Сергей Борщ @ Apr 21 2016, 12:19) *
2) Освоить С++, написать класс, для которого переопределить operator=, operator[] и скрыть все обращения к внешней памяти в этих двух операторах.

А есть примерчик посмотреть?
ar__systems
Цитата(Lagman @ Apr 28 2016, 04:15) *
А есть примерчик посмотреть?

В любой книжке по С++ есть.
Lagman
Цитата(ar__systems @ Apr 28 2016, 16:28) *
В любой книжке по С++ есть.

Применительно к EEPROM!? Так то я тоже могу вам насоветовать книжки читать, мне интересно посмотреть как это реализуется в данном конкретном случае, а не как переопределить оператор.
P.S. Я это прошу, потому что на С++ не пишу, и интересно увидеть код пусть даже больше абстрактный, для этих целей.
Сергей Борщ
QUOTE (Lagman @ Apr 30 2016, 22:37) *
и интересно увидеть код пусть даже больше абстрактный, для этих целей.
Примерно так (код из головы):
CODE
class eeprom_base
{
protected:
    void write(void * to, void const * from, size_t size);
    void read(void * to, void const * from, size_t size);
}

template<typename T>
class eeprom : prvate eeprom_base
{
public:
    T const & operator=(T const & new_value) { write(this, &new_value, sizeof(T)); }
    operator T() { T Result; read(&Result, this, sizeof(T)); return result; }
private:
    T dummy;    // to allocate memory
}


__attribute__((__section__(".eeprom")))
eeprom<uint8_t> Config_data_A;

uint8_t test(uint8_t in)
{
    uint8_t Out;
    Out = Config_data_A;
    Config_data_A = in;
}
Jenya7
ну если конкретно по моему вопросу то можно так.
Код
#define HEADER_SIZE 4
#define RECORD_SIZE 12
#define LOGS_PER_PAGE   5

uint32_t offset = (log_to_read * RECORD_SIZE) + (HEADER_SIZE * ( log_to_read / LOGS_PER_PAGE));
uint32_t new_addr = addr - offset;

чего только ни придумаешь чтоб не учить С++. sm.gif
Lagman
Цитата(Сергей Борщ @ May 1 2016, 09:03) *
Примерно так (код из головы):


Спасибо. Мне без практики на С++ тяжеловато с пониманием кода, но в такой виде понять можно.

Цитата(Jenya7 @ May 1 2016, 10:02) *
чего только ни придумаешь чтоб не учить С++. sm.gif

Да, мне тоже на С легче написать. Но камни делают все объемней и объемней (RAM ROM), компиляторы все умней и код на C++ для больших проектов уже "проще" для понимания чем код на С.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.