Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Глюк линкера в ewarm 4.31A (код в рам)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
SpiritDance
Исходные:
Есть маленький проектик в котором используются ассемблерные подпрограммы размещающиеся в сегменте CODE_I.
проблема:
В нужном месте вместо функций при помощи отладчика наблюдал мусор в RAM.
Проблема была устранена когда объявил одну из функций C как __ramfunc
причина:
У иара есть таблица в сегменте INITTAB, в нее записываются перерменные для функции __segment_init. Так вот, если в сишном коде не определяется ни одной функции в рам значения для сегмента CODE_I прибиваются, несмотря на то что в этом сегменте существуют вызывающиеся в сишном коде ассемблерные функции. Все это видно в map файле линкера.

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

ЗЫ. Подобное поведение наблюдал в crossworks, но детально пока не изучал.
KRS
Это не глюк линкера!
просто надо добавить данные в сегмент INITTAB и указать что надо CODE_I копировать, надо просто добавить в asm файл несколько команд
Код
PUBWEAK ?init?tab?CODE_I
        PUBWEAK `?*?CODE_ID`
        RSEG CODE_ID:CODE:NOROOT(2)
`?*?CODE_ID`:

        RSEG INITTAB:CODE:ROOT(2)
        DATA
?init?tab?CODE_I:
        DCD      sfe(CODE_I) - sfb(CODE_I), sfb(CODE_I), sfb(CODE_ID)
SpiritDance
07.gif Помогло.
Выглядит как шаманское заклинание. Можно чуть подробнее о том что здесь написано? Я подозреваю что это определение для сегмента code_i в модуле. Вот только откуда выдран этот кусок кода? Я, вроде, в листингах такого не встречал.
KRS
Цитата(SpiritDance @ Jul 3 2007, 11:16) *
07.gif Помогло.
Выглядит как шаманское заклинание. Можно чуть подробнее о том что здесь написано? Я подозреваю что это определение для сегмента code_i в модуле.

У IAR есть магическое слово PUBWEAK
это аналог PUBLIС, за исключением того, что если присутсвует несколько меток с одинаковым названием линкер выберет на свое усмотрение одну и не будет конфликта ( поэтому код должен быть одинаков)
кусок
Код
PUBWEAK ?init?tab?CODE_I
RSEG INITTAB:CODE:ROOT(2)
        DATA
?init?tab?CODE_I:
        DCD      sfe(CODE_I) - sfb(CODE_I), sfb(CODE_I), sfb(CODE_ID)

как раз вставляется во все файлы где есть __ramfunc, он везде одинаков и добавляет в сегмент INITTAB описание куда копировать CODE_ID

зачем используется
Код
PUBWEAK `?*?CODE_ID`
        RSEG CODE_ID:CODE:NOROOT(2)
`?*?CODE_ID`:

я не разбирался

Кстати есть еще одня фича - если есть много PUBWEAK и один PUBLIC, то линкер выберет PUBLIC, я это использовал в своем stratup для AVR и линкер вообще убирал сегмент INITTAB
примерно так
Код
//NEAR_Z initialization
        RSEG   STARTUPCODE:CODE:NOROOT(1)
PUBLIC `?<Segment init: NEAR_Z>`
`?<Segment init: NEAR_Z>`:
          lda   Z, SFB(NEAR_Z)
          lda   X, SIZEOF(NEAR_Z)
          clr   r16
filloop:
          st    Z+, r16
          sbiw XL, 1
          brne filloop

//NEAR_I initialization
        RSEG   STARTUPCODE:CODE:NOROOT(1)
PUBLIC `?<Segment init: NEAR_I>`
`?<Segment init: NEAR_I>`:
          lda   Z, SFB(NEAR_ID)
          lda   Y, SFB(NEAR_I)
          lda   X, SIZEOF(NEAR_I)
moveloop:
          lpm r0, Z+
          st Y+, r0
          sbiw XL, 1
          brne moveloop

Причем если нет сегмента NEAR_Z или NEAR_I то соотв. участок кода выкидывается поэтому не надо проверять длину сегмента на 0 если код включатся значит копировтаь надо больше 0 байт!!.
(lda - макрос для загрузки парного регистра)

К сожалению в ARM сегмент INITA_TAB можно выкинуть, но вот определить естть ли сегменты NEAR_Z или NEAR_I не получатся, у них по другому генерятся директивы компилятором, поэтому надо проверять длину на 0 и оба куска кода всегда будут.

Цитата(SpiritDance @ Jul 3 2007, 11:16) *
Вот только откуда выдран этот кусок кода? Я, вроде, в листингах такого не встречал.


Надо смотреть не листинг!!! а файлы asm (поставить опцию гененрировать asm файлы)
SpiritDance
Спасибо за ликбез. smile.gif
MALLOY2
может немного не в тему но есть директива __root которая может применятся как к переменным так и к функциям, а смысл ее в том что она заставляет компилятор оставить функцию или переменную даже если она нигде не используется. Тоесть если вы прменили эту дерективу к функции то эта функция 100% попадет в код даже если ее никто не вызывает.
SpiritDance
Это не в тему. smile.gif
Проблема была не в том что неиспользуемые функции выкидывались - они присутствовали, только в рам не переписывались.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.