Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Линковщик и внешняя оперативная память
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Novichok1
Доброго времени суток!
Работаю с LPC2478, у которого, как известно, есть внешние банки динамической памяти.
Так вот, возникла надобность указать линковщику, что у нас оперативная память не только на чипе, но еще и внешняя. Вопрос - как это сделать?
Дело в том, что нужно указать не один диапазон адресов, а хотя бы два, как это сделать, я не знаю. Другой вариант решения - покопаться с оператором "new" (C++), и в нем указать требуемый диапазон. Но я не знаю, как и это сделать(.
Буду рад любой помощи, заранее спасибо!
Novichok1
Неужели никто не сталкивался с подобными задачами? Может я неправильно сформулировал, попробую еще раз: мне надо указать линковщику дополнительный диапазон памяти, где он должен создавать переменные, ну или хотя бы только динамически создаваемы объекты. Как это можно сделать? Напрашивается корректировка скрипта для линковщика, но ни подробной документации по синтаксису и семантики этих скриптов, ни подобных примеров, где бы использовались несколько диапазонов для оперативной памяти я, к сожелению не нашел( Если есть какие - нибудь мысли, или полезные ссылки, пожалуйста, отпишитесь)
Dog Pawlowa
Полезная мысль - указать какой компилятор/линковщик Вы используете.
Вторая полезная мысль - поискать на форуме. Как раз недавно один коллега пришел к выводу, что использование линковщика вовсе необязательно и написал, как именно он сделал.
Novichok1
Использую GCC v.4.2.2.
KRS
так надо линкер скрипт написать
доки например здесь есть
http://www.delorie.com/gnu/docs/binutils/ld_6.html
Novichok1
Цитата
Вторая полезная мысль - поискать на форуме. Как раз недавно один коллега пришел к выводу, что использование линковщика вовсе необязательно и написал, как именно он сделал


Спасибо за совет. Пока из более- менее сродного нашел только http://electronix.ru/forum/index.php?showtopic=58599&hl=, но там кажись IAR. Ну и задачи разные ставяться. Будем дальше искать.

Цитата
так надо линкер скрипт написать
доки например здесь есть
http://www.delorie.com/gnu/docs/binutils/ld_6.html


Спасибо за ссылочку - буду учить матчасть.
zltigo
Цитата(Novichok1 @ Oct 20 2009, 11:49) *
Так вот, возникла надобность указать линковщику...
..
покопаться с оператором "new" (C++), и ...

Для начала та память, которую статически распределяет линкер и динамическая память в общем случае вещи малосвязанные. Посему сразу можете начинать копать ту конкретную реализацию new() на предмет того, что она вообще умеет штатно.
skripach
Цитата
Спасибо за совет. Пока из более- менее сродного нашел только http://electronix.ru/forum/index.php?showtopic=58599&hl=, но там кажись IAR. Ну и задачи разные ставяться. Будем дальше искать

Вот
Novichok1
To skripach:
Спасибо за ссылочку, но там IAR, а у меня GCC, ну и метод, к которому вы там пришли мне не подходит по идеологическим соображениям)
Просто мне нужно не просто разместить во внешней оперативке одну структуру, а постоянно работать в той области памяти. А обязанности линкера я не потяну.
Но я смотрю, Вы тоже были озабочены аналогичной проблемой, хотелось бы знать, есть ли какие - нибудь результаты, помимо освещенных в Вашей ветке?
zltigo
Цитата(Novichok1 @ Oct 22 2009, 10:44) *
А обязанности линкера я не потяну.

И не надо, просто скажите ему какими областями памяти он может распоряжаться. Однако, насколько я могу догадываться, Вы хотите динамически выделять память, к этому линкер, как я уже писал, вообще отношения не имеет - этим занимается менеджер памяти ВО ВРЕМЯ РАБОТЫ ПРИЛОЖЕНИЯ.
skripach
Цитата
есть ли какие - нибудь результаты, помимо освещенных в Вашей ветке?

пока нет, будут - поделюсь.
Novichok1
Цитата
И не надо, просто скажите ему какими областями памяти он может распоряжаться. Однако, насколько я могу догадываться, Вы хотите динамически выделять память, к этому линкер, как я уже писал, вообще отношения не имеет - этим занимается менеджер памяти ВО ВРЕМЯ РАБОТЫ ПРИЛОЖЕНИЯ.


Ну я уже понял, что глобальным и статическим переменным адреса выделяются в секциях .data и .bss (надеюсь, что правильно понял), а выделение памяти в куче происходит посредством выполнения оператора 'operator new'. А вот выделение памяти под локальные переменные, либо не статические члены класса происходит в стеке. И следующий момент, который нужно отметить - инициализация внешней памяти происходит внутри программы, то есть до этой инициализации никто туда не должен лезть, значит секции .data и .bss должны быть расположены во внутренней оперативке.

Ситуация, значит, вырисовывается такая: поскольку on-chip RAM всего 64KB, а внешняя оперативка несравнимо больше, и к тому же данные, которые требуются хранить довольно громоздкие, то их объявление как глобальных, и таким образом запись либо в секцию .data, либо в секцию .bss является плохим решением. Значит эти данные нужно объявить как локальные (либо не статическими членами класса). Это можно сделать двумя способами:
1) Объявить их в стеке;
2) Объявить их в куче посредством "new".

В первом случае не надо копать "operator new", второй более предпочтителен, но нужно разобрать "operator new". Но в обоих случаях нужно указать линковщику, что есть еще дополнительная оперативка, чего я пока не знаю(.

Надеюсь приведенные рассуждения правильные, если где- то ошибка, попрошу поправить.
И было бы замечательно, если кто - нибудь приведет пример указанию линковщику нескольких диапазонов оперативной памяти.
KRS
Цитата(Novichok1 @ Oct 22 2009, 13:11) *
И следующий момент, который нужно отметить - инициализация внешней памяти происходит внутри программы, то есть до этой инициализации никто туда не должен лезть, значит секции .data и .bss должны быть расположены во внутренней оперативке.

Нет не значит!
И более того даже инициализацию секции .bss можно на С написать, посмотрите для примера IAR cstartup.
Novichok1
Цитата
Нет не значит!


Спасибо, KRS, вывели меня из ступора. Так действительно, при направлении .bss на внешнюю рамку, адреса не инициализированных глобальных переменных лежат где надо! И тут пришло время слов уважаемого zltigo. А именно, выскакивает ошибка "Pabort exception !!!" при попытке в программе динамически выделить память для указанной переменной через "new". Подскажите, пожалуйста, как в нем копаться и что там нужно исправлять.


Вообще, не совсем понятно, зачем нужно копаться во внутренностях "new", на мой взгляд должно быть достаточно указать линковщику, как уже говорилось, два диапазона адресов для использования в качестве оперативной памяти, а уже сам "new" должен смотреть какие адреса допустимы, и сколько и где выделять. Если не прав- поправьте, а если прав, то как и где все - таки указать эти два диапазона? Насчет "где" по моему есть два варианта
1) Linker script (секции .data и .bss по ходу отпадают)
2) startup.s (там вроде что- то записывается, связанное с адресам оперативной памяти)
zltigo
Цитата(Novichok1 @ Oct 22 2009, 14:30) *
а уже сам "new" должен смотреть какие адреса допустимы, и сколько и где выделять.

А new об этом знает? Или Вы все это за его авторов решили? Уже писал - надо смотреть на конкретную реализацию.
Novichok1
Ну так где указывать допустимые адреса, не в самом же "new"?
Step_ARM
Цитата(Novichok1 @ Oct 22 2009, 13:11) *
Ситуация, значит, вырисовывается такая: поскольку on-chip RAM всего 64KB, а внешняя оперативка несравнимо больше, и к тому же данные, которые требуются хранить довольно громоздкие, то их объявление как глобальных, и таким образом запись либо в секцию .data, либо в секцию .bss является плохим решением. Значит эти данные нужно объявить как локальные (либо не статическими членами класса). Это можно сделать двумя способами:
1) Объявить их в стеке;
2) Объявить их в куче посредством "new".

А почему все так замороченно?
Разве нельзя, ничего не указывая линкеру, объявить указатель, а потом присвоить ему адрес во внешней памяти.
typedef struct
{
UInt32 a;
UInt32 b;
UInt32 mass[1024];

} struct_1, *struct_1;

struct_1=Адрес;

А отдельные переменные так -- #define temp (*((DWORD*)Адрес)) -- здесь ошибка возможна только если обратиться к этой переменной до инита внешней памяти....
Novichok1
Ну, этим методом хорошо пользоваться, когда у вас есть небольшое количество определенных структура данных и известно их количество. Я, например, пользуюсь им для использования двойного буфера у LCD. А если их количество не известно, и к тому же используются классы, то тут возникает ряд проблем:
1)Нужно как-то размещать класс по определенному адресу, тут уже class_1=Адрес не пройдет
2)Нужно контролировать "Адрес", то есть брать на себя обязанности диспетчера памяти.

Может я неправильно выразил свое желание, попробую сформулировать его еще раз: есть внутренняя и внешняя оперативка, и нужно использовать эти две области памяти в качестве оперативной памяти для программы, то есть при объявлении переменных и классов они должны размещаться в одной из этих областей. Также допустимо, чтобы только динамически создаваемые объекты размещались во внешней памяти, а остальные во внутренней.

Начинаю копать оператор "new", но пока ничего путного на глаза не попадается.
zltigo
Цитата(Novichok1 @ Oct 23 2009, 08:34) *
Начинаю копать оператор "new", но пока ничего путного на глаза не попадается.

Можно и не копать, а сразу на "свой" менежер поменять. Менеджеры на форуме обсуждались неоднократно, от простых до навороченных. Я как-то и исходники своего постил и критерии такой реализации излагал, кстати он конкретно поддерживает и фрагментированную память.
Novichok1
Спасибо большое всем откликнувшимся, в особенности zltigo! Сейчас вхожу в стадию отладки.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.