Перейти к содержанию
    

Как в Keil для ARM указать точное расположение процедуры в памяти FLASH

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

 

Заранее спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Воспользуйтесь поиском, ключевое слово - scatter.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Воспользуйтесь поиском, ключевое слово - 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 );

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может быть речь о разных программах?

Тогда проще и логичнее использовать SWI, благо оно именно для таких целей и предусматривалось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...кстати как потом можно будет обратиться к этой функции из другой функции?

 

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

#define CALL (*(void(*)(void)) Address) //функция CALL()

 

int main(void)

{

...

CALL(); //вызов функции по адресу 0x10000000

...

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функция которая размещена по определенному адресу и основная программа компилируется в разное время и в разных местах. Из всего вышесказанного не понял как указать размещение программы в памяти по определееному адресу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функция которая размещена по определенному адресу и основная программа компилируется в разное время и в разных местах.

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

 

Из всего вышесказанного не понял как указать размещение программы в памяти по определееному адресу.

Размещать лучше не программу, а таблицу переходов - это дает некоторую гибкость.

Указать размещение этой таблицы нужно линкеру, делается это через scatter description file. Описание можно найти в документации.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Размещать лучше не программу, а таблицу переходов - это дает некоторую гибкость.

Указать размещение этой таблицы нужно линкеру, делается это через scatter description file. Описание можно найти в документации.

 

 

ЧТо такое SWI и как это выглядит в KEIL компиляторе?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ЧТо такое SWI и как это выглядит в KEIL компиляторе?

SWI - это программное прерывание. Почитать про него можно в описании архитектуры ARM. В Keil выглядит так же, как и в любом другом месте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

создаем типы:

используем так:

А если так:

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. Такую таблицу, конечно, придется писать на ассемблере.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SWI - это программное прерывание. Почитать про него можно в описании архитектуры ARM. В Keil выглядит так же, как и в любом другом месте.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

Зачем для этого создавать таюлицу переходов, да еще на ассемблере?

Затем, что никто не гарантирует, что функцию удастся разместить по нужному адресу. Особенно, если она не одна. Да и возни с каждой отдельной функцией будет слишком много.

Это просто разумное решение для такой задачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Cоветов тут уже надавали кучу и без меня...

А у меня всего один вопрос имеющий отношение к делу:

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

 

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

Изменено пользователем Николай Z

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

BootLoader,API(IAP),типа дисковая ось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...