|
|
  |
Вычислить офсет в памяти. |
|
|
|
Apr 21 2016, 05:55
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Есть внешняя память. 512 страниц. каждая страница 64 байт. на каждой странице первые 4 байта - метка и потом 5 записей по 12 байт. у меня есть структура в которой я записываю номер текущей страницы и номер текущей записи на странице. нужно считать например N-ю запись от текущей. сижу думаю над алгоритмом. ничего красивого в голову не приходит. может кто подскажет интересное решение?
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 21 2016, 07:26
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
В чем затык? 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]; } На плюсах можно сделать красивее.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 21 2016, 08:13
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Сергей Борщ @ Apr 21 2016, 13:26)  В чем затык? ой... сейчас попробую. а page то мы не знаем. мы знаем текущую страницу а страницу требуемой записи надо вычислять. а что в линкере можно указать область памяти? у меня память 24LC256. я пишу по I2C.
Сообщение отредактировал Jenya7 - Apr 21 2016, 08:34
|
|
|
|
|
Apr 21 2016, 09:19
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
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[] и скрыть все обращения к внешней памяти в этих двух операторах.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 30 2016, 19:37
|
Знающий
   
Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245

|
Цитата(ar__systems @ Apr 28 2016, 16:28)  В любой книжке по С++ есть. Применительно к EEPROM!? Так то я тоже могу вам насоветовать книжки читать, мне интересно посмотреть как это реализуется в данном конкретном случае, а не как переопределить оператор. P.S. Я это прошу, потому что на С++ не пишу, и интересно увидеть код пусть даже больше абстрактный, для этих целей.
|
|
|
|
|
May 1 2016, 06:03
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
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; }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 2 2016, 09:51
|
Знающий
   
Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245

|
Цитата(Сергей Борщ @ May 1 2016, 09:03)  Примерно так (код из головы): Спасибо. Мне без практики на С++ тяжеловато с пониманием кода, но в такой виде понять можно. Цитата(Jenya7 @ May 1 2016, 10:02)  чего только ни придумаешь чтоб не учить С++.  Да, мне тоже на С легче написать. Но камни делают все объемней и объемней (RAM ROM), компиляторы все умней и код на C++ для больших проектов уже "проще" для понимания чем код на С.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|