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

как разместить подпрограмму по заданному адресу

Почтенные гуру!

Вот выскочила проблемка, не подскажите ли: можно ли разместить подпрограммку по определённому адресу в flash?

Я уже делал такое с данными, прописав в линкере сегмент по определённому адресу:

 

#pragma constseg=MY_SEG;

<данные>

#pragma constseg=default

 

А можно ли такую же вещь сделать с подпрограммой? И как это сделать?

 

main();

{

prog1();

prog2(); - допустим, я хочу разместить эту программу по определённому адресу, а ещё лучше, в выделенном сегменте, в котором будет сидеть только она. Можно?

prog3();

}

 

Я сейчас полезу в первоисточники, но ваше направляющее воздействие позволит значительно облегчить мои метания. Если не трудно, поделитесь опытом!

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


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

Почитайте про секции.

В GCC это будет __attribute__ ((section = "")), в IAR - #pragma location (емнип) или section (давно в руки не брал, забыл уже).

 

А для чего, если не секрет? Недавно тоже пробовали для неких целей.

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


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

Почитайте про секции.

В GCC это будет __attribute__ ((section = "")), в IAR - #pragma location (емнип) или section (давно в руки не брал, забыл уже).

 

А для чего, если не секрет? Недавно тоже пробовали для неких целей.

 

Поясню. Возможно, придётся реализовывать перепрошивку блока по GPRS. Хотелось бы часть программ положить в отдельные сектора и не трогать ни при каких обстоятельствах (продпрограммы включения GSM, собственно, сама подпрограмма перепрошивки). Я бы выделил им свой сегмент, в который линкер бы больше не пытался что-то размещать, и больше не трогал эти адреса, а всё остальное - меняй на здоровье. Это, по моему разумению, гарантировало бы нахождение блока на связи при любых условиях, с возможностью отката до предыдущей версии ПО.

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


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

ГЫ!

Ничего не понял, потыкал, и всё получилось.

 

void myfunc (void) @"BLOCK2", где BLOCK2 - прописанный в линкере сегмент, типа:

 

.

.

.

// -------------------------------------

// Information memory

//

 

-Z(CONST)INFO=1800-19FF

-Z(CONST)INFOA=1980-19FF

-Z(CONST)INFOB=1900-197F

-Z(CONST)INFOC=1880-18FF

-Z(CONST)INFOD=1800-187F

// -------------------------------------

// Low memory 0-0FFFF

//

// ---------------------------

// Code

//

-Z(CODE)CSTART,ISR_CODE=6000-FF7F

// ---------------------------

// Constant data

//

-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=6000-FF7F

// -------------------------------------

// All memory 0-FFFFF

//

// ---------------------------

// Code

//

-P(CODE)CODE=6000-FF7F,10000-45BFF

-Z(CODE)CODE_ID

// ---------------------------

// Constant data

//

-Z(CONST)DATA20_C,DATA20_ID=6000-FF7F,10000-45BFF

//---------------------------------------

// Our segment 5C00..5FFF 1024 bytes

-Z(CODE)BLOCK1=5C00-5DFF

-Z(CODE)BLOCK2=5E00-5FFF

// -------------------------------------

// Interrupt vectors

//

-Z(CODE)INTVEC=FF80-FFFF

-Z(CODE)RESET=FFFE-FFFF

 

Модифицированный линкер надо подключить в настройках вместо стандартного.

При этом чётко кидает функцию по адресу 5E00, и больше ничего туда не пишет. Вах, как харашо!

У меня вопрос снят.

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


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

Спасибо, 1921, за способ. Мне это тоже актуально.

Но предположим мне надо несколько функций разместить по определённым адресам. Интересует несколько моментов:

1) как узнать размер функции?

2) как предотвратить наложение адресов при перепрограммировании, вдруг новая функция растолстела больше диапазона первоначального?

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

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


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

...

1) как узнать размер функции?

Можно разместить ее в отдельном сегменте, и затем вычислять его адрес, через встроенные указатели начала и конца сегмента (__segment_begin("mySeg");__segment_end("meSeg");SFE("mySg");SFB("mySeg"))

2) как предотвратить наложение адресов при перепрограммировании, вдруг новая функция растолстела больше диапазона первоначального?
Можно сделать запас.

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

 

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


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

1) как узнать размер функции?
Сгенерить map-файл.

2) как предотвратить наложение адресов при перепрограммировании, вдруг новая функция растолстела больше диапазона первоначального?
Линковшик выдаст ошибку, если функция не помещается в выделенный для нее сегмент памяти.

3) можно ли при перепрограммировании переложить функцию по другому адресу, где при этом прописать остальной программе, что перепрограммированная функция запускается по новому адресу?
Можно сделать также, как это было в MSDOS. Чтобы была совместимость для программ, адреса вызова функций в этой ОС не менялись от версии к версии. Но по адресу вызова функции стоял JMP на ее реальный адрес, по которому она располагалась в памяти. Вам можно поступить так же, организовав таблицу переходов для вызова функций. Адреса функций в эту таблицу пускай заносит сам компилятор. Не барское это дело на ЯВУ вручную считать адреса и учитывать всякие смещения, чай не на ASMе программируете ;)

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


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

Коллеги! Поясните, пожалуйста, как вы потом планируете работать с такой программой? Распихали "постоянные" функции по конкретным фиксированным адресам. Понятно. Написали некую прикладную программу, которая содержит вызовы этих самых функций. И как линкеру сказать, что эти функции:

 

1. Определены.

2. Адреса их такие-то.

 

Непонятно.

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


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

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

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

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

P.S. если это только не булоадер или какие-то подпрограммы с шифрованием данных, то такие заморочки с принудительным размещением функций могут свидетельствовать о привычках завсегдатая ассемблера, который совсем недавно перешел на Си. ИМХО конечно :)

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


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

2. Адреса их такие-то.

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

 

P.S. если это только не булоадер или какие-то подпрограммы с шифрованием данных, то такие заморочки с принудительным размещением функций могут свидетельствовать о привычках завсегдатая ассемблера, который совсем недавно перешел на Си.

Конечно же это бутлоадер :).

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


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

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

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

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

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

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

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

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

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

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