Перейти к содержанию
    

Представление адреса. Как лучше.

У меня при обращении к памяти (чтение, запись) нужно передавать адрес. Адрес состоит из нескольких составляющих (на картинке).Изначально была такая конструкция

typedef struct {
    uint32_t     page_add  :  6;
    uint32_t     block_add : 11;
    uint32_t    reserved  : 15;
}g_row_address;
typedef union{
    uint32_t all;
    g_row_address bits;
}g_flashrow_address;

Может так и проще работать но я как то сравнивал листинги и такой код компилирует в два раза больше инструкций чем mask&shift.Я подумал сделать по простому

#define ROW_ADDRESS(BLOCK_ADDR,PAGE_ADDR)  (BLOCK_ADDR|(PAGE_ADDR<<6))

но адрес 17-битный. то есть возникает тот же гемор сдвигать влево а потом вправо. или я что то упускаю?

post-71075-1529316258_thumb.png

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задаю дефайнами нужные мне адреса в SPI flash, выравненные по началу страниц, и использую их в виде целого числа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задаю дефайнами нужные мне адреса в SPI flash, выравненные по началу страниц, и использую их в виде целого числа.

А когда нужно изменить размер какого-то элемента - пересчитываете все эти дефайны врукопашную? :biggrin:

Опишите структуру своей флешь через struct {...} и не конкурируйте с компилятором - времена рукопашной компоновки памяти давно прошли.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А когда нужно изменить размер какого-то элемента - пересчитываете все эти дефайны врукопашную? :biggrin:

Опишите структуру своей флешь через struct {...} и не конкурируйте с компилятором - времена рукопашной компоновки памяти давно прошли.

Зачем вручную? Препроцессор считает.

#define SFM_SYSTEM_BASE        0x00060000U            //!< SFM System Variables
...
#define SFM_SET1        (SFM_SYSTEM_BASE + SFM_PAGESIZE *  8)
#define SFM_SET2        (SFM_SYSTEM_BASE + SFM_PAGESIZE *  9)
...

 

Предлагаете описать в виде структуры из массивов, а потом вытягивать адреса членов этой структуры? Можно и так. Зато я точно знаю, где что расположено и сколько страниц занимает, а вам считать придется. А вдруг переполните размер памяти?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем вручную? Препроцессор считает.

Ну да! Это пока у вас всего пара таких переменных и когда одного размера/типа.

А когда их будет 100, да все разные - кто будет все эти 8,9,...,99 пересчитывать?

Посмотрите насколько удобнее и понятнее:

struct { //каждый байт структуры - страница FLASH
  char SFM_SET1;
  char SFM_SET2;
  ...
};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

//каждый байт структуры - страница FLASH

А если массив на 8 страниц?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

char massiv[8]; спасёт отца демократии? :rolleyes:

Сомнительной красоты решение.

А как вы потом превращаете эти переменные в адрес? А куда, вообще, компилятор положит эту громадную структуру? В какую память? Пардон, не настолько громадную... в 256 раз меньше, но все равно.

У меня код конфигурирования ПЛИС хранится в этой памяти. Половину объема занимает. Предлагаете мне килобайт ОЗУ или ПЗУ потратить для имитации SPI памяти? Можно определить тип структуры, но ее по некоему (нулевому?) адресу нужно прописать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я что то утерял нить повествования.

проблема в том что адрес не влезает в uint16_t. к примеру чтение по такому то адресу - сначала я передаю дами+17-ый бит а потом оставшиеся два байта.

 

ммм...в принципе количество блоков в данной памяти 2048. 17-й бит всегда будет 0. можно не париться я думаю.

post-71075-1529323261_thumb.png

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я что то утерял нить повествования.

проблема в том что адрес не влезает в uint16_t. к примеру чтение по такому то адресу - сначала я передаю дами+17-ый бит а потом оставшиеся два байта.

Храните 32-битовый адрес, а передавайте 24 бита из него. Порциями по 8 битов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Храните 32-битовый адрес, а передавайте 24 бита из него.

 

что то я туплю нипадецки. а как мне построить адрес - скажем последний блок 2048 - 0000 1000 0000 0000 - значит блок << 4 + адрес страницы << 6?

или нет - блок << 16 + адрес страницы << 22

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как вы потом превращаете эти переменные в адрес?

Макросом. Что сложного?

 

А куда, вообще, компилятор положит эту громадную структуру? В какую память? Пардон, не настолько громадную... в 256 раз меньше, но все равно.

Зачем он должен куда-то ложить???

Вы похоже не поняли.... Эта структура просто описывает размещение объектов внутри любой памяти. Формат размещения. Ничего никуда не кладётся.

Таким же образом я например адреса на CAN-шине распределяю.

И это всяко удобнее ручного пересчитывания всех смещений. И нагляднее.

 

Можно определить тип структуры, но ее по некоему (нулевому?) адресу нужно прописать.

Вы не поверите, но тип можно прописать даже без всего остального.

Вот это:

struct TVar {

...

};

в си называется объявлением типа TVar.

А вот это:

TVar var;

определение переменной типа TVar.

И Вы путаете эти два случая. Размещение в памяти делается только во 2-м случае.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я описываю структуры typedef-ми. Их точно никто никуда не кладет.

Адрес как берете? Макрос покажите. Как взять адрес того, что нигде не лежит?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я описываю структуры typedef-ми. Их точно никто никуда не кладет.

Во времена поголовно-си++ компиляторов typedef в этом случае - анахронизм. Ну если так больше нравится, то без разницы, можно и с typedef.

 

Адрес как берете? Макрос покажите. Как взять адрес того, что нигде не лежит?

Вроде всё очевидно..... :wacko:

struct DFLASH {
  u8 firmware[8];
  u8 fifoJournal1[6];
  u8 fifoJournal2[12];
  u8 fifoJournal3[7];
};
#define DFLASHoffset(member) ((size_t)&((DFLASH *)NULL)->member)
#define DFLASHsize(member) sizeof(((DFLASH *)NULL)->member)
#define DFLASHoffsetSize(member) DFLASHoffset(member), DFLASHsize(member)

в коде:

//Чтение len байт данных в *data из DFLASH начиная с адреса addr
void DflashRead(u32 addr, u32 len, void *data)
{
...
}

читаем первую страницу образа прошивки:

DflashRead(DFLASHoffset(firmware), DFLASHsize(firmware[0]), buf);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не вижу увеличения size на размер страницы.

Чем ваши [8], [6]... лучше моих * 8, * 9?

 

Мои функции проще.

void SfmData_read(uint8_t *pbuf, uint32_t addr, uint32_t num);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...