Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Распределить память во внешней serial-FLASH
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
k155la3
Есть необходимость работы со структурно-организованными блоками данных во внешней флеш-памяти AT45DB081 мегабайтного порядка.
Т.е. адреса находятся не в области адресов контроллера. Инф. достаточно разношерстная, и регулярная (массивы структур), и нерегулярная (различные структуры).
------------
(?) Можно ли задать распределение памяти для этой области адресов в xxxxx.xcl файле ( выделив какой-либо "фиктивный" сегмент ).
------------
Сейчас задача решается вычитыванием из адреса FLASH_ADRESS ( FLASH_ADRESS - макро-переменная, считаются макросами IAR) блока данных в
RAM контроллера и работа с этим блоком через указатель нужного типа.
Из-за чего собственно.
- отказаться от счета адресов внешней флеш макросами. Вместо этого использовать распределение памяти через xcl-файл и математику указателей.
- получить на "выходе" загрузочную прошивку для внешней флеш.

Вопрос возомжно и обсуждался, но не знаю как правильно сформулировать "ключевые фразы".
scifi
Хочется заполнять внешнюю флешку данными из сишных исходников?
k155la3
Цитата(scifi @ Jan 14 2015, 19:52) *
Хочется заполнять внешнюю флешку данными из сишных исходников?


Это не основное, хотоя тоже хотелосьбы.
Основное - распределять память указательной математикой.
( В проекте, который мне дали, пришлось проверять все макросные расчеты вручную. Эти плюхи трудно искать.
И это приходится делать в век нано-технологий sm.gif
scifi
Цитата(k155la3 @ Jan 14 2015, 18:58) *
Основное - распределять память указательной математикой.

Для этого не нужен никакой линкер. Достаточно объявить указатели __data20 и делать арифметику с ними, а дальше оно само.
jcxz
Цитата(k155la3 @ Jan 14 2015, 21:58) *
( В проекте, который мне дали, пришлось проверять все макросные расчеты вручную. Эти плюхи трудно искать.
И это приходится делать в век нано-технологий sm.gif

Конечно это дебилизм так делать. Сам с таким сталкивался (понаписанным предыдущими "писателями").
Небольшое изменение структуры хранения - и сиди час пересчитывай все смещения заданные #define. А потом ещё три часа ищи где ошибся.
Не очень хорошо знаю семейство MSP430, но если там позволяет размер адресного пространства вместить всю ёмкость флешки, то конечно - объявляйте виртуальный сегмент и линкуйте в него переменные.

А можно и без линкера обойтись: объявляете структуру, которая у Вас и будет представлять образ памяти флешки. В неё размещаете переменные, находящиеся в SPI-флешь:
Код
struct FlashMap {
  struct Var1 var10, var11;
  struct Var2 var20, var21;
  u32 a, b, c;
  ...
};
А потом используете смещения членов от начала виртуального образа:
Код
#define PtrFlashMap ((FlashMap *)NULL)
#define OffsetMemberFlashMap(member) ((char *)&PtrFlashMap->member - (char *)PtrFlashMap)
#define SizeMemberFlashMap(member) sizeof(PtrFlashMap->member)
Func1(OffsetMemberFlashMap(var21), SizeMemberFlashMap(var21));
...
У меня так во многих проектах с SPI-флешь сделано. Правда под 32-битные CPU.
ViKo
А если flash-память должна стираться страницами, секторами? Как это учесть при распределении?
Как-то, представлять каждую независимую переменную в виде объединения с массивом, длиной в страницу. Моя флэш имеет страницы по 256 байтов.
scifi
Цитата(jcxz @ Jan 15 2015, 08:04) *
Код
#define OffsetMemberFlashMap(member) ((char *)&PtrFlashMap->member - (char *)PtrFlashMap)

Зачем изобретать свой велосипед? Есть же православный offsetof().
jcxz
Цитата(ViKo @ Jan 15 2015, 12:03) *
А если flash-память должна стираться страницами, секторами? Как это учесть при распределении?
Как-то, представлять каждую независимую переменную в виде объединения с массивом, длиной в страницу. Моя флэш имеет страницы по 256 байтов.

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

Цитата(scifi @ Jan 15 2015, 13:13) *
Зачем изобретать свой велосипед? Есть же православный offsetof().

не знал. Буду иметь в виду. Спасибо!
Хотя - это то же самое.
ViKo
Цитата(jcxz @ Jan 15 2015, 11:04) *
Зачем это учитывать при распределении??? Процедура (драйвер) записывающая данные, определяет границы модифицируемой области, сохраняет те части
от соседних областей, которые должны сохраниться, сохраняет их, восстанавливает после стирания.
Мне кажется здесь всё очевидно.

Я учитываю. У меня памяти много, а данных мало.
Т.е., можно прочитать страницу, изменить то, что нужно, стереть страницу, записать.
jcxz
Цитата(ViKo @ Jan 15 2015, 15:16) *
Т.е., можно прочитать страницу, изменить то, что нужно, стереть страницу, записать.

Можно даже дописать. Если для каждого модифицируемого байта верно условие: !(~*oldDataPtr & *newDataPtr & 255)
k155la3
Цитата(scifi @ Jan 14 2015, 20:25) *
Для этого не нужен никакой линкер. Достаточно объявить указатели __data20 и делать арифметику с ними, а дальше оно само.


Понял. будем попробовать.

Цитата(jcxz @ Jan 15 2015, 09:04) *
Конечно это дебилизм так делать. Сам с таким сталкивался (понаписанным предыдущими "писателями").
Небольшое изменение структуры хранения - и сиди час пересчитывай все смещения заданные #define. А потом ещё три часа ищи где ошибся.
Не очень хорошо знаю семейство MSP430, но если там позволяет размер адресного пространства вместить всю ёмкость флешки, то конечно - объявляйте виртуальный сегмент и линкуйте в него переменные.

А можно и без линкера обойтись: объявляете структуру, которая у Вас и будет представлять образ памяти флешки. В неё размещаете переменные, находящиеся в SPI-флешь:
Код
struct FlashMap {
  struct Var1 var10, var11;
  struct Var2 var20, var21;
  u32 a, b, c;
  ...
};
А потом используете смещения членов от начала виртуального образа:
Код
#define PtrFlashMap ((FlashMap *)NULL)
#define OffsetMemberFlashMap(member) ((char *)&PtrFlashMap->member - (char *)PtrFlashMap)
#define SizeMemberFlashMap(member) sizeof(PtrFlashMap->member)
Func1(OffsetMemberFlashMap(var21), SizeMemberFlashMap(var21));
...
У меня так во многих проектах с SPI-флешь сделано. Правда под 32-битные CPU.


Спасибо за примеры.
зы - за макросы и IAR. Наряду с человеческими ошибками был еще труднонаходимый глюк самого IAR - из-за большой вложенности макросов, вычисление адреса слетало, хотя по синтаксису все было правильно.
#define pH1 (pB4 + _floatCRC)
#define pH2 (pH1 + _floatCRC)
#define pQ1 (pH1 + _floatCRC) <<<< это гуманитарная ошибка sm.gif
#define pQ2 (pQ1 + _floatCRC)
#define pQ3 (pQ2 + _floatCRC)
#define pKQN1 (pQ3 + _floatCRC)
#define pKQN2 (pKQN1 + _floatCRC)
#define pKQN3 (pKQN2 + _floatCRC)
итд

Цитата(ViKo @ Jan 15 2015, 10:03) *
А если flash-память должна стираться страницами, секторами? Как это учесть при распределении?
Как-то, представлять каждую независимую переменную в виде объединения с массивом, длиной в страницу. Моя флэш имеет страницы по 256 байтов.


это проблема драйверного (для конкретной мс флеш) модуля.
Адресации в линейном простр-ве адресов - это одна задача.
Логика управления режимом записи/стирания - это вторая задача. К распределению адресов оно как-бы отношения не имеет.
(разве что выравнивание на границы страниц/блоков).
----
Это все IMHO.



Цитата(scifi @ Jan 15 2015, 11:13) *
Зачем изобретать свой велосипед? Есть же православный offsetof().


я его тоже использую. В частности для отладочных утилит на PC под VisualStud.
В IAR (MSP430) можно и указатели повычитать, а в PC вычитать адреса форменный идиотизм.

Цитата(jcxz @ Jan 15 2015, 12:04) *
. . .
не знал. Буду иметь в виду. Спасибо!
Хотя - это то же самое.


насчет тогожесамого. Адресное простр-во может быть сегментировано.
Думаю все-таки offsetof более феншуй.
т.е. смотря какой процессор-компилятор.


Спасибо за ответы. попробуем

Цитата(scifi @ Jan 14 2015, 20:25) *
Для этого не нужен никакой линкер. Достаточно объявить указатели __data20 и делать арифметику с ними, а дальше оно само.

jcxz
Цитата(k155la3 @ Jan 15 2015, 18:45) *
В IAR (MSP430) можно и указатели повычитать, а в PC вычитать адреса форменный идиотизм.
Это идиотизм в любом случае, когда имеется компилятор и линкёр - пытаться делать их работу за них.
Для того и были придуманы компиляторы и линкёры, чтобы вручную смещения не считать.

Цитата(k155la3 @ Jan 15 2015, 18:45) *
насчет тогожесамого. Адресное простр-во может быть сегментировано.
Думаю все-таки offsetof более феншуй.
А причём тут сегментированность пространства??? wacko.gif
Он вычисляет смещение члена структуры относительно её начала (точно так же как и мои макросы).
А структуры никак не могут быть сегментированы.
scifi
Цитата(jcxz @ Jan 16 2015, 08:24) *
А причём тут сегментированность пространства??? wacko.gif
Он вычисляет смещение члена структуры относительно её начала (точно так же как и мои макросы).
А структуры никак не могут быть сегментированы.

Там другая проблема, если верить Википедии, - разыменование нулевого указателя (что вызывает неопределённое поведение).
k155la3
Цитата(jcxz @ Jan 16 2015, 08:24) *
Это идиотизм в любом случае, когда имеется компилятор и линкёр - пытаться делать их работу за них.
Для того и были придуманы компиляторы и линкёры, чтобы вручную смещения не считать.

А причём тут сегментированность пространства??? wacko.gif
Он вычисляет смещение члена структуры относительно её начала (точно так же как и мои макросы).
А структуры никак не могут быть сегментированы.


ну, за сегментированность я может и загнул. В смысле x86 процессора, когда одному физ.адресу могут соответствовать
указатели с разным содержимым. Так как здесь обсуждается IAR "в целом", а я не знаю механизмов адресации
конкретного target-процессора.

вот посмотрел по наводке scfi
------------------------------------- ( IAR MSP430 )
ifndef offsetof
define offsetof(T, member) (__INTADDR__((&((T *)0)->member)))
endif /* offsetof */

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.