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

Подскажите, уважаемые, как бороться с такой чепухой: (WinAVR-20090313)

 

Пишу софтину с printf_P периодически выскакивает error: relocation truncated to fit для фрагментов с его использованием.

меняю порядок компиляции файлов - все попускает. Можно ли заставить линкер как-то перетасовать объектники автоматиццки?

Автоматически он делает в том порядке, в каком файлы указаны в командной строке.

Вероятно память у Вас разбита на нескольков кусков в скрипте? Какие-то секции идут в один кусок, другие в другой. Ну если у Вас действительно так, то ошибка вполне законна. Добавили код - перестало влазить, что-то поменяли - размер уменьшился - опять влазит.

Или вот такое

http://www.motherboardpoint.com/relocation...ans-t94967.html

Изменено пользователем amw

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


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

Пишу софтину с printf_P периодически выскакивает error: relocation truncated to fit для фрагментов с его использованием.
Это не оно?

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


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

Всем спасибо.

 

Отключил -mshort-calls проблема ушла. На том и остановился, поскольку почти влез в 60%  флеша

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


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

Отключил -mshort-calls проблема ушла. На том и остановился...
Я аналогично сделал (m128 забита на 80%) :(

Но чуть позднее в TODO добавил посмотрть эффект ключей оптимизации:

-freorder-blocks

-freorder-blocks-and-partition

-freorder-functions

-ftoplevel-reorder

однако пока так и не добрался проверить, помогут ли они сохранить отсутствие jmp.

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


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

Можно ли как-нибудь создать один регион памяти из двух кусков,

например что-то вроде:

 

MFlash512 (rx)     : (ORIGIN = 0x20000, LENGTH = 0x1000) OR (ORIGIN = 0x40000, LENGTH = 0x1000)

:help:????

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


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

Можно ли как-нибудь создать один регион памяти из двух кусков,

например что-то вроде:

 

MFlash512 (rx)     : (ORIGIN = 0x20000, LENGTH = 0x1000) OR (ORIGIN = 0x40000, LENGTH = 0x1000)

:help:????

 

Написал этот вопрос в поддержку. Посмотрим, что ответят.

 

Получил ответ :)

Hi,

 

You just need to change ".boot" to ".text" in your linker script.

 

Full details on linker scripts can be found in the documentation at:

Help->Help Contents

Code Red Technologies Documentation

Tools Documentation

GNU Linker

Section 3 "Linker Scripts"

 

Best regards,

 

Попробовал поменять:

 

    .text : /* .boot*/
    {
        KEEP(*(.isr_vector));
        KEEP(*(.crp_key));
        KEEP(*(.macaddr));
        KEEP(*(.ipaddr));
            
    } > BOOTMEM

    .text :
    {
        *(.text*)
        *(.rodata*)
    } > MFlash512

 

Не работает.

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


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

После длительной переписки со службой поддержки выяснилось, что надо было делать совсем подругому, нежели в IAR5.x.

MEMORY
{
  /* Define each memory region */
  CODE_MEM (rx)       : ORIGIN = 0x0,         LENGTH = 0x00003000
  MAC_IP_MEM(rx)    : ORIGIN = 0x00003000,     LENGTH = 0x00002000
  Ram32 (rwx)         : ORIGIN = 0x40000000,     LENGTH = 0x8000     /* 32k */
  RAM_ETH_16 (rwx)     : ORIGIN = 0x7fe00000,     LENGTH = 0x4000     /* 16k */
  RAM_USB_8 (rwx)     : ORIGIN = 0x7fd00000,     LENGTH = 0x2000     /* 8k */
  RAM_RTC_2 (rwx)     : ORIGIN = 0xe0084000,     LENGTH = 0x800     /* 2k */
}

.text :
{
     KEEP(*(.isr_vector));   /*вектора прерываний*/
     . = 0x000001FC;         /*смещение указателя на адрес CRP*/
    KEEP(*(.crp_key));      /*секция CRP*/
    *(.text*)                     /*код программы*/
    *(.rodata*)                 /*константы*/
} > CODE_MEM

.MacIpMem :   /*. = 0x00003000;*/
{
   
    KEEP(*(.macaddr))      /*размещаем по адресу 0x00003000*/
        . = 0x00001000;          /*переход на адрес 0x00001000;*/
        KEEP(*(.ipaddr))    /*размещаем по адресу 0x00004000*/
} > MAC_IP_MEM

 

Вот так почти правильно размещать свой код в разные областя памяти.

Теперь про почти:

Инициализируемая константа находится в исходнике, задается следующим образом:

const BYTE OurMacAddr[6] __attribute__ ((section(".macaddr"))) = {0x00,0x01,0x02,0x03,0x04,0x06};

Инициализируется мусором!!! Почему???

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


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

После длительной переписки со службой поддержки выяснилось, что надо было делать совсем подругому, нежели в IAR5.x.
Вы конечно извините, но то, что вы показали и исходный ваш вопрос "Можно ли как-нибудь создать один регион памяти из двух кусков" имеют мало общего. Ибо вопрос подразумевает, что задаются два региона и одно описание выходной секции, а линкер впихивает сколько влезет в первый регион и остаток во второй. Вам же нужно было разместить секцию по конкретному адресу, а это совсем другой вопрос.

 

По поводу мусора - надо смотреть листинг и .map

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


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

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

По поводу мусора - надо смотреть листинг и .map

 

Как я понял, вектора прерываний и код должны сидеть в одной секции. У меня в проекте Iar, секции располагались следующим образом:

- Вектора прерываний

- CRP ключ

- Основной код

- MAC адрес

- IP адрес

В IAR каждая секция у меня сидела в своем регионе памяти. Между векторами и основным кодом сидела секция CRP. Но в GNU Linker вроде бы как нельзя разделять их по разным регионам. Поэтому я решил что можно выйти из этой ситуации, создав секцию .text из двух кусков (поэтому так и задал этот вопрос. :laughing:, про операцию = ADDR. не догадывался ). Один кусок расположить в свободной области между векторами и CRP, а второй после CRP. Однако так тут так тоже нельзя делать.

А надо было выделить один регион памяти и напихать туда по очереди все секции, а адреса смещать при помощи операции .= ADDR.

Собственно как тут и сделано:

    .text :
    {
    KEEP(*(.isr_vector));
    . = 0x000001FC;
        KEEP(*(.crp_key));
        *(.text*)
        *(.rodata*)
    } > CODE_MEM

 

По поводу мусора - надо смотреть листинг и .map

Про map смотреть сюда?:

.MacIpMem       0x00003000     0x1004
*(.macaddr)
.macaddr       0x00003000        0x6 ./src/Emac.o
                0x00003000                OurMacAddr

Как можно листинг посмотреть?

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


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

После разговора со службой поддержики. И после того как я выслал свой проект к ним.

Получил информацию, что мой проект у них компилируется и зашивается нормально.

После разбора в чем может быть дело, оказалось что просто не зашиваются нужные регионы с константами в процессор.

Разбираемся дальше, почему.

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


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

Инициализируемая константа находится в исходнике, задается следующим образом:

const BYTE OurMacAddr[6] __attribute__ ((section(".macaddr"))) = {0x00,0x01,0x02,0x03,0x04,0x06};

Инициализируется мусором!!! Почему???

Наверное неправильно написан стартап-код, который и занимается инициализацией (как кариант, инициализация просто забыта, и эта секция просто остается неинициализированной). Кстати, а что говорит objdump -d -j .macaddr <объектный файл> ? Может там вообще этой секции нет? :)

Как я понял, вектора прерываний и код должны сидеть в одной секции.
Совершенно необязательно. Хотите - размещайте в одной, хотите - в разных.

В IAR каждая секция у меня сидела в своем регионе памяти. Между векторами и основным кодом сидела секция CRP. Но в GNU Linker вроде бы как нельзя разделять их по разным регионам.
Неверный вывод. Разделять можно. Кстати, Вы не путаете секции и регионы? Это не одно и то же...

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


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

Наверное неправильно написан стартап-код, который и занимается инициализацией (как кариант, инициализация просто забыта, и эта секция просто остается неинициализированной).

Эти константы находятся во флешь.

У меня проблема несколько в другом. Мой код отлично работает у службы поддержки Code-Red. А у меня тупо не зашиваются эти константы в процессор.

Уже несколько дней разбираемся в чем может быть дело. :unsure:

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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