реклама на сайте
подробности

 
 
> Представление адреса. Как лучше.
Jenya7
сообщение Jun 18 2018, 10:04
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



У меня при обращении к памяти (чтение, запись) нужно передавать адрес. Адрес состоит из нескольких составляющих (на картинке).Изначально была такая конструкция
Код
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-битный. то есть возникает тот же гемор сдвигать влево а потом вправо. или я что то упускаю?

Сообщение отредактировал Jenya7 - Jun 18 2018, 10:04
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 24)
ViKo
сообщение Jun 18 2018, 11:03
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Задаю дефайнами нужные мне адреса в SPI flash, выравненные по началу страниц, и использую их в виде целого числа.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 18 2018, 11:10
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 18 2018, 14:03) *
Задаю дефайнами нужные мне адреса в SPI flash, выравненные по началу страниц, и использую их в виде целого числа.

А когда нужно изменить размер какого-то элемента - пересчитываете все эти дефайны врукопашную? biggrin.gif
Опишите структуру своей флешь через struct {...} и не конкурируйте с компилятором - времена рукопашной компоновки памяти давно прошли.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 18 2018, 11:18
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Jun 18 2018, 14:10) *
А когда нужно изменить размер какого-то элемента - пересчитываете все эти дефайны врукопашную? biggrin.gif
Опишите структуру своей флешь через 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)
...


Предлагаете описать в виде структуры из массивов, а потом вытягивать адреса членов этой структуры? Можно и так. Зато я точно знаю, где что расположено и сколько страниц занимает, а вам считать придется. А вдруг переполните размер памяти?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 18 2018, 11:30
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 18 2018, 14:18) *
Зачем вручную? Препроцессор считает.

Ну да! Это пока у вас всего пара таких переменных и когда одного размера/типа.
А когда их будет 100, да все разные - кто будет все эти 8,9,...,99 пересчитывать?
Посмотрите насколько удобнее и понятнее:
Код
struct { //каждый байт структуры - страница FLASH
  char SFM_SET1;
  char SFM_SET2;
  ...
};
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 18 2018, 11:35
Сообщение #6


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Jun 18 2018, 14:30) *
//каждый байт структуры - страница FLASH

А если массив на 8 страниц?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 18 2018, 11:39
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 18 2018, 14:35) *
А если массив на 8 страниц?

char massiv[8]; спасёт отца демократии? rolleyes.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 18 2018, 11:45
Сообщение #8


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Jun 18 2018, 14:39) *
char massiv[8]; спасёт отца демократии? rolleyes.gif

Сомнительной красоты решение.
А как вы потом превращаете эти переменные в адрес? А куда, вообще, компилятор положит эту громадную структуру? В какую память? Пардон, не настолько громадную... в 256 раз меньше, но все равно.
У меня код конфигурирования ПЛИС хранится в этой памяти. Половину объема занимает. Предлагаете мне килобайт ОЗУ или ПЗУ потратить для имитации SPI памяти? Можно определить тип структуры, но ее по некоему (нулевому?) адресу нужно прописать.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 18 2018, 12:01
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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

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

Сообщение отредактировал Jenya7 - Jun 18 2018, 12:07
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 18 2018, 12:12
Сообщение #10


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Jenya7 @ Jun 18 2018, 15:01) *
я что то утерял нить повествования.
проблема в том что адрес не влезает в uint16_t. к примеру чтение по такому то адресу - сначала я передаю дами+17-ый бит а потом оставшиеся два байта.

Храните 32-битовый адрес, а передавайте 24 бита из него. Порциями по 8 битов.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 18 2018, 12:16
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(ViKo @ Jun 18 2018, 18:12) *
Храните 32-битовый адрес, а передавайте 24 бита из него.


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

Сообщение отредактировал Jenya7 - Jun 18 2018, 12:18
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 18 2018, 12:24
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 18 2018, 14:45) *
А как вы потом превращаете эти переменные в адрес?

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

Цитата(ViKo @ Jun 18 2018, 14:45) *
А куда, вообще, компилятор положит эту громадную структуру? В какую память? Пардон, не настолько громадную... в 256 раз меньше, но все равно.

Зачем он должен куда-то ложить???
Вы похоже не поняли.... Эта структура просто описывает размещение объектов внутри любой памяти. Формат размещения. Ничего никуда не кладётся.
Таким же образом я например адреса на CAN-шине распределяю.
И это всяко удобнее ручного пересчитывания всех смещений. И нагляднее.

Цитата(ViKo @ Jun 18 2018, 14:45) *
Можно определить тип структуры, но ее по некоему (нулевому?) адресу нужно прописать.

Вы не поверите, но тип можно прописать даже без всего остального.
Вот это:
struct TVar {
...
};
в си называется объявлением типа TVar.
А вот это:
TVar var;
определение переменной типа TVar.
И Вы путаете эти два случая. Размещение в памяти делается только во 2-м случае.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 18 2018, 12:28
Сообщение #13


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Я описываю структуры typedef-ми. Их точно никто никуда не кладет.
Адрес как берете? Макрос покажите. Как взять адрес того, что нигде не лежит?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 18 2018, 12:44
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 18 2018, 15:28) *
Я описываю структуры typedef-ми. Их точно никто никуда не кладет.

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

Цитата(ViKo @ Jun 18 2018, 15:28) *
Адрес как берете? Макрос покажите. Как взять адрес того, что нигде не лежит?

Вроде всё очевидно..... wacko.gif
Код
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);
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 18 2018, 12:56
Сообщение #15


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Не вижу увеличения size на размер страницы.
Чем ваши [8], [6]... лучше моих * 8, * 9?

Мои функции проще.
void SfmData_read(uint8_t *pbuf, uint32_t addr, uint32_t num);
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 18 2018, 13:13
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 18 2018, 15:56) *
Не вижу увеличения size на размер страницы.

Да, там в комментарии надо читать как "Чтение len страниц", а не байт. Ну или на размер умножить.

Цитата(ViKo @ Jun 18 2018, 15:56) *
Чем ваши [8], [6]... лучше моих * 8, * 9?

Наглядностью. Это у Вас сейчас там два элемента. А когда будет больше? Да ещё и вложенные? У меня будут просто вложенные структуры, а у Вас - сложные формулы для вычисления адресов.
Если скажем внутри вашей флешь вам нужно разместить скажем три разных сложных объекта такой структуры:
Код
struct JournalTyp1 { //каждая запись журнала занимает 2 страницы флешь
  u8 head;
  u16p8 fifo[16];
};
и два таких:
Код
struct JournalTyp2 { //каждая запись журнала занимает 1 страницу флешь
  struct Record {  //формат записи журнала
    u8 typ;
    u8 sost;
    u8 data1[1000];
    u8 data1[1517];  
  };
  u8 head;
  u8 map;
  u8 flags;
  u8 fifo[16][(sizeof(Record) + PAGESIZE - 1) / PAGESIZE];
};
среди прочих объектов.
То у меня структура флешь будет выглядеть просто и наглядно:
Код
struct DFLASH {
  JournalTyp1 journalAA;
  JournalTyp1 journalAB;
  JournalTyp2 journalBA;
  u8 firmware[80];
  u8 reserved1[100];
  JournalTyp1 journalAC;
  u8 someData1[10];
  JournalTyp2 journalBB;
  u8 someData2[11];
};
А как будет у Вас? Приведите Ваш вариант? rolleyes.gif

Цитата(ViKo @ Jun 18 2018, 15:56) *
Мои функции проще.
void SfmData_read(uint8_t *pbuf, uint32_t addr, uint32_t num);

Функция у Вас точно такая же как у меня. Если больше нравится, то можно написать макрос SfmData_read, вызов которого будет выглядеть так же.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 18 2018, 13:29
Сообщение #17


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Мне раз формулы задать, сложностей не вижу. Объектов у меня два десятка. Пока в каждой странице не более одного объекта. Есть объекты на много страниц.
Зато потом, не напрягаясь, пользуюсь определенными адресами.
В конце концов, любую структуру можно привести к указателю на массив char.
Ваша идея, скажем, хитровата, но мне не приглянулась. Больше информации нужно держать в голове. Выше вы уже продемонстрировали, что надо иметь в виду. rolleyes.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 18 2018, 13:52
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 18 2018, 16:29) *
Ваша идея, скажем, хитровата, но мне не приглянулась. Больше информации нужно держать в голове. Выше вы уже продемонстрировали, что надо иметь в виду. rolleyes.gif

С моей идеей как раз в голове держать ничего не надо. Всё делает компилятор. А с вашей - всё считать и контролировать размеры вручную.
И "раз формулы задать" - это видимо Вы гений разработки, что сразу предусматриваете все хотелки заказчиков, которые появятся в течение жизни прибора, что потом и редактировать не надо. И сжимать-оптимизировать не надо. Ну не все такие гении: в реальной жизни карту размещения приходится править постоянно. А бывает что исходники пишутся сразу для линейки разных устройств, и карта такая собирается из множества кусков #if/#else/#end. Кстати - как Ваш метод совместим с условной компиляцией? cool.gif
Вы и остальные переменные в программах тоже define-ами размещаете? Или всё-таки доверяете компоновщику? biggrin.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 19 2018, 06:17
Сообщение #19


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Да, я гений. Я умею задать дефайнами размеры, варианты. Слышали такое: #ifdef, #else, #endif?
Я сам себе заказчик, творю, что хочу. А если что-то предлагают, тоже делаю, если идет на пользу прибору.
А что было вам не описать структуру с нормальными размерами?
Повторю вопрос, как вы контролируете, что структура не вылезла за размеры памяти? Вот я знаю, сколько страниц в памяти, на столько и умножаю размер, не более.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 19 2018, 07:36
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 19 2018, 09:17) *
Повторю вопрос, как вы контролируете, что структура не вылезла за размеры памяти?

В смысле? Вам надо объяснить как sizeof(struct FLASH) умножить на размер страницы? wacko.gif
И что значит "нормальные размеры"? Структура у меня описывается теми элементами, которыми идёт распределение памяти.
Если память распределяется байтами (в тех случаях, когда так и нужно), то каждый байт структуры == байту в памяти; если страницами - каждый байт структуры == странице; если секторами (стирания) - каждый байт структуры == сектору.
Эта структура задаёт не какую-то переменную в памяти, она задаёт ПОРЯДОК РАСПРЕДЕЛЕНИЯ ДАННОГО РЕСУРСА (СТРАНИЦ В НЕКОЕЙ ПАМЯТИ)!! Вы похоже этого никак понять не можете. Зациклились на каких-то переменных в памяти.... Причём они тут??? wacko.gif
Точно так же например у меня структурой задаётся распределение пространства адресов на CAN-шине. Тоже никаких переменных данного типа при этом не создаётся.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 19 2018, 07:40
Сообщение #21


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Jun 19 2018, 10:36) *
В смысле? Вам надо объяснить как sizeof(struct FLASH) умножить на размер страницы? wacko.gif

Объясните, что написали здесь, это понятно, дайте ответ на вопрос. Где и когда вы сравниваете размер вашей структуры (в байтах, умноженных на размер страницы) и размер памяти? Кому вы доверяете эту процедуру, или просто забили, на авось?
Да что там понимать? Не понятно только, зачем? Вы не могли в своей структуре задать размеры объектов, кратных размеру страницы? Умножение вам в помощь.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 19 2018, 07:48
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 19 2018, 09:17) *
Да, я гений. Я умею задать дефайнами размеры, варианты. Слышали такое: #ifdef, #else, #endif?

Гений, знающий про ifdef, вот Вам пример из конкретного коммерческого проекта (ПО для линейки устройств). Покажите пожалуйста как вы сделаете распределение страниц FLASH в Вашем стиле?
А мы посмотрим - чей вариант нагляднее и читаемее.
Код
//каждый байт структуры соответствует странице DFLASH
union DFLASH {
  struct {
    u8 nastr[8];
    u8 jrnDayEnergy[10];
    u8 jrnMonthEnergy[5];
    u8 jrnEventFwUpdate[2];
    u8 jrnEventSetPwd[2];
    u8 jrnEventAccessDeny[2];
    u8 jrnEventTamper[2];
    u8 jrnEventClearEnergy[2];
    u8 jrnProfilePower[700];
    u8 jrnProfileBillingData1[39];
    u8 jrnProfileBillingData2[73];
    #if FIRMWARE_TARGET == FIRMWARE_TARGET_S04 || FIRMWARE_TARGET == FIRMWARE_TARGET_S07
    u8 jrnProfile_phase_A[510];
    u8 jrnProfile_phase_B[510];
    u8 jrnProfile_phase_C[510];
    u8 jrnProfileBillingData1_A[36];
    u8 jrnProfileBillingData2_A[64];
    u8 jrnProfileBillingData1_B[36];
    u8 jrnProfileBillingData2_B[64];
    u8 jrnProfileBillingData1_C[36];
    u8 jrnProfileBillingData2_C[64];
    #ifdef PKE
    u8 jrnEvent_PKE[2002];                 //Журнал текущих данных ПКЭ
    u8 jrnEvent_PKE_PandP[34];             //Журнал провалов,прерываний напряжения и перенапряжений
    u8 jrnEvent_PKEStatistic[368];         //Общий статистический журнал событий ПКЭ
    u8 jrnEvent_PKE_PandP_statistic[124];  //Журнал статистики по провалам, прерываниям, перенапряжениям
    #endif  //PKE
    #endif
    u8 jrnEventCosem[45];
    u8 jrnEventMonitorRegister[45];
    u8 jrnEventMeterConfiguration[45];
    #if FIRMWARE_TARGET == FIRMWARE_TARGET_S07
    u8 jrn_change_transformation_coefficient[10];
    #endif
    u8 jrn_Events_not_erase[10];
    u8 unuse0[FIRM_BUF_SIZE];  //резерв для DFLASH::firmware
  };
  struct {
    u8 unuse1[DF_N_PAGES - FIRM_BUF_SIZE];
    u8 firmware[FIRM_BUF_SIZE];
  };
};

Раз уж в теории никак не доходит, то может хоть на реальном примере дойдёт rolleyes.gif

Цитата(ViKo @ Jun 19 2018, 10:40) *
Где и когда вы сравниваете размер вашей структуры (в байтах, умноженных на размер страницы) и размер памяти? Кому вы доверяете эту процедуру, или просто забили, на авось?

Я эту "процедуру" доверяю стандартному инструменту, называемому assert_static.
А Вы какому авосю доверяете? wink.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 19 2018, 08:03
Сообщение #23


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Замените в моих
#define SFM_SET1 (SFM_SYSTEM_BASE + SFM_PAGESIZE * 8)
цифры на ваши (можете отдельными дефайнами высчитать позицию страницы, складывая предыдущую позицию и количество страниц, занимаемых объектом), и получите точные адреса.
А мне и assert не нужен, я глазами вижу количество используемых страниц.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 19 2018, 08:37
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 19 2018, 11:03) *
Замените в моих

Ага, значит в кусты. laughing.gif

Цитата(ViKo @ Jun 19 2018, 11:03) *
А мне и assert не нужен, я глазами вижу количество используемых страниц.

Т.е. - доверяете Авосю? Авось пронесёт. Всё ясно с Вашими методами "программирования"... laughing.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 19 2018, 08:39
Сообщение #25


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



В кусты, так в кусты. Собственно, всё уже выяснили.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 12:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01651 секунд с 7
ELECTRONIX ©2004-2016