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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> EWARM. Cделать переход по известному адресу?
singlskv
сообщение Nov 9 2007, 00:24
Сообщение #16


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Сергей Борщ @ Nov 9 2007, 02:29) *
P.S. Мнения четко разделились на два подхода. Вот пришел бы кто-нибудь умный, вроде ReAl, и растолковал ограничения и правильность каждого решения.
Я конечно не ReAl, но знаю один вариант, когда
вызов функции по фиксированному адресу приводит к непредсказуемым последствиям.
Это касается младших контроллеров AVR у которых все jmp и call существуют только в
версии rjmp и rcall.
Mega8:
Код
169:      ((void(*)(void))0x0000)();
+00000450:   DBF0        RCALL   PC-0x040F        Relative call subroutine

Mega128:
Код
169:      ((void(*)(void))0x0000)();
+00000489:   940E0000    CALL    0x00000000       Call subroutine


WinAVR-20060421

Может в новых версиях они чего-то и подправили...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 9 2007, 02:22
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Сергей Борщ @ Nov 9 2007, 02:29) *
Да. Но если без напряжения можно сделать лучше - почему бы и да?

Чем лучше?
ИМХО, задание левых символов для линкера - это изврат. Особенно, если имеешь дело с полудюжиной разных архитектур и, соответственно, разных линкеров.

Цитата(Сергей Борщ @ Nov 9 2007, 02:29) *
Аналогично можно объявлять и функции с параметрами, причем указывать фиктивные самодокументирующие имена параметров.

То же самое легко делается дефайном:
Код
#define    func(x, y)    ((int(*)(int, int))0x10000000)((x), (y))

И объявить функцию в любом виде можно.

Цитата(Сергей Борщ @ Nov 9 2007, 02:29) *
Не спорю - можно и так. Ненаказуемо smile.gifВозможность-то наверняка есть, просто мы о ней (пока) не знаем. Хотя бы и через файл.

Нет там такой возможности - только через symdefs, который в обычной жизни не нужен.
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Nov 9 2007, 07:09
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Если делать на классическом С, то что-то типа того получается:

Код
typedef void (*MyFunc)(void);
MyFunc MyCode;

int main()
{
  MyCode = (MyFunc)0x10000000;
  MyCode();
}


Только вызов по всем книжкам (*MyCode)() должен быть, а работает правильно и просто MyCode().
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Nov 9 2007, 09:56
Сообщение #19


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(aaarrr @ Nov 9 2007, 05:22) *
ИМХО, задание левых символов для линкера - это изврат. Особенно, если имеешь дело с полудюжиной разных архитектур и, соответственно, разных линкеров.


Могу только повториться... Да можно и без линкера... и даже без компилятора, можно даже без ассемблера.... В пределе - можно вообще без процессора - все на логических схемах...

Скорее всего Вы просто плохо понимаете назначение линкера и описания make, которые как раз и отвечают за создание исполняемого кода и распределение памяти.

Зачем говорить о разных процессорах, если уже в программе main - вы себя жестко привязали к одной-единственной архитектуре наглухо практически - именно путем задания статического адреса? Причем тут тогда другие процессоры c другой архитектурой - у них точка входа почти наверняка будет в другом месте?

А вот символическое задание имен в программе - позволяет ее как раз переносить между разными архитектурами намного легче... Задача только увязать с требуемыми адресами заданными архитектурой - т.е. в make файле или как раз в параметрах линкера и нигде больше... А саму программу править уже и не надо в 99% cлучаев, если Вы в нее не запихнете еще какую-то архитектурную зависимость.
==============================================
PS: По поводу легко или нелегко- практически притча... Представьте себе у Вас в квартире - новую стену после ремонта... Новые обои - все красиво... Стоит на полу картина... Задача - повесить ее на стену.... Решаться может разными способами...
Первый способ - находите три ржавых гвоздя в сундуке... и какой попало молоток... Два вбиваете как попало в дорогую раму - сзади.... И привязываете к гвоздям кусок первого попавшегося шпагата.... Третий - криво и с трудом вгоняете в стену.... Ржавый такой гвоздь... кривой... Вешаете за шпагатину Вашу замечательную картину... Ну - нравится Вам этот самый простой способ? ведь проще не бывает... biggrin.gif
Способ второй Чтобы ничего не портить и сделать все аккуратно и красиво - идете в специальный магазин и покупаете соответствующий раме аккуратный и незаметный крепеж, специальную оснастку для его установки на раму и стену... Дома изучаете это все и аккуратно выполняете все инструкции по установке и в конце-концов картина на стене...

Мне кажется, что второй способ при его кажущейся большей сложности - правильнее первого и намного эстетичности. А часто - еще и более простой и легкий... Да еще и мобильный - ибо специальный крепеж легко и удалется и вид стены не испортит - а попробуйте без последствий вырнуть из стены 100 мм ржавый гвоздь? biggrin.gif

Сообщение отредактировал Николай Z - Nov 9 2007, 10:09
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 9 2007, 11:23
Сообщение #20


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(Николай Z @ Nov 9 2007, 11:56) *
Могу только повториться... Да можно и без линкера...


Не без линкера, а без использования определенных СТАТИЧЕСКИ в линкере адресов.

Цитата
Скорее всего Вы просто плохо понимаете назначение линкера и описания make, которые как раз и отвечают за создание исполняемого кода и распределение памяти.


Отлично понимаю, и в другом случае конечно по возможности определю адреса в .xcl-файле например.

Цитата
Зачем говорить о разных процессорах, если уже в программе main - вы себя жестко привязали к одной-единственной архитектуре наглухо практически - именно путем задания статического адреса? Причем тут тогда другие процессоры c другой архитектурой - у них точка входа почти наверняка будет в другом месте?


Причем тут архитектура. Понятное дело, что бутлоадер - вещь сугубо интимная со всех сторон.

Только вот вы видимо невнимательно читаете. Я (уж простите такую вольность) предположил, что автору возможно понадобится расширить функционал до вызова функции по произвольному адресу.

Вот что я написал:

Цитата(Rst7 @ Nov 8 2007, 17:23) *
Я понимаю. Представим себе ситуацию, что в процессе развития этого начального загрузчика будет необходимо загружать код не только на адрес 0x10000000, но и на любой другой адрес, который будет передаваться загрузчику (ну например в коммандной строке). Тогда придется перейти к моему варианту.


И автор топика ответил (болд мой)

Цитата(VladislavS @ Nov 8 2007, 22:01) *
Так оно и есть. Запуск кода из параллельной flash был только первым шагом. Теперь буду загружать разные приложения из DataFlash в SDRAM.
Да мне вообще стыдно за такой вопрос. Просто заклинило. Сидел побеждал размещение сегментов в памяти, копирование векторов прерываний, стартовые инициализации, флэшлоадер. Когда все вроде заработало и осталась такая мелочь как передать управление на код и пришлось воспользоваться подзатыльником.

Теперь после просветления никакого труда не составит сделать указатель на функцию и по нему запускать код в любом нужном месте памяти.


Давайте, ваш удар, принц - сделайте это линкером - запускать код в любом нужном месте памяти

Так зачем вы нам тут притчи рассказываете?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Nov 9 2007, 11:44
Сообщение #21


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(Rst7 @ Nov 9 2007, 14:23) *
Давайте, ваш удар, принц - сделайте это линкером - запускать код в любом нужном месте памяти

Так зачем вы нам тут притчи рассказываете?


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

А притча затем - что Ваше решение - как раз те самые три ржавых гвоздя.
А второе - это то что Вам рекомендовал г-н Сергей Борщ - это и есть правильное и довольно мобильное решение. Может и не идеальное - но классическое и проверенное.

Но Вы вправе ему как следовать, так и не следовать. Больше тут добавить нечего.

Сообщение отредактировал Николай Z - Nov 9 2007, 11:48
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 9 2007, 12:12
Сообщение #22


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(Николай Z @ Nov 9 2007, 13:44) *
А во-ворых Вам уже все рассказали...


Что именно?

Цитата
Не нравится подход - используйте свой...


Мне нравится подход. Но он стреляет только в том случае, если этот адрес - константа.

Цитата
А притча затем - что Ваше решение - как раз те самые три ржавых гвоздя.
А второе - это то что Вам рекомендовал г-н Сергей Борщ - это и есть правильное и довольно мобильное решение. Может и не идеальное - но классическое и проверенное.


Не поверите - классика - это как раз то что я написал biggrin.gif

Я пытаюсь Вам сказать, что автору топика нужен в последствии вызов функции по произвольному адресу. Модифицируйте ваш метод с учетом такого требования - и я умою руки.

В более общем случае рассмотрите вопрос загрузки выполняемых приложений на разные адреса (куда malloc вернул указатель, там и будет приложение). Как такое победить линкером?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Nov 9 2007, 13:26
Сообщение #23


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(Rst7 @ Nov 9 2007, 15:12) *
Мне нравится подход. Но он стреляет только в том случае, если этот адрес - константа.

Нравится так нравится... Но Вам никто не мешает использовать вместо вашей константы зарезервированный заранее пойнтер и инициировать его перед использованием как Вам угодно.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 9 2007, 13:30
Сообщение #24


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(Николай Z @ Nov 9 2007, 15:26) *
Нравится так нравится... Но Вам никто не мешает использовать вместо вашей константы зарезервированный заранее пойнтер и инициировать его перед использованием как Вам угодно.



Видимо я недостаточно точно сформулировал. Правильно будет звучать так -
"Мне нравится подход с указанием адреса в скрипте/параметрах линкера. Но он стреляет только в том случае, если этот адрес - константа."

Вот и я к тому же, что в варианте, предложенным мной, вполне будет работать переменная вместо константы. А у Вас?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Nov 9 2007, 13:39
Сообщение #25


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(Rst7 @ Nov 9 2007, 16:30) *
Видимо я недостаточно точно сформулировал. Правильно будет звучать так -
"Мне нравится подход с указанием адреса в скрипте/параметрах линкера. Но он стреляет только в том случае, если этот адрес - константа."

Вот и я к тому же, что в варианте, предложенным мной, вполне будет работать переменная вместо константы. А у Вас?


Я начинаю подозревать что мы говорим о чем-то разном... Я о вопросе заданном в топе...
А Вы об чем?

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

Зачем надо переменную точку старта - вообще?

Цитата(Rst7 @ Nov 9 2007, 15:12) *
В более общем случае рассмотрите вопрос загрузки выполняемых приложений на разные адреса (куда malloc вернул указатель, там и будет приложение). Как такое победить линкером?


Возможно Вы собираетесь использовать что-то типа дозагрузки overlay-ев?
Если я правильно понимаю - то у Вас уже что-то работает в процессоре - ведь кто-то должен вызвать Ваш malloc(), который вам дает указатель?

Сообщение отредактировал Николай Z - Nov 9 2007, 13:41
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 9 2007, 13:46
Сообщение #26


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(Николай Z @ Nov 9 2007, 15:39) *
Я начинаю подозревать что мы говорим о чем-то разном... Я о вопросе заданном в топе...
А Вы об чем?


Я о том, что автор уточнил задачу чуть позже

Цитата(VladislavS @ Nov 8 2007, 22:01) *
Так оно и есть. Запуск кода из параллельной flash был только первым шагом. Теперь буду загружать разные приложения из DataFlash в SDRAM.


Так что уже 2 точки входа как минимум.

А теперь представьте себе, что автору понадобится загрузить два приложения на разные адреса, которые, например, ему вернет malloc. Как он выйдет из положения?


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


Вы видимо хотите, чтобы уточнил автор топика, а не я. Перед мной такая задача на данный момент не стоит, а когда стояла, решалась так:
Код
typedef long TElfEntry(char *, void *,void *,void *);
long elfload(char *filename, void *param1, void *param2, void *param3){
....
....
  //выделим эту область и очистим ее
  if ((base=(char *)malloc(maxadr-minadr))==0){        //не выделяеться память под ельф
...
...
  ((TElfEntry *)(base+ehdr.e_entry-minadr))(filename,param1,param2,param3);
...


Цитата
Зачем надо переменную точку старта - вообще?
Возможно Вы собираетесь использовать что-то типа дозагрузки overlay-ев?
Если я правильно понимаю - то у Вас уже что-то работает в процессоре - ведь кто-то должен вызвать Ваш malloc(), который вам дает указатель?


Я не собираюсь. А автор топика - вполне возможно. Посему лучше использовать вариант, предложеный мной. На будущее.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 9 2007, 14:48
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Да расшумелись sad.gif.
В общем случае несомненно (для меня smile.gif ) надо всеми силами избегать явных указаний адресов в исходниках - конткретика это дело линкера. Когда я такое "безобразие" вижу, например, для широко используемого некоторыми размещения неких конфигурационных констант, то очень расстраиваюсь smile.gif,
что вместо нормального "выхода в дверь" используют "выход в окно". Однако любое правило сильно исключениями для перехода куда-то безвозвратно в bootloader я явно отдам предпочтение действительно очевидно-классическому варианту, а не указания линкеру виртуальных имен. Причина проста - сразу видно, что "выход именно в окно", а не нечто обыденное.

А вот практический результат в виде полученного кода в одном и другом случае надо иметь ввиду.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Nov 9 2007, 16:23
Сообщение #28


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(Rst7 @ Nov 9 2007, 16:46) *
А теперь представьте себе, что автору понадобится загрузить два приложения на разные адреса, которые, например, ему вернет malloc. Как он выйдет из положения?


Это и есть механизм дозагрузки софта в уже работающем...
Как раз типа механизма работы оверлея...

malloc() не сам вызвался - его вызвала уже загруженная часть ситемы которая стартовала - раньше когда система стартовала...

Потому тут задача вглядит немного иначе:
Надо просто вызвать подпрограмму, которую вы прочли из Флэша или откуда-то еще в память, которую Вам указал вызванный malloc...

В таком случае - начальная загрузка и адрес указанный линкеру - совершенно не имеет отношения к делу... У Вас загрузка уже давно закончилась начальная и никаких переменных адресов ей не нужно...
Система у Вас уже работает... В ней ваш модуль определил место дозагрузки - вызовом malloc() и получил адрес места для размещения программы...

Замечу - я честно говоря не знаю зачем для этого malloc() использовать - но предположим пусть так, хотя это можно сделать гораздо более эффективно...

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

А вот написать кусок программы, который это делает - это уже гораздо более сложная песня...
Во FreeRTOS нету встроенного механизма работы с Оверлеями и софт для их поддержки непредусмотрен. Его надо делать самому... или исать в каких-то других системах...

Сообщение отредактировал Николай Z - Nov 9 2007, 16:26
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Nov 9 2007, 17:53
Сообщение #29


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Да ладно вам на пустом месте ругаться... Чтобы никому не было обидно я оставил вызов кода из флэшь по первому варианту (изменить её адрес всё равно не получится), а загруженный в SDRAM код по второму варианту. Работают оба варианта, а практика критерий истины.
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Nov 9 2007, 20:27
Сообщение #30


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(VladislavS @ Nov 9 2007, 20:53) *
Да ладно вам на пустом месте ругаться... Чтобы никому не было обидно я оставил вызов кода из флэшь по первому варианту (изменить её адрес всё равно не получится), а загруженный в SDRAM код по второму варианту. Работают оба варианта, а практика критерий истины.


Я так понимаю - что пытаюсь ответить уже совсем не на ваш вопрос... а на вопрос плавно вытекший из вашего... И я лично - вроде бы пока ни с кем не ругаюсь, а только пытаюсь понять - что у меня спросили... то ли ваш вариант, то ли еще какой... Придет автор уточнений - и скажет.. Если надо -- то мы откроем другую тему - потому что организация оверлеев в рамках FreeRTOS - меня самого сильно интересует...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 21:52
Рейтинг@Mail.ru


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