Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC23XX. Запуск программы в RAM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Step_ARM
Задача следующая. Надо Загрузить с внешнего носителя (датафлэш ,SD) программу в RAM и запустить в RAM из программы на флэш.
Наверняка кто-нибудь делал это? Подскажет кто-нибудь как это сделать?
HARMHARM
Если Вам нужно загрузить одну такую программу, или несколько однотипных, то можно линковать её статически на определенные адреса в памяти к определенной версии программы во флеше. Похоже на работу с загрузчиком во флеш...
Иначе придется использовать Dynamic Linking, точно как программы на ПК загружаются. Посмотрите также ELF, есть его спецификация для ARM. Для ARM7 имхо сложновато будет.
Step_ARM
Я может чего-то не понимаю...
Если взять обычную программу объемом к примеру 3-4кБ, указать при ините режим работы в оперативке, скомпилить ее с указанием адресов в памяти 0х40000040(для таблицы векторов).
Указать точку входа -- адрес 0х40000040.
Разве так не будет работать?
Как же тогда работает программа загрузчик через JTAG она ведь грузится в оперативку?
Дело в том , что мне не важно что произойдет с программой на флэш.
Всвязи с этим еще возникает вопрос -- как программно запустить исполняемую программу сначала т.е. с нулевого адреса флэш?
meister
Цитата(Step_ARM @ May 25 2009, 11:07) *
Всвязи с этим еще возникает вопрос -- как программно запустить исполняемую программу сначала т.е. с нулевого адреса флэш?


Код
MOV pc, #0;


Код
((void (*)(void))0)();
Step_ARM
Цитата(meister @ May 25 2009, 11:16) *
Код
MOV pc, #0;


Код
((void (*)(void))0)();

Действительно
start=(void (*)(void))START_ADDR;
start();
запускает программу заново.
KRS
Цитата(Step_ARM @ May 25 2009, 11:23) *
Действительно
start=(void (*)(void))START_ADDR;
start();
запускает программу заново.


Опасный способ, потому что обычно, когда проц начинает исполнять программу с Reset Vectora он вышел из ресета ( переферрия выключена...). IMHO лучше использовать программный сброс! ( Например при помощи watchdog или другие механизмы бывают...)
Step_ARM
Цитата(KRS @ May 25 2009, 12:02) *
Опасный способ, потому что обычно, когда проц начинает исполнять программу с Reset Vectora он вышел из ресета ( переферрия выключена...). IMHO лучше использовать программный сброс! ( Например при помощи watchdog или другие механизмы бывают...)

Я делал не с ресета, с адреса фактически исполняемого кода-- нормально. Прога заново все инитит и все...
Но от темы мы все-таки уклонились -- читай [1] и [3].
KRS
Так по теме все просто!
Делаете программу для RAM, можно и отлаживать прямо в RAM ( среды разработки это позволяют, с помощью макросов при старте отладки инитится RAM, remap...).
Потом полученных hex файл, конвертируете в нужный вам формат...
А бутлоадер ( или другая ваша программа) инитит RAM, remap.... грузит файл в память и запускает. ( По принципу как и отладка прямо в рам).
Step_ARM
Цитата(KRS @ May 25 2009, 12:42) *
Так по теме все просто!
Делаете программу для RAM, можно и отлаживать прямо в RAM ( среды разработки это позволяют, с помощью макросов при старте отладки инитится RAM, remap...).
Потом полученных hex файл, конвертируете в нужный вам формат...
А бутлоадер ( или другая ваша программа) инитит RAM, remap.... грузит файл в память и запускает. ( По принципу как и отладка прямо в рам).

Ну наверное не все так просто... Сделал я программу для RAM. В дебаггере запускается, выводит на индикатор сообщение. Смотрю память -- действительно прога там висит и флэш нетронута.
Далее мои действия:
1. Записать на внешний носитель эту прогу (с таблицей векторов или без нее?)
2. Прочитать из основной программы(кот. на флэш) прогу с внешнего носителя в память с адреса (0х40000000 или 0х40000040?)
3. Настроить -- MEMMAP=0x02
4. Запустить
start=(void (*)(void))0x40000040(или0х40000000);
start();
5. Пить пиво
Так или нет?

И еще возможно ли запустить такую загруженную снаружи программу в старших адресах (например, в Ethernet или USB памяти).
Если да , то какие надо дать настройки линкеру... (ИАР)
KRS
Цитата(Step_ARM @ May 25 2009, 15:05) *
1. Записать на внешний носитель эту прогу (с таблицей векторов или без нее?)

это зависиит от вашей реализации. для ARM7 можно сделать стандартный код обработчика который в итоге (или сразу) переходит на обработчик заданный в VIC

Цитата(Step_ARM @ May 25 2009, 15:05) *
2. Прочитать из основной программы(кот. на флэш) прогу с внешнего носителя в память с адреса (0х40000000 или 0х40000040?)

Насколько я понял у вас LPC? ( это у них ремап на 64 байта)
Конечно писать с адреса 0x40000000 ( то что отремаплено все равно надо сохранить)

Цитата(Step_ARM @ May 25 2009, 15:05) *
3. Настроить -- MEMMAP=0x02

Если у вас не стандартные обработчики в загрузчике то да!

Цитата(Step_ARM @ May 25 2009, 15:05) *
4. Запустить
start=(void (*)(void))0x40000040(или0х40000000);
start();

если ремап ( свои обработчики ) то на 0 и переходить.
если стандартные (в загрузчике) - то логичнее точку входа сделать в начале RAM


Цитата(Step_ARM @ May 25 2009, 15:05) *
И еще возможно ли запустить такую загруженную снаружи программу в старших адресах (например, в Ethernet или USB памяти).
Если да , то какие надо дать настройки линкеру... (ИАР)

Не пробовал, но должно работать - только надо этоу память обычно проинитить ( включить устройство...)
НО НЕ РАЗУМНО там размещать код - это память медленнее и к тому же там может работать DMA что ценно иногда для данных
а настройки линкеру примерно такие же как и для обычной отладки в РАМ.

IMHO все эти вопросы у вас возникли потому что вы пользуетесь визуальными настройками а не XCL/ICF файлами. Стоит вам посмотреть как работает стартап, написать свои XCL файлы... Пройти программу пошагам не от main, а от перовй инструкции все эти вопросы отпадут сами собой.
Troll
Цитата
1. Записать на внешний носитель эту прогу (с таблицей векторов или без нее?)
Забыли шаг 0. Необходимо собрать (слинковать) исполняемую программу с адреса 0х40000000 в бинарник(если конечно хотите просто копировать в RAM без всяких преобразований). Естественно таблица векторов исполняемой программы должна быть в этом бинарнике и располагаться вначале.
После этого записать бинарник на внешний носитель (датафлэш ,SD).

Цитата
Прочитать из основной программы(кот. на флэш) прогу с внешнего носителя в память с адреса (0х40000000 или 0х40000040?)
Как считали данные с внеш. носителя: отключить прерывания, скопировать данные в RAM с адреса 0х40000000. При этом загрузчик, который записан во флэш контроллера, должен быть собран так, чтобы переменные загрузчика не располагались по адресам 0х40000000 - (0х40000000+Длина исполняемой программы) иначе при копировании загрузчик похерит сам себя.

Цитата
3. Настроить -- MEMMAP=0x02
Да.

Цитата
4. Запустить
start=(void (*)(void))0x40000040(или0х40000000);
start();
с адреса 0х40000000 или 0х0, если сделали ремап на ОЗУ, то это уже одни и теже адреса.

первые 64 байта исполняемой программы должны быть вида:
CODE
_exception_vectors:
LDR PC, ResetAddr /* Reset */
LDR PC, UndefAddr /* Undefined instruction */
LDR PC, SWIAddr /* Software interrupt */
LDR PC, PAbortAddr /* Prefetch abort */
LDR PC, DAbortAddr /* Data abort */
NOP /* Reserved */
LDR PC, IRQAddr /* IRQ interrupt */
LDR PC, FIQAddr /* FIQ interrupt */
ResetAddr:
.word ResetHandler
UndefAddr:
.word UndefHandler
SWIAddr:
.word SWIHandler
PAbortAddr:
.word PAbortHandler
DAbortAddr:
.word DAbortHandler
NOP
IRQAddr:
.word IRQHandler
FIQAddr:
.word FIQHandler

Цитата
5. Пить пиво
Можно и коньячку.

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

Удачи.
Step_ARM
Ну что ж... Заработало все прекрасно. Проблема только одна осталась. В LPC2364 всего 8кБ основной памяти. Это очень немного. Да и стеки всякие жрут уж больно много памяти.
Например вывод на графический дисплей уже не помещается.

Как запустить в RAM , используя всю оперативку 8кБ + USB(8кБ) +Ethernet (16кБ)???
В файле конфигурации IAR есть только начало и конец RAM. Как же определить еще куски памяти ведь они идут с отступом?
Step_ARM
У LPC23XX основной памяти 8кБ, USB_RAM -- 8кБ, Ethernet RAM -- 16кБ. Между ними резервные области памяти.
Возможна ли в IAR настройка xcl при которой будет использоваться вся память с отключенными резервными сегментами?
meister
Цитата(Step_ARM @ May 27 2009, 11:34) *
У LPC23XX основной памяти 8кБ, USB_RAM -- 8кБ, Ethernet RAM -- 16кБ. Между ними резервные области памяти.
Возможна ли в IAR настройка xcl при которой будет использоваться вся память с отключенными резервными сегментами?


Код
To alocate specific areas of memory to SEGA and SEGB:

-Z(CODE)SEGA,SEGB=100-1FF,400-6FF,1000

In this example SEGA will be placed between address 100 and 1FF, if it fits in that amount of space. If it does not, XLINK will try the range 400-6FF. If none of this ranges are large enough to hold SEGA, it will start at 1000. SEGB will be placed, according to the same rules, after segment SEGA.


Но не думайте, что можно помесить половину unsigled long в одном диапазоне адресов, а вторую половину - в другом, ARM7 так не умеет.
zltigo
Цитата(Step_ARM @ May 27 2009, 10:34) *
Возможна ли в IAR настройка xcl при которой будет использоваться вся память с отключенными резервными сегментами?

Для этого достаточно хотя-бы бегло почитать описание линкера идущее в комплекте с IAR. А не плодить кросспосты.
Troll
Цитата(Step_ARM @ May 27 2009, 12:56) *
Как запустить в RAM , используя всю оперативку 8кБ + USB(8кБ) +Ethernet (16кБ)???
Если в USB и Ethernet располагаются только данные исполняемой программы, то как KRS уже советовал Вам написать свои XCL файлы.. В скриптах определить секции (RAM, USB_RAM, ETH_RAM), которые будут располагаться по нужным адресам.

Если требуется, чтобы там располагался исполняемый код. Отдельные функции исполняемой программы расположить в секциях USB_RAM, ETH_RAM и загрузчик должен будет считывать и копировать несколько бинарников по требуемым адресам. Ну или как вариант загрузчик копирует только первый бинарник и передает управление исполняемой программе, а сама программа уже подгружает в USB_RAM и ETH_RAM требуемые функции.
zltigo
Цитата(Troll @ May 27 2009, 11:31) *
..а сама программа уже подгружает в USB_RAM и ETH_RAM требуемые функции.

Зачем все эти пляски с бубном, если всем этим прекрасно по жизни занимается линкер, только ему надо сказать, какой памятью он может располагать. Только в скрипте загрузчика еще надо, естественно, надо вдарить по регистрам, дабы память была доспупна, да errata почитать - там по крайней мере в первых ревизиях были ограничения на использования памяти для исполняемого кода.

А вообще сам подход к делу неверен - совершено незачем мучительно впихивать для отладки слона в посудную лавку sad.gif. Если уж совсем без отладчика думалка не думает, то отдаживайтесь во Flash - ресурс у него большой, а если и помрет (у меня еще за пяток лет ни один еще не помер в боевых отладочных платах), то цена вопроса замена контроллера. В дополнение, если уж возникает необходимость мучительно отлаживать всего-то десяток килобайт программы, тогда до прояснения прямой путь в симуляторы и/или кроссотладку кусков исходников на PCшке.
Step_ARM
Цитата(zltigo @ May 27 2009, 12:53) *
Зачем все эти пляски с бубном, если всем этим прекрасно по жизни занимается линкер, только ему надо сказать, какой памятью он может располагать. Только в скрипте загрузчика еще надо, естественно, надо вдарить по регистрам, дабы память была доспупна, да errata почитать - там по крайней мере в первых ревизиях были ограничения на использования памяти для исполняемого кода.

А вообще сам подход к делу неверен - совершено незачем мучительно впихивать для отладки слона в посудную лавку sad.gif. Если уж совсем без отладчика думалка не думает, то отдаживайтесь во Flash - ресурс у него большой, а если и помрет (у меня еще за пяток лет ни один еще не помер в боевых отладочных платах), то цена вопроса замена контроллера. В дополнение, если уж возникает необходимость мучительно отлаживать всего-то десяток килобайт программы, тогда до прояснения прямой путь в симуляторы и/или кроссотладку кусков исходников на PCшке.

zltigo в своем репертуаре :-)))
Вопрос-то и был в том как рассказать линкеру о доступной ему памяти. Тут перед этим кто-то показал как на сегменты бить. Проверим.Просто не нашел описания этого дела.

Подход к делу вещь индивидуальная. При чем тут вообще отладчик? Задача-то с довольно приятными последствиями. Например, можно не писать свой нестандартный загрузчик на флэш. Можно еще писать дополнительные программки и загружать их с внешнего носителя в память. Разве не в кайф?

Результаты: Написал программу загрузчик с SD карты. Хранение в dataflash. Из основной программы загружается с dataflash в Ethernet RAM. INTVEC в 0х40000000 -- 0х4000003F. Ремап. Выводит на экран запрос карты и состояние загрузки. Длина кода ~ 5600 байт , DATA -- ~4200 байт. Стирает flash. Затем с SD карты записывает нужный файл. Ремап и переход на старт адрес. Вроде работает -- ищу глюки. Вот еще разберусь с сегментами памяти и можно довольно большие проги в RAM запускать(если получится).

Проблема же с загрузчиком была в том, что COPY_RAM_TO_FLASH не хочет копировать из старших областей RAM. Буфер пришлось размещать в основной памяти через указатель. И еще не инитится основная память нулями, но это поправимо.
zltigo
Цитата(Step_ARM @ May 27 2009, 12:58) *
zltigo в своем репертуаре :-)))

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

Ответ был - это получится, только в документацию заглянуть. Узнав о самом факте существования документации и возможности управлять линкером не только из более, чем убогой IDE жизнь становится веселее.
Цитата
Задача-то с довольно приятными последствиями. Например, можно не писать свой нестандартный загрузчик на флэш.

Толку в мелких программах мало, как и в цеплянии дополнительно флеша в такой ситуации. С другой стороны для контроллеров с внешней 32bit RAM уже тупо грузить по фиксированным адресам неразумно. Правильный путь загрузка перемещаемого кода.
Цитата
Можно еще писать дополнительные программки и загружать их с внешнего носителя в память. Разве не в кайф?

С таким-же успехом их можно в Flash подгружать.
Step_ARM
Цитата(zltigo @ May 27 2009, 15:02) *
Вы правы - люблю давать наводки для самостоятельного поиска а не "нажми на кномку". Иначе поток вопросок "где кнопка" не иссякнет.

Ответ был - это получится, только в документацию заглянуть. Узнав о самом факте существования документации и возможности управлять линкером не только из более, чем убогой IDE жизнь становится веселее.

Толку в мелких программах мало, как и в цеплянии дополнительно флеша в такой ситуации. С другой стороны для контроллеров с внешней 32bit RAM уже тупо грузить по фиксированным адресам неразумно. Правильный путь загрузка перемещаемого кода.

С таким-же успехом их можно в Flash подгружать.

Все замечательно, но ведь HELP у IARa -- полный отстой. По крайней мере я ничего не нашел об этом. Помоги с доками, zltigo?

Ни фига себе мелкая -- около 30 кБ за минусом стеков. При желаниии много чего можно впихнуть.
А о внешней RAM и говорить не стоит -- цена проекта вырастает и размеры платы не позволяют. Да и медленновато работает с внешней RAM.

Конечно, можно и во флэш грузить... Только для этого надо держать ДЛИ-И-И-ИННЫЙ загрузчик на флэш, у которого есть интерфейсы для внешних носителей , что тупо, говоря языком zltigo.

А в принципе все ясно. Глюков не нашел. Все отлично работает. Спасибо.
meister
Цитата(Step_ARM @ May 27 2009, 17:50) *
около 30 кБ за минусом стеков


Я бы стэки разместил в USB, данные загрузчика в ETH и посмотрел бы на скорость... возможно не изменится. Будет полных 32к на программу.
zltigo
Цитата(Step_ARM @ May 27 2009, 16:50) *
Все замечательно, но ведь HELP у IARa -- полный отстой.

Отнюдь - он ОЧЕНЬ хороший.
Цитата
Конечно, можно и во флэш грузить... Только для этого надо держать ДЛИ-И-И-ИННЫЙ загрузчик на флэш, у которого есть интерфейсы для внешних носителей

Этот загрузчик будет "длиннее" загрузчика в RAM на несколько команд вызова функции системного LPC загрузчика записи во Flash.
Step_ARM
Цитата(zltigo @ May 27 2009, 22:17) *
Отнюдь - он ОЧЕНЬ хороший.

Этот загрузчик будет "длиннее" загрузчика в RAM на несколько команд вызова функции системного LPC загрузчика записи во Flash.

Я думаю -- это просто слова... Укажите , в подтверждение своих слов, название раздела помощи и стр.

Насчет загрузчика. Ну зачем же так? Сейчас я использую переделанный немного загрузчик через USB AN10759. Весит он около 6500 байт. Добавляешь всякие пользовательские опции -- клавиатура, вывод на графику, декодер ПО. Получается уже 10200(THUMB , min LIB). Если добавить SD Card(SSP1) ,dataflash(SSP0), FAT16/32 b и др. сопутствующее, то размеры его будут слишком уж большие.
Не надо забывать о том, что загрузчик в RAM хранится на внешнем носителе достаточного объема и "жрать не просит"...
В принципе и загрузчик через USB можно переписать для RAM. Дальше вообще дело техники -- в основной программе в меню выбор -- загрузить с USB или с карты. Загружается соответствующая программа и перезаписывает флэш.
Может быть господин модератор скажет , что не прав? :-)))



Цитата(meister @ May 27 2009, 18:25) *
Я бы стэки разместил в USB, данные загрузчика в ETH и посмотрел бы на скорость... возможно не изменится. Будет полных 32к на программу.

Настолько ли критична скорость при загрузке с внешнего носителя? 32к никогда не будет всего у 2364 32к. Минус стеки и дата. Я думаю где-то 28кБ кода.
Ну еще можно под DWORD buff использовать батарейную память 2к.
meister
Цитата(Step_ARM @ May 28 2009, 09:13) *
32к никогда не будет всего у 2364 32к.


Я перепутал с 2366.
zltigo
Цитата(Step_ARM @ May 28 2009, 08:13) *
Я думаю -- это просто слова... Укажите , в подтверждение своих слов, название раздела помощи и стр.

Явки, пароли, ключи от квартиры... smile.gif Flash в LPC действительно программируется посредством вызова штатного bootloader и соответствено размер этого кода ничтожен.
Step_ARM
Цитата(zltigo @ May 28 2009, 10:15) *
Явки, пароли, ключи от квартиры... smile.gif Flash в LPC действительно программируется посредством вызова штатного bootloader и соответствено размер этого кода ничтожен.

Вы , наверное, совсем не читаете мои сообщения... Я понимаю -- при вашей-то божественной сущности. Когда наступает творческая импотенция ВСЕ ведут себя аналогично. Очень надеюсь , что Вы еще не достигли такой стадии...
zltigo
Цитата(Step_ARM @ May 28 2009, 08:13) *
Весит он около 6500 байт. Добавляешь всякие пользовательские опции -- клавиатура, вывод на графику, декодер ПО. Получается уже 10200(THUMB , min LIB). Если добавить SD Card(SSP1) ,dataflash(SSP0), FAT16/32 b и др. сопутствующее, то размеры его будут слишком уж большие.

Для размещения всего этого хозяйства даже в 128K Flash минимального в линейке контроллера - нет.
Если Вам кажется, что Вы рожаете нечто креативное вротивовес "творческим импотентам", то таки нет - Вы рожаете просто обычного кастрированного уродца sad.gif. Вместо утаптывания загружаемых программ целиком в несколько десятков килобайт RAM их совершенно спокойно можно подгружать в имеющиюся даже на Вашем минимальном контроллере сотню килобайт Flash и использовать RAM по назначению.
Step_ARM
Цитата(zltigo @ May 28 2009, 10:29) *
Для размещения всего этого хозяйства даже в 128K Flash минимального в линейке контроллера - нет.
Если Вам кажется, что Вы рожаете нечто креативное вротивовес "творческим импотентам", то таки нет - Вы рожаете просто обычного кастрированного уродца sad.gif. Вместо утаптывания загружаемых программ целиком в несколько десятков килобайт RAM их совершенно спокойно можно подгружать в имеющиюся даже на Вашем минимальном контроллере сотню килобайт Flash и использовать RAM по назначению.

Странно, как же все поместилось + десяток протоколов и многоуровневое меню и еще место осталось? Вы,дорогой товарищ, так ничего и не поняли... Ну что ж -- выше головы не прыгнешь.
Хам... просто какой-то... , а не модератор.
esaulenka
Подниму тему.

Скажите, а как красиво расположить вектор IRQ в ОЗУ?
Вот эту конструкцию надо как-то отвязать от PC:
LDR PC, [PC, #-0x0FF0] ; Vector from VicVectAddr


Хотя и остальные вектора сделал как-то коряво...
В стартапе вместо LDR PC, Addr сделал
Код
LDR        R0, =0x40000000
LDR        R1, Reset_Addr
STR        R1, [R0, #0x00]


Надо бы какие-нибудь асмовые исходники почитать на досуге...
Компилятор кейл, камень - 2138 (впрочем, это влияет только на расположение VicVectAddr).
esaulenka
В очередной раз сработала примета "напиши о проблеме, она сама решится" smile.gif

Банально вынес объявление векторов в отдельную процедурку, сказал "положить в ОЗУ" и кейл сделал всё самостоятельно. Чудеса smile.gif
Код
AREA VECTORS_TBL,    CODE,    AT 0x40000000
VECTORS_TABLE        PROC    ARM

Vectors:        LDR     PC,Reset_Addr        
                LDR     PC,Undef_Addr
                LDR     PC,SWI_Addr
                LDR     PC,PAbt_Addr
                LDR     PC,DAbt_Addr
                NOP                            /* Reserved Vector */
                LDR     PC,[PC, #-0x0FF0]      /* Vector from VicVectAddr */
                LDR     PC,FIQ_Addr
                            

Reset_Addr:     DD      Reset_Handler
Undef_Addr:     DD      Undef_Handler?A
SWI_Addr:       DD      SWI_Handler?A
PAbt_Addr:      DD      PAbt_Handler?A
DAbt_Addr:      DD      DAbt_Handler?A
FIQ_Addr:       DD      FIQ_Handler?A

                    ENDP


AREA   STARTUPCODE, CODE, AT 0x00002000

       PUBLIC  __startup
__startup       PROC    ARM


Reset_Handler:  

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