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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как в Keil для ARM указать точное расположение процедуры в памяти FLASH
Romanello
сообщение Oct 2 2007, 14:32
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 138
Регистрация: 10-03-05
Пользователь №: 3 204



Нужно расположить функцию в заанее известном месте в памяти контроллера и потом обращаться к ней, кстати как потом можно будет обратиться к этой функции из другой функции?

Заранее спасибо.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 2 2007, 15:08
Сообщение #2


Гуру
******

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



Цитата(Romanello @ Oct 2 2007, 18:32) *
Нужно расположить функцию в заанее известном месте в памяти контроллера и потом обращаться к ней, кстати как потом можно будет обратиться к этой функции из другой функции?

Воспользуйтесь поиском, ключевое слово - scatter.
Обращаться к функции можно будет так же, как и к любой другой - линкер ведь будет знать её расположение.
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 2 2007, 21:01
Сообщение #3


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(aaarrr @ Oct 2 2007, 18:08) *
Воспользуйтесь поиском, ключевое слово - scatter.
Обращаться к функции можно будет так же, как и к любой другой - линкер ведь будет знать её расположение.

Может быть речь о разных программах?
В одной программе некая сервисная функция кладется по оговоренному адресу, из другой программы, эта сервисная функция вызывается. Тогда первое ваше предложение верно, а второе насчет линкера не пригодится, т.к. линкер может и не знать где располагается требуемая функция. В обход линкера можно например создать тип сервисной функции и указатель, и написав макрос или проинициализировать такой уазатель вручную, вызывать сервисную функию с любого адреса (в примере вызов функции по адресу 0x1000):

создаем типы:
Код
typedef void __service_func(void);
typedef __service_func *__p_service_func;


используем так:
Код
int main( void )
{
    __p_service_func foo = (__p_service_func)0x1000;
    ...
    foo();

или так:
Код
#define CALL_SERVICE( addr )  ( ((__p_service_func)( addr )) () )

int main( void )
{
    CALL_SERVICE( 0x1000 );
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 2 2007, 22:46
Сообщение #4


Гуру
******

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



Цитата(defunct @ Oct 3 2007, 01:01) *
Может быть речь о разных программах?

Тогда проще и логичнее использовать SWI, благо оно именно для таких целей и предусматривалось.
Go to the top of the page
 
+Quote Post
romashko
сообщение Oct 2 2007, 22:59
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 85
Регистрация: 25-12-06
Пользователь №: 23 865



Цитата(Romanello @ Oct 3 2007, 01:32) *
...кстати как потом можно будет обратиться к этой функции из другой функции?


#define Address 0x10000000 //адрес по которому расположена функция
#define CALL (*(void(*)(void)) Address) //функция CALL()

int main(void)
{
...
CALL(); //вызов функции по адресу 0x10000000
...
}
Go to the top of the page
 
+Quote Post
Romanello
сообщение Oct 3 2007, 12:56
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 138
Регистрация: 10-03-05
Пользователь №: 3 204



Функция которая размещена по определенному адресу и основная программа компилируется в разное время и в разных местах. Из всего вышесказанного не понял как указать размещение программы в памяти по определееному адресу.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 3 2007, 13:01
Сообщение #7


Гуру
******

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



Цитата(Romanello @ Oct 3 2007, 16:56) *
Функция которая размещена по определенному адресу и основная программа компилируется в разное время и в разных местах.

Тогда лучше SWI, или в таком решении что-то не устраивает?

Цитата(Romanello @ Oct 3 2007, 16:56) *
Из всего вышесказанного не понял как указать размещение программы в памяти по определееному адресу.

Размещать лучше не программу, а таблицу переходов - это дает некоторую гибкость.
Указать размещение этой таблицы нужно линкеру, делается это через scatter description file. Описание можно найти в документации.
Go to the top of the page
 
+Quote Post
Romanello
сообщение Oct 3 2007, 16:09
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 138
Регистрация: 10-03-05
Пользователь №: 3 204



Цитата(aaarrr @ Oct 3 2007, 17:01) *
Тогда лучше SWI, или в таком решении что-то не устраивает?
Размещать лучше не программу, а таблицу переходов - это дает некоторую гибкость.
Указать размещение этой таблицы нужно линкеру, делается это через scatter description file. Описание можно найти в документации.



ЧТо такое SWI и как это выглядит в KEIL компиляторе?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 3 2007, 16:22
Сообщение #9


Гуру
******

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



Цитата(Romanello @ Oct 3 2007, 20:09) *
ЧТо такое SWI и как это выглядит в KEIL компиляторе?

SWI - это программное прерывание. Почитать про него можно в описании архитектуры ARM. В Keil выглядит так же, как и в любом другом месте.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 3 2007, 20:34
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(defunct @ Oct 3 2007, 00:01) *
создаем типы:
используем так:
А если так:
Код
extern void func1();
extern int func2(int, char);
extern char func3(long);
А линкеру указать конкретные адреса функций. В IAR это делается ключем командной строки линкера -Dfunc1=0x1000 -Dfunc2=0x2000 или в .xcl-файле, в WinAVR - -wl,--defsym,func1=0x1000 или в файле для ld. Предполагаю, что в Кейле есть такая же возможность. Насчет таблицы тоже мысль очень правильная - при изменении самих функций не придется перекраивать вторую программу. Причем в таблице могут быть не адреса, а команды B func1, B func2. Такую таблицу, конечно, придется писать на ассемблере.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Romanello
сообщение Oct 4 2007, 08:50
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 138
Регистрация: 10-03-05
Пользователь №: 3 204



Цитата(aaarrr @ Oct 3 2007, 20:22) *
SWI - это программное прерывание. Почитать про него можно в описании архитектуры ARM. В Keil выглядит так же, как и в любом другом месте.


А как программное прерывание привязать к выполнению функции из определенного адреса. Можно же просто обратиться в определенный адрес. А мен нужно разместить функцию по определленному адресу. Зачем для этого создавать таюлицу переходов, да еще на ассемблере?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 4 2007, 09:20
Сообщение #12


Гуру
******

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



Цитата(Romanello @ Oct 4 2007, 12:50) *
А как программное прерывание привязать к выполнению функции из определенного адреса.

Не нужно ничего привязывать. Вся прелесть SWI в том, что вызов всегда будет одинаков. А разбираться, какая функция соответствует вызову будет обработчик SWI.

Цитата(Romanello @ Oct 4 2007, 12:50) *
Зачем для этого создавать таюлицу переходов, да еще на ассемблере?

Затем, что никто не гарантирует, что функцию удастся разместить по нужному адресу. Особенно, если она не одна. Да и возни с каждой отдельной функцией будет слишком много.
Это просто разумное решение для такой задачи.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 4 2007, 09:41
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Romanello @ Oct 4 2007, 11:50) *
Зачем для этого создавать таюлицу переходов, да еще на ассемблере?
А вы попробуйте. Потом чуть измените одну из функций и у вас "поплывут" адреса всех остальных. Придется исправлять и перекомпилировать приложение, в котором эти функции вызываются. А с таблицей все точки входа во все функции будут располагаться всегда в одном и том же месте, вне зависимости от размера функций.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Oct 4 2007, 10:03
Сообщение #14


Местный
***

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



Цитата(Romanello @ Oct 2 2007, 18:32) *
Нужно расположить функцию в заанее известном месте в памяти контроллера и потом обращаться к ней, кстати как потом можно будет обратиться к этой функции из другой функции?


Cоветов тут уже надавали кучу и без меня...
А у меня всего один вопрос имеющий отношение к делу:
А зачем вообще какую-то функцию нужно располагать в "заранее известном месте..."?

По-моему логично сперва понять - а нужно ли это и зачем, а уж потом решать такую задачу...

Сообщение отредактировал Николай Z - Oct 4 2007, 10:04
Go to the top of the page
 
+Quote Post
bodja74
сообщение Oct 4 2007, 10:52
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Цитата(Николай Z @ Oct 4 2007, 13:03) *
А зачем вообще какую-то функцию нужно располагать в "заранее известном месте..."?

BootLoader,API(IAP),типа дисковая ось.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 5th July 2025 - 04:06
Рейтинг@Mail.ru


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