|
Представление адреса. Как лучше. |
|
|
|
Jun 18 2018, 10:04
|
Профессионал
    
Группа: Участник
Сообщений: 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
Эскизы прикрепленных изображений
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 24)
|
Jun 18 2018, 11:18
|

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

|
Цитата(jcxz @ Jun 18 2018, 14:10)  А когда нужно изменить размер какого-то элемента - пересчитываете все эти дефайны врукопашную? Опишите структуру своей флешь через 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) ... Предлагаете описать в виде структуры из массивов, а потом вытягивать адреса членов этой структуры? Можно и так. Зато я точно знаю, где что расположено и сколько страниц занимает, а вам считать придется. А вдруг переполните размер памяти?
|
|
|
|
|
Jun 18 2018, 11:30
|
Гуру
     
Группа: Свой
Сообщений: 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; ... };
|
|
|
|
|
Jun 18 2018, 12:01
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
я что то утерял нить повествования. проблема в том что адрес не влезает в uint16_t. к примеру чтение по такому то адресу - сначала я передаю дами+17-ый бит а потом оставшиеся два байта. ммм...в принципе количество блоков в данной памяти 2048. 17-й бит всегда будет 0. можно не париться я думаю.
Сообщение отредактировал Jenya7 - Jun 18 2018, 12:07
Эскизы прикрепленных изображений
|
|
|
|
|
Jun 18 2018, 12:24
|
Гуру
     
Группа: Свой
Сообщений: 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-м случае.
|
|
|
|
|
Jun 18 2018, 12:44
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Jun 18 2018, 15:28)  Я описываю структуры typedef-ми. Их точно никто никуда не кладет. Во времена поголовно-си++ компиляторов typedef в этом случае - анахронизм. Ну если так больше нравится, то без разницы, можно и с typedef. Цитата(ViKo @ Jun 18 2018, 15:28)  Адрес как берете? Макрос покажите. Как взять адрес того, что нигде не лежит? Вроде всё очевидно..... Код 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);
|
|
|
|
|
Jun 18 2018, 13:13
|
Гуру
     
Группа: Свой
Сообщений: 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]; }; А как будет у Вас? Приведите Ваш вариант? Цитата(ViKo @ Jun 18 2018, 15:56)  Мои функции проще. void SfmData_read(uint8_t *pbuf, uint32_t addr, uint32_t num); Функция у Вас точно такая же как у меня. Если больше нравится, то можно написать макрос SfmData_read, вызов которого будет выглядеть так же.
|
|
|
|
|
Jun 18 2018, 13:52
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Jun 18 2018, 16:29)  Ваша идея, скажем, хитровата, но мне не приглянулась. Больше информации нужно держать в голове. Выше вы уже продемонстрировали, что надо иметь в виду.  С моей идеей как раз в голове держать ничего не надо. Всё делает компилятор. А с вашей - всё считать и контролировать размеры вручную. И "раз формулы задать" - это видимо Вы гений разработки, что сразу предусматриваете все хотелки заказчиков, которые появятся в течение жизни прибора, что потом и редактировать не надо. И сжимать-оптимизировать не надо. Ну не все такие гении: в реальной жизни карту размещения приходится править постоянно. А бывает что исходники пишутся сразу для линейки разных устройств, и карта такая собирается из множества кусков #if/#else/#end. Кстати - как Ваш метод совместим с условной компиляцией? Вы и остальные переменные в программах тоже define-ами размещаете? Или всё-таки доверяете компоновщику?
|
|
|
|
|
Jun 19 2018, 06:17
|

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

|
Да, я гений. Я умею задать дефайнами размеры, варианты. Слышали такое: #ifdef, #else, #endif? Я сам себе заказчик, творю, что хочу. А если что-то предлагают, тоже делаю, если идет на пользу прибору. А что было вам не описать структуру с нормальными размерами? Повторю вопрос, как вы контролируете, что структура не вылезла за размеры памяти? Вот я знаю, сколько страниц в памяти, на столько и умножаю размер, не более.
|
|
|
|
|
Jun 19 2018, 07:36
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

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

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

|
Цитата(jcxz @ Jun 19 2018, 10:36)  В смысле? Вам надо объяснить как sizeof(struct FLASH) умножить на размер страницы?  Объясните, что написали здесь, это понятно, дайте ответ на вопрос. Где и когда вы сравниваете размер вашей структуры (в байтах, умноженных на размер страницы) и размер памяти? Кому вы доверяете эту процедуру, или просто забили, на авось? Да что там понимать? Не понятно только, зачем? Вы не могли в своей структуре задать размеры объектов, кратных размеру страницы? Умножение вам в помощь.
|
|
|
|
|
Jun 19 2018, 07:48
|
Гуру
     
Группа: Свой
Сообщений: 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]; }; }; Раз уж в теории никак не доходит, то может хоть на реальном примере дойдёт  Цитата(ViKo @ Jun 19 2018, 10:40)  Где и когда вы сравниваете размер вашей структуры (в байтах, умноженных на размер страницы) и размер памяти? Кому вы доверяете эту процедуру, или просто забили, на авось? Я эту "процедуру" доверяю стандартному инструменту, называемому assert_static. А Вы какому авосю доверяете?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|