Romanello 0 2 октября, 2007 Опубликовано 2 октября, 2007 · Жалоба Нужно расположить функцию в заанее известном месте в памяти контроллера и потом обращаться к ней, кстати как потом можно будет обратиться к этой функции из другой функции? Заранее спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 2 октября, 2007 Опубликовано 2 октября, 2007 · Жалоба Нужно расположить функцию в заанее известном месте в памяти контроллера и потом обращаться к ней, кстати как потом можно будет обратиться к этой функции из другой функции? Воспользуйтесь поиском, ключевое слово - scatter. Обращаться к функции можно будет так же, как и к любой другой - линкер ведь будет знать её расположение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 2 октября, 2007 Опубликовано 2 октября, 2007 · Жалоба Воспользуйтесь поиском, ключевое слово - 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 ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 2 октября, 2007 Опубликовано 2 октября, 2007 · Жалоба Может быть речь о разных программах? Тогда проще и логичнее использовать SWI, благо оно именно для таких целей и предусматривалось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
romashko 0 2 октября, 2007 Опубликовано 2 октября, 2007 · Жалоба ...кстати как потом можно будет обратиться к этой функции из другой функции? #define Address 0x10000000 //адрес по которому расположена функция #define CALL (*(void(*)(void)) Address) //функция CALL() int main(void) { ... CALL(); //вызов функции по адресу 0x10000000 ... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Romanello 0 3 октября, 2007 Опубликовано 3 октября, 2007 · Жалоба Функция которая размещена по определенному адресу и основная программа компилируется в разное время и в разных местах. Из всего вышесказанного не понял как указать размещение программы в памяти по определееному адресу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 3 октября, 2007 Опубликовано 3 октября, 2007 · Жалоба Функция которая размещена по определенному адресу и основная программа компилируется в разное время и в разных местах. Тогда лучше SWI, или в таком решении что-то не устраивает? Из всего вышесказанного не понял как указать размещение программы в памяти по определееному адресу. Размещать лучше не программу, а таблицу переходов - это дает некоторую гибкость. Указать размещение этой таблицы нужно линкеру, делается это через scatter description file. Описание можно найти в документации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Romanello 0 3 октября, 2007 Опубликовано 3 октября, 2007 · Жалоба Тогда лучше SWI, или в таком решении что-то не устраивает? Размещать лучше не программу, а таблицу переходов - это дает некоторую гибкость. Указать размещение этой таблицы нужно линкеру, делается это через scatter description file. Описание можно найти в документации. ЧТо такое SWI и как это выглядит в KEIL компиляторе? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 3 октября, 2007 Опубликовано 3 октября, 2007 · Жалоба ЧТо такое SWI и как это выглядит в KEIL компиляторе? SWI - это программное прерывание. Почитать про него можно в описании архитектуры ARM. В Keil выглядит так же, как и в любом другом месте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 3 октября, 2007 Опубликовано 3 октября, 2007 · Жалоба создаем типы: используем так: А если так: 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. Такую таблицу, конечно, придется писать на ассемблере. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Romanello 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба SWI - это программное прерывание. Почитать про него можно в описании архитектуры ARM. В Keil выглядит так же, как и в любом другом месте. А как программное прерывание привязать к выполнению функции из определенного адреса. Можно же просто обратиться в определенный адрес. А мен нужно разместить функцию по определленному адресу. Зачем для этого создавать таюлицу переходов, да еще на ассемблере? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба А как программное прерывание привязать к выполнению функции из определенного адреса. Не нужно ничего привязывать. Вся прелесть SWI в том, что вызов всегда будет одинаков. А разбираться, какая функция соответствует вызову будет обработчик SWI. Зачем для этого создавать таюлицу переходов, да еще на ассемблере? Затем, что никто не гарантирует, что функцию удастся разместить по нужному адресу. Особенно, если она не одна. Да и возни с каждой отдельной функцией будет слишком много. Это просто разумное решение для такой задачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба Зачем для этого создавать таюлицу переходов, да еще на ассемблере?А вы попробуйте. Потом чуть измените одну из функций и у вас "поплывут" адреса всех остальных. Придется исправлять и перекомпилировать приложение, в котором эти функции вызываются. А с таблицей все точки входа во все функции будут располагаться всегда в одном и том же месте, вне зависимости от размера функций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NikolayZ 0 4 октября, 2007 Опубликовано 4 октября, 2007 (изменено) · Жалоба Нужно расположить функцию в заанее известном месте в памяти контроллера и потом обращаться к ней, кстати как потом можно будет обратиться к этой функции из другой функции? Cоветов тут уже надавали кучу и без меня... А у меня всего один вопрос имеющий отношение к делу: А зачем вообще какую-то функцию нужно располагать в "заранее известном месте..."? По-моему логично сперва понять - а нужно ли это и зачем, а уж потом решать такую задачу... Изменено 4 октября, 2007 пользователем Николай Z Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bodja74 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба А зачем вообще какую-то функцию нужно располагать в "заранее известном месте..."? BootLoader,API(IAP),типа дисковая ось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться