|
Вылет в Abort после LDR, почему это происходит |
|
|
|
Dec 19 2011, 06:49
|

Практикующий маг
     
Группа: Свой
Сообщений: 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Все нашел в чем проблема (и как я не заметил сразу, наверно это всё понедельник  ), предыдущая строчка LDR lr, =AT91C_BASE_AIC 0x200044: 0x00000000 ANDEQ R0, R0, R0 не загружает в LR ничего, видимо с определением чтото, буду разбираться. Странно что ассемблер не ругается
|
|
|
|
|
 |
Ответов
(1 - 9)
|
Dec 19 2011, 09:45
|
Группа: Новичок
Сообщений: 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, то кто-то пишет по этому адресу.
|
|
|
|
|
Dec 19 2011, 12:12
|

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

|
Цитата(Aleph @ Dec 19 2011, 13:45)  <br />Есть подозрение, что ассемблер такого сгенерить не мог. Проверьте сразу после ресета, до выполнения чего бы то ни было, что по этому адресу находится. Если LDR, а не 0x0, то кто-то пишет по этому адресу.<br /><br /> <br /><br /><br /> Точно!  Так и оказалось, банально переполнение массива -поменял число элементов массива, а размерность не поправил.
|
|
|
|
|
Dec 30 2011, 06:17
|

Практикующий маг
     
Группа: Свой
Сообщений: 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 должно при этом находится?
|
|
|
|
|
Dec 30 2011, 08:30
|
.
     
Группа: Участник
Сообщений: 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 в системе один, то этот регистр вектора вообще читать не обязательно. Можно сразу прыгать на этот единственный вектор.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Dec 30 2011, 10:03
|

Практикующий маг
     
Группа: Свой
Сообщений: 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 в системе один, то этот регистр вектора вообще читать не обязательно. Можно сразу прыгать на этот единственный вектор. Извиняюсь, это мой глюк, пока экспериментировал с этими регистрами, забыл вернуть как было. А был там R8 вместо R14. Про него в шапке функции написано: R8 is initialize in Cstartup. Вообщем я его проинициировал =AT91C_BASE_AIC и все заработало. Но возник другой вопрос. Код отвечающий за вход-выход из обычного IRQ только чуть чуть длиннее, чем для FIQ, желание использовать FIQ возникло в виду слишком долгого входа в простое прерывание. Но судя по всему с FIQ я не получу существенной выгоды в скорости? В чем тут можно сэкономить? Не сохранять/восстанавливать РОН и соотв.не использовать их в подпрограмме FIQ? Я по простоте душевной полагал, что происходит переключение банков, и в FIQ можно не боятся испортить значения регистров РОН в которых лежат данные основной программы. Выходит это не так?
|
|
|
|
|
Jan 10 2012, 11:42
|

Практикующий маг
     
Группа: Свой
Сообщений: 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 то выход из обработчика делается без декремента.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|