|
почему может сботь контроллер прерываний VIC? |
|
|
|
Jan 21 2009, 10:25
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
пишу проект под LPC2478 + FreeRTOS, столкнулся со следующей проблемой - при использовании аппаратных прерываний (VIC) при каких-то условиях происходит их полное отключение. то есть, в отладчике видно, что все нужные регистры VIC сконфигурированы, биты прерываний установлены, VicAddress показывает куда надо - но прерывания не происходят, то есть процессор тупо стоит в пустом цикле. Отследить все как следует не удается, проблемы начались, вроде бы, когда я задействовал прерывания модуля USB, но четкой связи не вижу, развязка с операционкой сделана вроде бы так же, как во всех остальных модулях. Может быть, есть какая-то стандартная ошибка, которую делают все новички, или особенность этого ядра? До этого работал с STR710, там ничего подобного не наблюдалось
|
|
|
|
|
Jan 21 2009, 10:38
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(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 концом прерывания?
|
|
|
|
|
Jan 21 2009, 10:46
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(aaarrr @ Jan 21 2009, 13:45)  Возьмите даташит на сам VIC - там все расписано весьма подробно. спасибо, щас попробую почитать
|
|
|
|
|
Jan 21 2009, 10:56
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

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

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

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

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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" Согласен. Лишние записи не повредят.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 21 2009, 11:59
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Сергей Борщ @ Jan 21 2009, 14:36)  Дребезга быть не должно. Медленно выполняетеся, если отладчик не подерживает софтовые точки останова, а все аппаратные вы заняли и даете команду run to cursor - тогда он начинает выполнять программу покомандно. Но там замедление не в 4 раза, а сильно больше. Какой отладчик, какая среда? отладчик МТ-линк, среда IAR 5.20, драйвер segger 3.92, отладочная плата SK-LPC2478-S3E вот именно что не сильно больше, с STR у меня такого не было, но тут процессор новый, кто его знает... выполняется одинаково медленно даже если вообще не задавать точек останова, просто дать команду run из-под отладчика. Цитата А не открыто ли у вас в отладчике при этом окно регистров VIC? Чтение VICVectAddr отладчиком для отображения приводит к тем же последствиям, что и чтение его программой - к блокировке прерываний с более низким приоритетом. а вот это может быть. а что будет, если я в этот момент вручную запишу VICADDRESS из-под отладчика? или он снова его прочитает, и так 15 раз... понял, спасибо, хоть с этим разобрался
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|