реклама на сайте
подробности

 
 
> Вылет в Abort после LDR, почему это происходит
Alexashka
сообщение Dec 19 2011, 06:49
Сообщение #1


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Поскажите пожалуйста, в проекте для ARM под IAR происходит такая беда, после возникновения прерывания (неважно какого из двух) прога попадает в приведенный ассемблерный код, после чего должна перейти собственно на обработчик, но происходит какаято ерунда.

Код
irqHandler:
        /* Save interrupt context on the stack to allow nesting */
        SUB     lr, lr, #4
        STMFD   sp!, {lr}
        MRS     lr, SPSR
        STMFD   sp!, {r0, lr}

        /* Write in the IVR to support Protect Mode */
        LDR     lr, =AT91C_BASE_AIC
        LDR     r0, [r14, #AIC_IVR]
        STR     lr, [r14, #AIC_IVR]


После выполнения 6-й инструкции (пошагово в окне дизассемблера) я попадаю в ячейку с адресом 0x10 (вроде как Abort). Может я чего не понимаю, но LDR по идее должна просто грузить значение в r0. Или тут сложнее? Что конкретно делает данная инструкция LDR r0, [r14, #AIC_IVR]. В дизассемблере эта строчка выглядит так:

Код
        LDR     r0, [r14, #AIC_IVR]
     0x200048: 0xe59e0100     LDR       R0, [LR, #0x100]


В другом проекте все работает нормально, на 6-м шаге в r0 загружается адрес входа в обработчик прерывания, стартапы у проектов одинаковые, настройки тоже. Никак не пойму изза чего это может быть.

Update
Все нашел в чем проблема (и как я не заметил сразу, наверно это всё понедельник sm.gif), предыдущая строчка
LDR lr, =AT91C_BASE_AIC
0x200044: 0x00000000 ANDEQ R0, R0, R0
не загружает в LR ничего, видимо с определением чтото, буду разбираться.
Странно что ассемблер не ругается
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
Aleph
сообщение Dec 19 2011, 09:45
Сообщение #2





Группа: Новичок
Сообщений: 8
Регистрация: 3-12-08
Пользователь №: 42 191



Цитата(Alexashka @ Dec 19 2011, 07:49) *
LDR lr, =AT91C_BASE_AIC
0x200044: 0x00000000 ANDEQ R0, R0, R0
не загружает в LR ничего, видимо с определением чтото, буду разбираться.
Странно что ассемблер не ругается
Есть подозрение, что ассемблер такого сгенерить не мог. Проверьте сразу после ресета, до выполнения чего бы то ни было, что по этому адресу находится. Если LDR, а не 0x0, то кто-то пишет по этому адресу.
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Dec 19 2011, 12:12
Сообщение #3


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(Aleph @ Dec 19 2011, 13:45) *
<br />Есть подозрение, что ассемблер такого сгенерить не мог. Проверьте сразу после ресета, до выполнения чего бы то ни было, что по этому адресу находится. Если LDR, а не 0x0, то кто-то пишет по этому адресу.<br /><br />
<br /><br /><br />
Точно! sm.gif Так и оказалось, банально переполнение массива -поменял число элементов массива, а размерность не поправил.
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Dec 30 2011, 06:17
Сообщение #4


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Снова здорова. Решил замутить обработчик FIQ прерываний. В исходном проекте под IAR5.1 его не было, нашел проект под какойто 4й IAR, вставил из него стартап файл в свой проект, однако он не захотел компилятся. Тогда я перенес в свой стартап только функцию fiqHandler, и вообщемто я в нее попадаю, но та же проблема что и в первом посте, из этой функции вылетаю черте куда. Ошибка возникает при загрузке
ldr r0 , [r14, #AIC_FVR]
в r0 явно грузится какаято шняга
и дальше должен перейти на обработчик
;- Branch to the routine pointed by the AIC_FVR
mov r14, pc
bx r
и вот тут происходит аборт.
#AIC_FVR нигде не нашел, откуда он вообще берется?

Вот код функции из стартапа
Цитата
fiqHandler:

;- Switch in SVC/User Mode to allow User Stack access for C code
; because the FIQ is not yet acknowledged

;- Save and r0 in FIQ_Register
mov r9,r0
ldr r0 , [r14, #AIC_FVR]
msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC
;- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, lr}

;- Branch to the routine pointed by the AIC_FVR
mov r14, pc
bx r0

;- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, lr}

;- Leave Interrupts disabled and switch back in FIQ mode
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ

;- Restore the R0 ARM_MODE_SVC register
mov r0,r9

;- Restore the Program Counter using the LR_fiq directly in the PC
subs pc,lr,#4


Собственно теперь все строки кода нормальные, никаких нулей нету, но вот передаваемое значение #AIC_FVR какоето левое.
Вообще есть у когонибудь рабочий стартап с обработчиком FIQ под IAR5 или 6 версии?
Добавлено: Вообщем в качестве #AIC_FVR подставляется значение 0x00000104, похоже на правду? А что в LR должно при этом находится?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 30 2011, 08:30
Сообщение #5


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Alexashka @ Dec 30 2011, 11:17) *
ldr r0 , [r14, #AIC_FVR]
в r0 явно грузится какаято шняга
и дальше должен перейти на обработчик
;- Branch to the routine pointed by the AIC_FVR
mov r14, pc
bx r0
и вот тут происходит аборт.
#AIC_FVR нигде не нашел, откуда он вообще берется?

Тут явно ошибка в непонятно кем написанном обработчике. При залёте в FIQ, R14 (aka LR) содержит адрес возврата (-4). С чего бы это относительно него происходит загрузка адреса обработчика из контроллера прерываний. По логике, этот R14 нужно сперва сохранить в стеке, потом обнулить, а потом использовать как базу при обращении к контроллеру прерываний. Но равно можно юзать любой другой регистр в качестве базы. У меня вообще первой командой иногда стоит сохранение регистров в стеке, вместе с LR.

Про AIC_FVR не могу сказать, т.к. с Atmel ARM дело не имел. Но вероятно это тот же регистр, который содержит вектор для IRQ. В NXP ARM именно так - регистр общий. Но когда обработчик FIQ в системе один, то этот регистр вектора вообще читать не обязательно. Можно сразу прыгать на этот единственный вектор.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Dec 30 2011, 10:03
Сообщение #6


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(GetSmart @ Dec 30 2011, 12:30) *
Тут явно ошибка в непонятно кем написанном обработчике. При залёте в FIQ, R14 (aka LR) содержит адрес возврата (-4). С чего бы это относительно него происходит загрузка адреса обработчика из контроллера прерываний. По логике, этот R14 нужно сперва сохранить в стеке, потом обнулить, а потом использовать как базу при обращении к контроллеру прерываний. Но равно можно юзать любой другой регистр в качестве базы. У меня вообще первой командой иногда стоит сохранение регистров в стеке, вместе с LR.

Про AIC_FVR не могу сказать, т.к. с Atmel ARM дело не имел. Но вероятно это тот же регистр, который содержит вектор для IRQ. В NXP ARM именно так - регистр общий. Но когда обработчик FIQ в системе один, то этот регистр вектора вообще читать не обязательно. Можно сразу прыгать на этот единственный вектор.

Извиняюсь, это мой глюк, пока экспериментировал с этими регистрами, забыл вернуть как было. laughing.gif
А был там R8 вместо R14. Про него в шапке функции написано: R8 is initialize in Cstartup.
Вообщем я его проинициировал =AT91C_BASE_AIC и все заработало. Но возник другой вопрос. Код отвечающий за вход-выход из обычного IRQ только чуть чуть длиннее, чем для FIQ, желание использовать FIQ возникло в виду слишком долгого входа в простое прерывание. Но судя по всему с FIQ я не получу существенной выгоды в скорости? В чем тут можно сэкономить? Не сохранять/восстанавливать РОН и соотв.не использовать их в подпрограмме FIQ? Я по простоте душевной полагал, что происходит переключение банков, и в FIQ можно не боятся испортить значения регистров РОН в которых лежат данные основной программы. Выходит это не так?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 30 2011, 10:17
Сообщение #7


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



R8-R12 индивидуальные для FIQ. Их можно не сохранять. Но обработчик на Си будет юзать R0-R7, которые придётся сохранять. Всю скорость FIQ можно поиметь только написав обработчик на асме в идеале даже не юзая R0-R7.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Dec 30 2011, 16:05
Сообщение #8


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(GetSmart @ Dec 30 2011, 14:17) *
R8-R12 индивидуальные для FIQ. Их можно не сохранять. Но обработчик на Си будет юзать R0-R7, которые придётся сохранять. Всю скорость FIQ можно поиметь только написав обработчик на асме в идеале даже не юзая R0-R7.

Ясно, спасибо. А можно както указать компилятору не использовать R0-R7 в обработчике FIQ? LR и R12 я так понимаю можно не сохранять так как они банкируются, интересно для чего это делается в данном коде? А вот R4-R7 не сохраняются, видимо компилятору достаточно первых 4 регистра.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 30 2011, 16:19
Сообщение #9


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Alexashka @ Dec 30 2011, 21:05) *
А можно както указать компилятору не использовать R0-R7 в обработчике FIQ? LR и R12 я так понимаю можно не сохранять так как они банкируются,...

Какому компилятору? - хотя не важно. Скажу только за IAR. Там есть служебное слово __fiq, которое указывает, что сохранять в обработчике R8-R12 не нужно. Но функции, вызываемые из этой функции-обработчика будут юзать младшие регистры.

ЗЫ. LR сохранять надо полюбому. Почему - читайте документацию на АРМ.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Alexashka
сообщение Jan 10 2012, 11:42
Сообщение #10


Практикующий маг
******

Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576



Цитата(GetSmart @ Dec 30 2011, 20:19) *
Какому компилятору? - хотя не важно. Скажу только за IAR. Там есть служебное слово __fiq, которое указывает, что сохранять в обработчике R8-R12 не нужно. Но функции, вызываемые из этой функции-обработчика будут юзать младшие регистры.

ЗЫ. LR сохранять надо полюбому. Почему - читайте документацию на АРМ.

Добавил в обработчик FIQ директиву __fiq и теперь внутри обработчика используются только регистры R8-R12. Это очень радует! Сохранение регистров R0...R7 перед входом в обработчик выкинул, LR тоже не сохраняю, т.к у меня нет вложенных быстрых прерываний, вообщем время входа в обработчик уменьшилось раза в 3 наверно. Однако почемуто теперь возврат из обработчика делается не копированием в PC значения из LR, а с декрементом на 4, поэтому перед входом в обработчик приходится в LR записывать значение PC+4. Зачем так сделано не понял. Если не указывать директиву __fiq то выход из обработчика делается без декремента. 05.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 16:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01452 секунд с 7
ELECTRONIX ©2004-2016