Полная версия этой страницы:
Программа в двух местах
Дварфик
Jun 16 2009, 10:36
EDK 8.1.02
Где-то в документации видел, что можно размещать разные куски программы в разных местах.
В конкретном случае, программа находится в медленной внешней микросхеме, а хочется разместить часто выполняемые куски кода (маленькие вызываемые функции) в быстрой BRAM памяти.
Недавно нашёл неплохую альтернативу -- использование КЭША. А он использует брамку, поэтому получается ускорение.
Но вот хотелось бы узнать, есть ли, всётаки, функция размещать код где хочешь или её нет.
Мне кажется это связано с linker script. Там генерируется какой-то файл и возможно там можно что-то менять.
Вопрос как это делается. Желательно дайте где это можно конкретно почитать (все пдфки облазил и ничего не нашёл)
Костян
Jun 17 2009, 09:39
Цитата(Дварфик @ Jun 16 2009, 08:36)

EDK 8.1.02
Мне кажется это связано с linker script. Там генерируется какой-то файл и возможно там можно что-то менять.
Вы на верном пути. Осталось только открыть файл линковщика и посмотреть как он прописывается для стандартных примеров с EDK.
Да, все это можно, только довольно геморойно. Нужно создать свою секцию кода в ликовщике, а затем разместить ее по нужному адресу. Потом в проге размещаете функцию в нужную секцию, с помощью атрибутов. Книга GCC Complete reference вам в помощь.
Дварфик
Jun 22 2009, 12:58
Благодарствую за советы, полистав в часности GCC Complete reference нашёл два полезных момента
1) как задавать секции в программе
section
A function with this attribute will have its assembly language
code placed into the named section instead of the default text
section. The following is an example of a function being put
into a section named specials:
void mspec(void) __attribute__((section(“specials”)));
2)как ставить адреса под нужные секции
The following example can be used to generate a linked object file. It takes the sections
of the various input object files and combines them together at the specified addresses:
SECTIONS
{
. = 0x0100000;
.text : {
*(.text)
}
. = 0x8000000;
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}
The SECTIONS keyword specifies that this is a map of the memory layout for the
linked object module. The statements between the opening and closing braces of the
SECTIONS command are taken in order and specify the exact layout of output.
The period is a special variable that contains the current address (also called the
location counter) for insertion of data into the output. The first statement in this example
sets the current address to the absolute value 0x0100000. If it had not been set, the
output address would have defaulted to 0. Once the current address has been set, it
will be incremented automatically by each item added to the output.
Список необходимых действий
1) Пометить все шустрые функции атрибутом(описано выше)
2) В EDK правой кнопкой по проекту Build Project
3) В том же контексном меню щёлкаем по Generate Linker Script ... Видим нашу секцию
4) Щелкаем Generate
5) В Set Compiler Options не забываем поменять с Default Linker Script на Custom ... указываем путь
(он обычно в папке проекта)
6) Не забываем поменять адрес в этом скрипте "<имя програмного проекта>.ld" на нужный нам (как это делается см выше)
7) Делаем окончательную прошивку Build Project (пункт 2)
Получилось!!
Подводные камни: тут в скрипте адреса задаются не явно (со смещением) т.е. для сектора спетиалс:
Мы хотим поместить его по адресу 500АШ придётся написать следующим образом -0х461 это следующий
свободный адрес (заметьте, что " . = (0x500 - 0x461); " находится внутри определения сектора, а не снаружи,
как в примере, потому что снаружи почему-то не работает под EDK). Узнаётся этот адрес только
компилированием. Лично я использую закоментированную часть строки для этого. Вылетает ошибка
следующего рода "cannot move location counter backwards (from 0000096c to 0000046c)" отсюда и берём
следующий свободный адрес. При десятках компилирований программы этот момент будет раздражать.
Но на практике думаю это понадобится только несколько раз при компиляции конечной рабочей программы
specials : {
__specials_start = .;
. = (0x500 - 0x461); /*. = (0x500 - .);*/
*(specials)
__specials_end = .;
} > lmb_bram_if_cntlr_intstruction_lmb_bram_if_cntlr_data
ЗЫ: Чтобы разобраться во всём пришлось убить день
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.