Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как прочитать link register в переменную
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
xelax
Портирую код из arm-elf-gcc в iar, стал возникать perfetch abort. Хочу почитать LR в локальную переменную в обработчике этой исключительной ситуации, но в синтаксисе IARа пока не силён.

Кто-нибудь знает как это сделать?
aaarrr
У атмеловких ARM'ов есть Abort Status Register и Abort Address Status Register, посмотрите описание Memory Controller'а.

А для извлечения LR и остальных регистров лучше писать свой обработчик.
xelax
Цитата(aaarrr @ Jun 24 2008, 11:05) *
У атмеловких ARM'ов есть Abort Status Register и Abort Address Status Register, посмотрите описание Memory Controller'а.

А для извлечения LR и остальных регистров лучше писать свой обработчик.


Есть то он есть, но там адрес записан, по которому неправильный доступ был, а в каком месте кода он произошёл озябнешь искать, особенно если код пишется несколькими людьми и не один месяц.

Самый простой вариант посмотреть адрес возврата из прерывания, а следовательно предыдущая инструкция вызвала исключение. Для этого необходимо прочитать LR регистр и посчитать смещение. А как это сделать на IAR C я не умею. 05.gif
aaarrr
На "C" такие вещи как-то вообще делать не стоит. Вот мой asm-обработчик:

Код
    INCLUDE    arm.inc

; ***************************************************************************
; *

    EXPORT prefetch_abort_handler

    IMPORT prefetch_abort_handler_c

; ***************************************************************************
; *

    AREA code0, CODE, READONLY

; ***************************************************************************
; *

prefetch_abort_handler
        sub        r14, r14, #0x04
        stmfd    r13!, {r14}
        stmfd    r13!, {r0-r3, r12}

        ldr        r0, =regs_temp
        str        r14, [r0], #0x04
        mov        r14, r0
        ldr        r0, [r13]
        stmia    r14!, {r0-r12}
        mov        r0, r14

        mrs        r14, SPSR
        stmfd    r13!, {r14}
        orr        r14, r14, #F_BIT :OR: I_BIT
        msr        CPSR_c, r14
        stmia    r0!, {r13-r14}
        mov        r0, #F_BIT :OR: I_BIT :OR: ARM_MODE_ABORT
        msr        CPSR_c, r0

        ldr        r0, =regs_temp
        bl        prefetch_abort_handler_c

        ldmfd    r13!, {r0}
        msr        SPSR_c, r0

        ldmfd    r13!, {r0-r3, r12, pc}^

; ***************************************************************************
; *

    AREA code1, DATA, READWRITE

regs_temp
    SPACE    0x40

    END


Вызывает prefetch_abort_handler_c и передает ему указатель на структуру (LR_abt-4, R0-R14).
zltigo
Цитата(xelax @ Jun 24 2008, 09:27) *
Самый простой вариант посмотреть адрес возврата из прерывания...

И получите адрес в какой-нибудь функции, например, memcpy вызываемой из сотни мест sad.gif. Короче еще стек сохранять (мне обычно 8 хватает) придется...
xelax
Возможно туплю, но не понятно откуда вы стек читаете. В arm в abort моде свой собственный стек и в текущем режиме ядра(abort mode) указатель стека, например на system(irq, fiq, supervisor в зависимости от того где исключение произошло) не доступен. Зато доступен указатель на стек abort режима. smile.gif
zltigo
Цитата(xelax @ Jun 24 2008, 11:22) *
Возможно туплю, но не понятно откуда вы стек читаете.

Естественно, по указателю того режима из котрого вылетели в Abort.
xelax
Цитата(zltigo @ Jun 24 2008, 13:28) *
Естественно, по указателю того режима из котрого вылетели в Abort.


А как вы режим узнаёте из которого вылетели в Abort, теоретически это может быть какой угодно.
aaarrr
Цитата(xelax @ Jun 24 2008, 13:34) *
А как вы режим узнаёте из которого вылетели в Abort, теоретически это может быть какой угодно.

На то есть SPSR.
xelax
Ок. Спасибо.

Ещё вопрос, как в IAR сделать функцию на C без пролога и эпилога?
zltigo
Цитата(xelax @ Jun 24 2008, 17:10) *
как..

Зачем?
xelax
Цитата(zltigo @ Jun 24 2008, 19:14) *
Зачем?


Что бы в обработчике исключения(сишная функция) не записывался LR в стек.

Ситуацию воспроизвёл, но LR оказалось указывает на мою функцию, сделал дизасм и увидел, что в эпилоге LR(настоящий) запихиватся в стек.

Пока ничего умней, чем в начале функции восстанавливать сохранённые регистры из стека руками не придумал.
Понятно, что это убьёт программу, но это нужно только для отладки, чтобы убить эксепшн.
zltigo
Цитата(xelax @ Jun 24 2008, 17:47) *
Пока ничего умней...

Умнее - Вам пример дали. А о глупостях, типа __noreturn и иже с ней и говорить не хочется.
xelax
Цитата(zltigo @ Jun 24 2008, 19:58) *
А о глупостях, типа __noreturn и иже с ней и говорить не хочется.


Но всё таки сказали wink.gif

Спасибо за подсказки.
Alex03
Цитата(xelax @ Jun 24 2008, 21:10) *
Ещё вопрос, как в IAR сделать функцию на C без пролога и эпилога?

Не знаю как в IAR, а
в GCC __attribute__((naked)).
у MS __declspec( naked )
и т.д.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.