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

 
 
 
Reply to this topicStart new topic
> Адрес функции
Vadim.Dyachuk
сообщение Oct 24 2013, 08:46
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 9-10-13
Пользователь №: 78 662



Доброго времени суток!

Как можно узнать адрес определенной процедуры или функции которая находится в Boot Section?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 24 2013, 09:45
Сообщение #2


Гуру
******

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



QUOTE (Vadim.Dyachuk @ Oct 24 2013, 11:46) *
Как можно узнать адрес определенной процедуры или функции которая находится в Boot Section?
Вы так формулируете вопрос, что даже и непонятно, что на него отвечать. Что в этой теме, что в ваших предыдущих.
Этот адрес нужен вам лично, вы его хотите увидеть глазами или его нужно использовать в вашей программе?
Если первое - смотрите .map -файл той программы, которая загружена в область загрузчика.
Если второе - то функция является частью этой же программы или же какой-то другой?

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


--------------------
На любой вопрос даю любой ответ
"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
Vadim.Dyachuk
сообщение Oct 24 2013, 10:00
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 9-10-13
Пользователь №: 78 662



Извините за неполное формулирование предложения.

Я хочу в основной программе (которая находится а AppSection) вызвать процедуру которая находится в BootLoader'е. Но для этого мне нужно знать адрес этой процедуры. Поскольку я пишу программу в IAR EW то его компилятор не дает нормального .map-файла, и по этому я решил спросить у Вас, как можно определить этот адрес программно или хотя бы вручную (увидеть своими глазами).
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 24 2013, 10:21
Сообщение #4


Гуру
******

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



QUOTE (Vadim.Dyachuk @ Oct 24 2013, 13:00) *
Извините за неполное формулирование предложения.

Я хочу в основной программе (которая находится а AppSection) вызвать процедуру которая находится в BootLoader'е. Но для этого мне нужно знать адрес этой процедуры.
Теперь понятно. Но если делать так, как вы хотите - это будет работать до того момента, как вы захотите что-то поменять (исправить) в BootLoader`е и адрес этой функции "уплывет".

QUOTE (Vadim.Dyachuk @ Oct 24 2013, 13:00) *
Поскольку я пишу программу в IAR EW то его компилятор не дает нормального .map-файла,
Неправда, ой неправда... Либо вы не включили его генерацию, либо не разобрались в его содержимом. Вот отрывок из моего очень-очень старого проекта:
CODE
################################################################################
#                                                                              #
#      IAR Universal Linker V4.53O/WIN                                         #
#                                                                              #
#           Link time     =  18/May/2005  13:09:41                             #
.........
CODE
  Relative segment, address: CODE 00000506 - 00000527 (22 bytes), align: 1
  Segment part 28.
           ENTRY                   ADDRESS         REF BY
           =====                   =======         ======
           main                    00000506        ?cstartup_call_main (?C_STARTUP)


QUOTE (Vadim.Dyachuk @ Oct 24 2013, 13:00) *
и поэтому я решил спросить у Вас, как можно определить этот адрес программно или хотя бы вручную (увидеть своими глазами).
Вот теперь вопрос понятнен. Посмотрите ответ на аналогичный вопрос тут и тут. Там описана идея. Вам останется просто переложить ее на ваш компилятор. Увы, с IARом давно не работаю, поэтому дать готовое решение для вашего случая не могу.


--------------------
На любой вопрос даю любой ответ
"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
zombi
сообщение Oct 24 2013, 10:56
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Пишу только на ассемблере.
И если мне нужно "прыгать" между разными программами компилируемыми отдельно,
то адреса входов всех необходимых функций размещаю по фиксированным заранее определённым адресам в начале.
Что бы ничего не "уплывало".
Может и на СИ тоже так же можно.
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Oct 25 2013, 09:48
Сообщение #6


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(zombi @ Oct 24 2013, 14:56) *
...адреса входов всех необходимых функций размещаю по фиксированным заранее определённым адресам...


+1
правильный ответ...

я больше скажу, можно не только звать из бута, можно звать "не зная адреса" и те функции, которые находятся внутри переписываемого блока. Для этого достаточно сделать следующее:
1) закрепить за каждой такой функцией дальний джамп из таблицы переходов.
2) разместить таблицу переходов по фиксированным адресам
3) всегда использовать табличный переход как "дальний колл" по статичному адресу таблицы.
(в принципе ничего нового, см. устройство форточной дэлеле).

Более того. Если не перезаписывать флэш, а писать рядом (определить две области - одну пишем, во второй работаем). И определить две таких таблицы, а контрольные вещи целостности этих участков флэша упаковать сразу за таблицей векторов (как правило таблица векторов меньше чем сегмент записи), то перепрошивать можно на лету с достаточно высокой отказоустойчивостью (т.е. слетит только, если слетит первый сектор флэша).

схема рабочая, в одном проекте под авр-ки так и юзаю...

Go to the top of the page
 
+Quote Post
ARV
сообщение Oct 25 2013, 10:06
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



появилась одна идея по поводу этого вопроса... в МК с секцией бутлоадера есть одна область, которая гарантированно никуда не переместится - область таблицы векторов. если в своей программе выделить часть векторов под свои интерфейсные функции, то при помощи этой таблицы можно отлично выкрутиться! допустим, вектор переполнения таймера_1 в бутлоадере не используется, и мы используем этот вектор для функции чтения команды из USART, например. саму функцию организуем в виде традиционного для GCC макроса ISR, только в конце вместо return используем ассемблерную вставку с ret вместо reti.
по-моему, должно получиться...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 25 2013, 12:19
Сообщение #8


;
******

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



Можно откусить 2-3 байта ОЗУ под адрес размещения таблицы. Надо подправить инит стека в стартапе приложения и поскольку бут стартует первым, он должен в последние ячейки записать адрес таблицы.

Можно написать бут таким образом, чтобы проверить, со сброса ли мы попали на адрес старта бута, если нет, то вернуть адрес таблицы.
Тогда вызов может быть таким
Код
void *(*boot_func)(void);
//blah blah
boot_func = (void*) BOOT_ADDRESS;//это здеся фиксир адрес старта загрузчика
function_tbl = boot_func();// get address of table


Передача параметров, очевидно, должна быть в виде указателя на структуру.
Дальше, можно вынести в хедер то, что используется из бута и сделать две реализации этого набора - через собственно вызов в буте и через формирование описанного выше вызова.
Соглашения о регистрах лучше использовать свои, т.е. при передаче параметров их адрес структуры должен быть в самостоятельно определенной паре регистров.
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 25 2013, 13:15
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(ARV @ Oct 25 2013, 14:06) *
появилась одна идея по поводу этого вопроса... в МК с секцией бутлоадера есть одна область, которая гарантированно никуда не переместится - область таблицы векторов. если в своей программе выделить часть векторов под свои интерфейсные функции, то при помощи этой таблицы можно отлично выкрутиться! допустим, вектор переполнения таймера_1 в бутлоадере не используется, и мы используем этот вектор для функции чтения команды из USART, например. саму функцию организуем в виде традиционного для GCC макроса ISR, только в конце вместо return используем ассемблерную вставку с ret вместо reti.
по-моему, должно получиться...


жалко нет софтверных прерываний sm.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 25 2013, 14:25
Сообщение #10


Гуру
******

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



QUOTE (Tarbal @ Oct 25 2013, 16:15) *
жалко нет софтверных прерываний sm.gif
Ну да. Если бы они были, это делалось бы через команды SWI(123) или INT 21h sm.gif


--------------------
На любой вопрос даю любой ответ
"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
_Pasha
сообщение Oct 25 2013, 14:52
Сообщение #11


;
******

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



Цитата(Tarbal @ Oct 25 2013, 16:15) *
жалко нет софтверных прерываний sm.gif

Собственно, есть еще удобный вариант, тсз в развитие @ARV.
Поскольку на неиспользуемые прерывания ставится WEAK-заглушка, можно переписать её для обработки нашего SWI (в тексте бута, ессно) - и вызывать любым понравившимся способом, вплоть до генерации хардверного прерывания.
Правда, ограничения на IVSEL и LOCK с запрещением чтения, выполнения итд не позволят.
--
По сему, универсальных решений нет.

Сообщение отредактировал _Pasha - Oct 25 2013, 14:57
Go to the top of the page
 
+Quote Post
ARV
сообщение Oct 26 2013, 08:41
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 27 2013, 14:35
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(ARV @ Oct 26 2013, 12:41) *
а софтверное прерывание для обращения к "вектору" и не требуется. номер вектора нам известен, адрес начала таблицы нам известен. длина элемента таблицы нам известна. путем простых вычислений мы легко определяем адрес этого вектора и делаем обычный вызов функции по указателю... джамп на саму функцию уже проставлен в таблице компилятором - что еще надо?
допустим, прерывание по срабатыванию аналогового компаратора в загрузчике - оно хотя бы теоретически кому-нибудь может понадобиться? почему бы его не сделать "стандартной" точкой входа по типу int21 ? wink.gif

Да мы и в первый раз поняли. Просто подход/отход был бы стандартным и более простым.
Go to the top of the page
 
+Quote Post

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

 


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


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