|
Вопрос по IAR, Настройки среды программирования |
|
|
|
 |
Ответов
(45 - 59)
|
Jan 6 2014, 13:29
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Уже устал биться с линкером. Помогите... У меня в проекте на ассемблере 2 файла (1 и 2). В 1 основные функции программы, во 2 так сказать рутинные функции (умножение, деление и прочее). Функции из файла 2 вызываются в 1 файле посредством директив PUBLIC и EXTERN. XCL-файл я использую свой. Его содержимое, состоящее из одной строки, такое: Код -Z(CODE)CODE=FC60-FFDF,9668-97EB // Весь мой код должен быть в этих диапазонах адресов Перед каждой функцией в файлах 1 и 2 я указываю сегмент размещения. Делаю это вот так (на примере функции умножения): Код RSEG CODE:NOROOT:REORDER:SORT Mul16u16uTo32u: DINT NOP MOV R12, &MPY MOV R13, &OP2 MOV &RESLO, R12 MOV &RESHI, R13 EINT RET Все было хорошо, пока мой код был мал. Линкер его размещал начиная с адреса FC60. Я думал, что когда закончится место в диапазоне FC60-FFDF, то линкер начнет размещать код в диапазоне 9668-97EB. Однако этого не произошло. Когда размер скомпилированного кода стал превышать размер диапазона FC60-FFDF, то линкер выдал мне ошибку: Цитата Linking Error[e16]: Segment CODE (size: 0x384 align: 0x1) is too long for segment definition. At least 0x4 more bytes needed. The problem occurred while processing the segment placement command "-Z(CODE)CODE=FC60-FFDF,9668-97EB", where at the moment of placement the available memory ranges were "CODE:fc60-ffdf,CODE:9668-97eb" Reserved ranges relevant to this placement: 9668-97eb CODE fc60-ffdf CODE Error while running Linker Total number of errors: 1 Total number of warnings: 0 Я попробовал изменить порядок диапазонов адресов в XCL-файле. Однако это не помогло. Линкер выдает ту же ошибку. Что самое интересное, после изменения порядка адресов в XCL-файле, я убрал некоторые строки кода (чтобы "все стало помещаться"). После компиляции ошибки не стало, однако линкер все равно размещает код в диапазоне FC60-FFDF, хотя в XCL-файле этот диапазон прописан после диапазона 9668-97EB. Подскажите, что за напасть и как с ней бороться...  P.S. Для информации: CODE NOROOT, ROOT NOROOT means that the segment part is discarded by the linker if no symbols in this segment part are referred to. Normally, all segment parts except startup code and interrupt vectors should set this flag. The default mode is ROOT which indicates that the segment part must not be discarded.
REORDER, NOREORDER REORDER allows the linker to reorder segment parts. For a given segment, all segment parts must specify the same state for this flag. The default mode is NOREORDER which indicates that the segment parts must remain in order.
SORT, NOSORT SORT means that the linker sorts the segment parts in decreasing alignment order. For a given segment, all segment parts must specify the same state for this flag. The default mode is NOSORT which indicates that the segment parts are not sorted.
Сообщение отредактировал d7d1cd - Jan 6 2014, 13:35
|
|
|
|
|
Jan 6 2014, 14:59
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(rezident @ Jan 6 2014, 17:52)  Приложите в сообщению весь ваш XCL-файл полностью. Приложил...
|
|
|
|
|
Jan 6 2014, 15:46
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(SM @ Jan 6 2014, 19:30)  Сделайте еще одну секцию с кодом, с другим именем, и вынесете в нее часть кода. На сколько я знаю, нельзя одну секцию разделить на два диапазона адресов, должно быть две разные секции. Я понимаю, что можно так сделать. Но ведь хочется эту работу возложить на линкер. Тем более было тут сообщение уважаемого rezidenta: Цитата Вам просто нужно для сегмента CODE указать несколько диапазонов адресов, перечислив их через запятую. Вот там я пояснял как правильно отредактировать XCL-файл.
|
|
|
|
|
Jan 6 2014, 16:57
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(d7d1cd @ Jan 6 2014, 19:46)  Я понимаю, что можно так сделать. Но ведь хочется эту работу возложить на линкер. Вообще, обычно линкеры не могут сами разбивать секцию на части, потому что не знают, как это корректно делать, в каком месте. Возможно, конечно, у IAR есть подсекции функций, или еще какие то механизмы для указания линкеру, как ему можно разбить секцию, но я этих механизмов в рамках IAR-а не знаю. В любом случае, требуются какие то директивы/указания, в каком месте секции можно разрывать - линкер сам этого не знает, и поэтому ругается.
|
|
|
|
|
Jan 6 2014, 17:16
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(SM @ Jan 6 2014, 20:57)  Вообще, обычно линкеры не могут сами разбивать секцию на части, потому что не знают, как это корректно делать, в каком месте. Возможно, конечно, у IAR есть подсекции функций, или еще какие то механизмы для указания линкеру, как ему можно разбить секцию, но я этих механизмов в рамках IAR-а не знаю. В любом случае, требуются какие то директивы/указания, в каком месте секции можно разрывать - линкер сам этого не знает, и поэтому ругается. Тогда для чего придуманы флаги для директивы RSEG (REORDER, SORT)? Про NOROOT знаю для чего: если данный код не используется, то линкер не вставляет его в готовую прошивку.
|
|
|
|
|
Jan 6 2014, 19:17
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(d7d1cd @ Jan 6 2014, 21:16)  Тогда для чего придуманы флаги для директивы RSEG (REORDER, SORT)? Про NOROOT знаю для чего: если данный код не используется, то линкер не вставляет его в готовую прошивку. Я так подозреваю, что все это касается частей одной секции, располагающейся в разных объектных модулях - потому что куски одноименной секции точно можно перемешивать в порядке размещения, если они были скомпилированы из разных отдельных исходных файлов. Но именно подозреваю. Да и NOROOT тоже - о неиспользуемости кода линкер может судить только по одному принципу - что в модуле нет ни точки входа, и ни одного использованного PUBLIC-символа. Но, именно, в секции модуля, которая внутри каждого модуля едина. PS повторюсь, я не слышал, чтобы у IAR был механизм подсекций для процедур/функций - именно поэтому, вроде, на сколько я помню, секция внутри каждого модуля едина (для того и придумана, чтобы код/данные можно было прерывать, перемежать, в т.ч. в макросах, а потом все стало едиными цельными и гарантировано последовательными кусками), а вот куски секции, собираемые из разных модулей, линкер может менять местами, сортировать, выкидывать, и т.д.
|
|
|
|
|
Feb 27 2014, 16:09
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(rezident @ Feb 27 2014, 19:38)  Сделать что "это"? Переменные вы и так обязаны объявлять в своей программе. Я пишу на ассемблере. Чтобы разместить код функции по определенному адресу, я пишу: Код RSEG MySegment Mul16u16uTo32u: ... RET А в файле XCL или в опциях линкера и прописываю: Код -Z(CODE)MySegment=1200-1300 Так вот: нельзя ли обойтись без файла XCL и опций линкера и описание сегмента расположить в файле, где расположен код функции.
|
|
|
|
|
Feb 27 2014, 16:56
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(_Артём_ @ Feb 27 2014, 20:54)  Может и можно - посмотрите в документации есть ли у IAR директива ASEG или аналогичная. ASEG есть. И ASEGN есть. Какую директиву использовать? Не особо я силен в англицком. Подскажите в чем отличие этих директив друг от друга и от директивы RSEG? Вот их описание в документации: CODE Beginning an absolute segment Use ASEG to set the absolute mode of assembly, which is the default at the beginning of a module. If the parameter is omitted, the start address of the first segment is 0, and subsequent segments continue after the last address of the previous segment. Note: If a move of an immediate value to an absolute address, for example mov #0x1234, 0x300 is made in a relocatable or absolute segment, the offset is calculated as if the code begun at address 0x0000. The assembler does not take into account the placement of the segment.
Beginning a named absolute segment Use ASEGN to start a named absolute segment located at the address address. This directive has the advantage of allowing you to specify the memory type of the segment.
Beginning a relocatable segment Use RSEG to start a new segment. The assembler maintains separate location counters (initially set to zero) for all segments, which makes it possible to switch segments and mode anytime without having to save the current program location counter. Up to 65536 unique, relocatable segments can be defined in a single module.
Beginning a common segment Use COMMON to place data in memory at the same location as COMMON segments from other modules that have the same name. In other words, all COMMON segments of the same name start at the same location in memory and overlay each other. Obviously, the COMMON segment type should not be used for overlaid executable code. A typical application would be when you want several different routines to share a reusable, common area of memory for data. It can be practical to have the interrupt vector table in a COMMON segment, thereby allowing access from several routines. The final size of the COMMON segment is determined by the size of largest occurrence of this segment. The location in memory is determined by the XLINK -Z command; see the IAR Linker and Library Tools Reference Guide. Use the align parameter in any of the above directives to align the segment start address.
Сообщение отредактировал d7d1cd - Feb 27 2014, 17:28
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|