Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывание LPC2378 не срабатывает.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
svss
Ситуация: после инициализации процессора разрешается прерывание,
в результате в регистре VICADDRESS я вижу адрес входной точки прерывания таймера Timer0IntrHandler (код ниже),
однако ловушки (breakpoints) в обработчике прерываний не срабатывают::

продолжает крутиться main() - "мотает" счётчик loops,
считают аппаратные счётчики таймера, а
lbolt (изменяемый в обработчике прерывания) стоит в нуле.

Регистры:
CPSR = 0x3F
VICIRQSTATUS = 0x0000010 // timer0
VICPRIORITY4 = 9
VICINTENABLE = 0x000010 // timer0

Куда б ещё поглядеть, чтоб понять причину невхода в обработчик прерывания?
Подскажите, кто знает, пож.

Станок: Olimex-LPC2378 + JLINK, инструмент: IAR.

Код
void main(void)
{
    PlatformInit();        
    timer_initialize();    
    i2c_initialize(false);
    uart_initialize();
    __enable_interrupt();

    while(1){
        loops++;
    }//end while(1)
} // main ()


Таблица векторов:
Код
__irq __arm void IRQ_Handler (void) {
    void (*interrupt_function)();
    UINT32 vector;

    vector = VICVectAddr;               // Get the interrupt vector.
    interrupt_function = (void(*)())vector;                                         //  <--- breakpont is set here  ---
    if(interrupt_function != NULL) {
        interrupt_function();           // Call vectored interrupt function.
    } else {
        VICVectAddr = 0;                // Clear interrupt request in VIC.
    }
} // void IRQ_Handler

__irq __arm void Abort_Handler (void)      { while (true); }
__irq __arm void FIQ_Handler (void)        { while (true); }
__irq __arm void Prefetch_Handler (void)   { while (true); }
__irq __arm void SWI_Handler (void)        { while (true); }
__irq __arm void Undefined_Handler (void)  { while (true); }


Обработчик прерываний таймера:
Код
void Timer0IntrHandler (void)
{
    lbolt++;                //                                                  <--- breakpont is set here  ---
    T0IR = 1;               // T0IR.MR0INT = 1; -- Clear interrupt flag */
    VICVectAddr = 0;        // Acknowledge Interrupt.
} // Timer0IntrHandler
baralgin
lbolt объявлен как volatile?
svss
Цитата(baralgin @ May 26 2010, 16:20) *
lbolt объявлен как volatile?

Хммм.
Нет. Дело в том, что я не одну софтину написал и всё как бы работает.. Работало.
Просто не залазил (не имел счасться) настолько глубоко.
Копировал накатанный (свой) код инициализации процессора, UART, таймера .. и вдруг не стало работать.
Сейчас попробую.

----------- (через 5 минут: )

Не помогло. (Да и зачем, казалось бы? Чисто софтовая глобальная переменная)
Было:
Код
UINT32    lbolt;                   /* main clock. 10mS */

Стало:
Код
volatile UINT32    lbolt;    /* main clock. 10mS */



----------- (ещё через 2 минуты: smile.gif

Да и при чём здесь переменные? Не срабатывает прерывание! Debugger breakpoint, то есть.

Спасибо за ответ, anyway. smile.gif
DpInRock
1. Два подряд VICVectAddr = 0; - не фэнщуй.
2. Без понятия volatile вам не жить.
svss
Цитата(DpInRock @ May 26 2010, 18:51) *
1. Два подряд VICVectAddr = 0; - не фэнщуй.
2. Без понятия volatile вам не жить.


1. Спасибо, постараюсь изучить. Хотя, с первого взгляда, операция безопасная, если выполняется с запрещёнными прерываниями (вольная цитата из мануала). Поправьте, ежли вру.
Кроме того я (пока) не вижу двух подряд... Со зрением что или в консерватории crying.gif

2. Volatile, imho нужно для *важных* переменных, имеющих собственное мнение. Типа аппаратных счётчиков.
Глобальные переменные сами по себе не изменяются.
Например, в приведенном коде lbolt программно изменяется в единственном месте и его содержимое +-палка никаких последствий не влечёт. Безопасно то есть.
Если Вы знаете другие причины, зачем бы нужно было метить переменные volatile, поделИтесь, пож. с народом, а то не ровен час таки повымрет весь. smile.gif

Ну, разместил я, скажем, буфер и зарядил на него бесконечный DMA неведомо отколе. Да, он volatile - ну и что? Никаких последствий, пока я сам не придумаю их.
---

Собственно, суть вопроса пока не прояснена. Попробую ещё раз:
Прерывания разрешены.
В регистр VICADDRESS попал нужный адрес из вектора.
СамогО прерывания нет. Почему? Можно ли где чего *увидеть* типа причины?

(переменные, в т.ч. volatile, - это потом. Лишняя запись в VICVectAddr - отличная идея, позволяющая, в случае правды, устранить проблему, но-увы -не увидеть - понять причину)
Сергей Борщ
Цитата(svss @ May 26 2010, 16:12) *
В регистр VICADDRESS попал нужный адрес из вектора.
СамогО прерывания нет. Почему? Можно ли где чего *увидеть* типа причины?
А откуда вы знаете, что он туда попал? Вы его прочитали отладчиком? Поздравляем - вы этим чтением загрузили в него следующий адрес. Закройте окно с регистром VICADDRESS и все заработает.
aaarrr
Цитата(Сергей Борщ @ May 26 2010, 17:24) *
Поздравляем - вы этим чтением загрузили в него следующий адрес.

Дык это ж LPC23xx и контроллер PL192. Переключение логики VIC'а осуществляется записью в VICADDRESS, а не чтением.
svss
Цитата(aaarrr @ May 26 2010, 21:05) *
Дык это ж LPC23xx и контроллер PL192. Переключение логики VIC'а осуществляется записью в VICADDRESS, а не чтением.

Казалось бы, верно (я тоже так дууумал), но не совсем. Как я писал, у меня есть работающие резиденты.

Если перед стартом открыто окошко VIC то прерывание не возникает.
Если закрыть VIC, то после старта прерывания начинают возникать и после этого можно глядеть отладчиком регистры VIC, ходить по шагам и т.д.

Вполне возможно маэстро Сергей Борщ подсказал правильную дорогу. Поклон и благодарность.
Попробую подтвердить гипотезу на резиденте-инвалиде, с которого началась тема.
smile.gif
aaarrr
А не оказался ли VIC "забит" и не сброшен? При инициализации не сбрасываете его записями VICADDRESS?
svss
((Попробую подтвердить гипотезу на резиденте-инвалиде, с которого началась тема.))
smile.gif


---- (прошло 15 минут, попил кофе, подавил кнопки. продолжение)
Как будто, всё заработало. Но не сразу.
Оказывается меня подвело слишком точное следование мануалу (а сбило с толку открытое окно VIC):
Цитата
VICAddress Contains ....ISR. Writing to the register at any other time can cause incorrect operation.

В процессе изысканий я стёр VICAddress = 0; из метода инициализации VIC (он не является ISR и я его счёл за то самое "other time".

1) Закрыл окошко отладчика
2) Восстановил VIC_init { VICAddress = 0; }

работает.
Спасибо. laughing.gif



aaarrr -- отдельный спасиб. Я написал ответ, затем прочитал совет. Всё именно так.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.