Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: почему может сботь контроллер прерываний VIC?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
sergik_vrn
пишу проект под LPC2478 + FreeRTOS, столкнулся со следующей проблемой - при использовании аппаратных прерываний (VIC) при каких-то условиях происходит их полное отключение. то есть, в отладчике видно, что все нужные регистры VIC сконфигурированы, биты прерываний установлены, VicAddress показывает куда надо - но прерывания не происходят, то есть процессор тупо стоит в пустом цикле. Отследить все как следует не удается, проблемы начались, вроде бы, когда я задействовал прерывания модуля USB, но четкой связи не вижу, развязка с операционкой сделана вроде бы так же, как во всех остальных модулях. Может быть, есть какая-то стандартная ошибка, которую делают все новички, или особенность этого ядра? До этого работал с STR710, там ничего подобного не наблюдалось
GetSmart
Телепатически трудно угадать что Вы как новичёк забыли сделать.
Версия №1
Забыли записать VICVectAddr = 0 в конце прерывания для сброса приоритетов в VIC ?
aaarrr
Проверьте, всегда ли VIC сбрасывается записью в VICVecAddr по окончании обслуживания прерывания.
sergik_vrn
Цитата(GetSmart @ Jan 21 2009, 13:29) *
Телепатически трудно угадать что Вы как новичёк забыли сделать.
Версия №1
Забыли записать VICVectAddr = 0 в конце прерывания для сброса приоритетов в VIC ?

все прерывания сделаны следующим образом (в соответствии с портом FreeRTOS):

usb_isr.s79
Код
        RSEG ICODE:CODE
        CODE32

        EXTERN vUSB_ISR
        PUBLIC vUSB_ISREntry

vUSB_ISREntry:

    portSAVE_CONTEXT        ; Save the context of the current task.

    LDR R0, =vUSB_ISR
    mov     lr, pc
    BX R0

    portRESTORE_CONTEXT        ; Restore the context of the current task -
                            ; which may be different to the task that
                            ; was interrupted.
        END


usb_main.c
Код
BOOL USB_isr()
{
    if (USBINTS & 0x00000008)
    {
        u32 int_status    = HCINTERRUPTSTATUS;
        u32 ie_status     = HCINTERRUPTENABLE;

        if (!(int_status & ie_status))
            return FALSE;
        else
        {
            int_status = int_status & ie_status;
            if (int_status & OR_INTR_STATUS_RHSC)
            {                 /* Root hub status change interrupt     */
                if (HCRHPORTSTATUS1 & OR_RH_PORT_CSC)
                {
                    if (HCRHPORTSTATUS1 & OR_RH_PORT_CCS)
                        HOST_RhscIntr = 1;
                    else
                        HOST_RhscIntr = 0;
                    HCRHPORTSTATUS1 = OR_RH_PORT_CSC;
                }
                if (HCRHPORTSTATUS1 & OR_RH_PORT_PRSC)
                    HCRHPORTSTATUS1 = OR_RH_PORT_PRSC;
            }
            if (int_status & OR_INTR_STATUS_WDH)  // Writeback Done Head interrupt
                HOST_WdhIntr = 1;
            HCINTERRUPTSTATUS = int_status;   // Clear interrupt status register
        }
    }

    return FALSE; // context switch?
}

// ********************************************************************
// ********************************************************************
// USB ISR.  This can cause a context switch
// The interrupt service routine - called from the assembly entry point.
extern "C" void vUSB_ISR( void );
void vUSB_ISR( void )
{
    // If a task was woken by either a character being received or a character
    // being transmitted then we may need to switch to another task.
    portEND_SWITCHING_ISR(USB_isr());

    // End the interrupt in the EIC
    VICADDRESS = 0; // clear interrupt
}



Цитата(aaarrr @ Jan 21 2009, 13:31) *
Проверьте, всегда ли VIC сбрасывается записью в VICVecAddr по окончании обслуживания прерывания.

сбрасывается вроде бы всегда. но вообще, я не совсем понимаю этот механизм, в даташите написано очень коротко и расплывчато, что подразумевается под "в конце прерывания", можно ли считать точку перед выполнением portRESTORE_CONTEXT концом прерывания?
aaarrr
Цитата(sergik_vrn @ Jan 21 2009, 13:38) *
сбрасывается вроде бы всегда. но вообще, я не совсем понимаю этот механизм, в даташите написано очень коротко и расплывчато, что подразумевается под "в конце прерывания", можно ли считать точку перед выполнением portRESTORE_CONTEXT концом прерывания?

Возьмите даташит на сам VIC - там все расписано весьма подробно.
sergik_vrn
Цитата(aaarrr @ Jan 21 2009, 13:45) *
Возьмите даташит на сам VIC - там все расписано весьма подробно.

спасибо, щас попробую почитать
GetSmart
Сбрасывать нужно когда между этой командой и выходом из обработчика все прерывания полностью запрещены. Если внутри обработчика глобальные прерывания вообще не разрешаются, то сбрасывать VIC можно в любой момент.
sergik_vrn
Цитата(GetSmart @ Jan 21 2009, 13:49) *
Сбрасывать нужно когда между этой командой и выходом из обработчика все прерывания полностью запрещены. Если внутри обработчика глобальные прерывания вообще не разрешаются, то сбрасывать VIC можно в любой момент.

а вот, кстати, где разрешаются и запрещаются глобальные прерывания? запрещает ли их процессор автоматически при вызове прерывания? в описании VIC указано, что он при чтении адреса вектора запрещает все прерывания приоритетом не ниже текущего
aaarrr
Цитата(sergik_vrn @ Jan 21 2009, 13:56) *
а вот, кстати, где разрешаются и запрещаются глобальные прерывания? запрещает ли их процессор автоматически при вызове прерывания? в описании VIC указано, что он при чтении адреса вектора запрещает все прерывания приоритетом не ниже текущего

Процессор запрещает прерывания при входе в режим IRQ. VIC запрещает прерывания на своем уровне.
Сергей Борщ
Цитата(sergik_vrn @ Jan 21 2009, 12:25) *
при использовании аппаратных прерываний (VIC) при каких-то условиях происходит их полное отключение.
Это случайно происходит не после того, как вы остановившись отладчиком в теле обработчика жмете на "сброс"? В таком случае сбрасывается только ядро, а VIC так и остается с необслуженным прерыванием и запрещенными прерываниями с приоритетом равным и ниже текущего. Для ИАРа надо в .mac-файл отладчика в execUserReset() дописать запись 0 в VICVectAddr.
sergik_vrn
Цитата(Сергей Борщ @ Jan 21 2009, 14:20) *
Это случайно происходит не после того, как вы остановившись отладчиком в теле обработчика жмете на "сброс"? В таком случае сбрасывается только ядро, а VIC так и остается с необслуженным прерыванием и запрещенными прерываниями с приоритетом равным и ниже текущего. Для ИАРа надо в .mac-файл отладчика в execUserReset() дописать запись 0 в VICVectAddr.

спасибо за совет. вообще, использование отладчика это отдельная песня sad.gif как правило, после ресета программа вообще не стартует, процессор зависает и не отзывается на jtag. хотя у меня при старте выполняется в том числе и сброс VIC. а иногда возникает ощущение, что проблемы с прерываниями вообще провоцируются использованием отладчика, то есть, после пары-тройки остановов начинаются... кстати, так и должно быть, что под отладчиком программа выполняется раза в 4 медленнее и на ЖК-индикаторе странный такой дребезг?
aaarrr
Цитата(Сергей Борщ @ Jan 21 2009, 14:20) *
Для ИАРа надо в .mac-файл отладчика в execUserReset() дописать запись 0 в VICVectAddr.

Тогда уж лучше не один "0" - прерываний может быть несколько (хотя и не в данном случае).
Сергей Борщ
Цитата(sergik_vrn @ Jan 21 2009, 13:28) *
кстати, так и должно быть, что под отладчиком программа выполняется раза в 4 медленнее и на ЖК-индикаторе странный такой дребезг?
Дребезга быть не должно. Медленно выполняетеся, если отладчик не подерживает софтовые точки останова, а все аппаратные вы заняли и даете команду run to cursor - тогда он начинает выполнять программу покомандно. Но там замедление не в 4 раза, а сильно больше. Какой отладчик, какая среда?

Цитата(sergik_vrn @ Jan 21 2009, 13:28) *
хотя у меня при старте выполняется в том числе и сброс VIC.
А не открыто ли у вас в отладчике при этом окно регистров VIC? Чтение VICVectAddr отладчиком для отображения приводит к тем же последствиям, что и чтение его программой - к блокировке прерываний с более низким приоритетом.

Цитата(aaarrr @ Jan 21 2009, 13:29) *
Тогда уж лучше не один "0"
Согласен. Лишние записи не повредят.
sergik_vrn
Цитата(Сергей Борщ @ Jan 21 2009, 14:36) *
Дребезга быть не должно. Медленно выполняетеся, если отладчик не подерживает софтовые точки останова, а все аппаратные вы заняли и даете команду run to cursor - тогда он начинает выполнять программу покомандно. Но там замедление не в 4 раза, а сильно больше. Какой отладчик, какая среда?

отладчик МТ-линк, среда IAR 5.20, драйвер segger 3.92, отладочная плата SK-LPC2478-S3E
вот именно что не сильно больше, с STR у меня такого не было, но тут процессор новый, кто его знает... выполняется одинаково медленно даже если вообще не задавать точек останова, просто дать команду run из-под отладчика.

Цитата
А не открыто ли у вас в отладчике при этом окно регистров VIC? Чтение VICVectAddr отладчиком для отображения приводит к тем же последствиям, что и чтение его программой - к блокировке прерываний с более низким приоритетом.

а вот это может быть. а что будет, если я в этот момент вручную запишу VICADDRESS из-под отладчика? или он снова его прочитает, и так 15 раз... понял, спасибо, хоть с этим разобрался
Сергей Борщ
Цитата(sergik_vrn @ Jan 21 2009, 13:59) *
а вот это может быть.
Не знаю как в 5.хх, а в 4.хх окна регистров описывались в .ddf файлах. Вытрите из него упоминание о VIСVectAddr, и можете держать окно открытым.
sergik_vrn
Цитата(Сергей Борщ @ Jan 21 2009, 15:26) *
Не знаю как в 5.хх, а в 4.хх окна регистров описывались в .ddf файлах. Вытрите из него упоминание о VIСVectAddr, и можете держать окно открытым.

в этом так же. да после того, как стало понятно, в чем дело, это уже не проблема smile.gif но все равно какая-то беда с прерываниями наблюдается sad.gif и со скоростью
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.