Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не генерируются прерывания в STR912
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
artur_off
Здравствуйте господа.

Возникла следующая проблема. В процессоре STR912 не хотят генерироваться прерывания. Вот код инициализации прерываний:

Код
VIC_DeInit();
                  VIC_InitDefaultVectors();
              
                    VIC_Config(TIM3_ITLine, VIC_IRQ, 0);
    VIC_ITCmd(TIM3_ITLine, ENABLE);



Прерывания в таймере также включены: TIM_ITConfig(TIM3, TIM_IT_OC1, ENABLE);

При отладке видно, что в VIC и в таймере прерывания настроены и таймер считает. Но при достижении значения счетного регистра равному регистру сравнения OC1R в прерывание заходить не хочет

Код
TIM_CounterCmd(TIM3, TIM_STOP);
          TIM_CounterCmd(TIM3, TIM_CLEAR);
              var_delay++;
          if(var_delay == 60000) var_delay = 0;
          TIM_ClearFlag(TIM3, TIM_FLAG_OC1);
          TIM_CounterCmd(TIM3, TIM_START);
    VIC0->VAR = 0xFF;


MALLOY2
Я не пользуюсь ST библиотеками, и все нормально работает.

1) Другие прерывания есть ?

2) Глобально прерывания разрешены ?

3) в программе не получается так что сначала специализируется прерывание таймера к примеру в 0 слот, а потом при инициализации чего нить другого в этот слот назначаются другие прерывания ? тобиш одно прерывание перезаписывает другое.
artur_off
Сейчас настроено только одно прерывание - от таймера.
Пробовал возится с другими прерываниями - тоже самое.
Если вас не затруднит, можете показать свой пример?

Цитата
2) Глобально прерывания разрешены ?

А вот по поводу этого у меня есть сомнения.
artur_off
Переписал настройку VIC, но ничего не изменилось.
Код
u32 mask = 1;
    // Init VIC
    VIC_DeInit();
    // initialize VICs default vector registers
    VIC_InitDefaultVectors();
    
    // Configure TIM3 interrupt in VIC
    VIC0->VAiR[0] = (u32)(void*)(TIM3_IRQHandler);
    VIC0->INTSR &= ~(mask<<TIM3_ITLine);
    VIC0->VCiR[0] |= 0x20;
    VIC0->VCiR[0] &= 0xFFFFFFE0;
    VIC0->VCiR[0] |= TIM3_ITLine;
    VIC0->INTER |= (mask << TIM3_ITLine); // enable interrupt
aaarrr
Дык в CPSR-то прерывания разрешены?
artur_off
Цитата(aaarrr @ Jan 5 2010, 13:12) *
Дык в CPSR-то прерывания разрешены?


Не разрешены. Но не могу догнать, как их включить. Не могу нигде найти описание CPSR. Даже в reference manual.
aaarrr
Цитата(artur_off @ Jan 5 2010, 14:28) *
Не разрешены. Но не могу догнать, как их включить.

Стартап свой приложите.

Цитата(artur_off @ Jan 5 2010, 14:28) *
Не могу нигде найти описание CPSR. Даже в reference manual.

Искать нужно в reference manual на ядро.
artur_off
Цитата(aaarrr @ Jan 5 2010, 13:36) *
Стартап свой приложите.


Искать нужно в reference manual на ядро.



Не загружается файл.

CODE
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size

; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size

; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size

; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size

; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size



Я так понимаю, это здесь. 
aaarrr
Цитата(artur_off @ Jan 5 2010, 14:44) *
Не загружается файл. Где надо смотреть в стартапе?

Смотреть, что загружается в CPSR (команда MSR) перед уходом в C-часть. Если это "стандартный" кейловский STR91x.s, то прерывания в нем разрешены.

Цитата(artur_off @ Jan 5 2010, 14:44) *
Я так понимаю, это здесь. 

Да. Это последний MSR, или есть еще переход в SYSTEM/USER?
artur_off
Цитата(aaarrr @ Jan 5 2010, 13:49) *
Смотреть, что загружается в CPSR (команда MSR) перед уходом в C-часть. Если это "стандартный" кейловский STR91x.s, то прерывания в нем разрешены.


Да. Это последний MSR, или есть еще переход в SYSTEM/USER?



CODE
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size

; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB

EXPORT __initial_sp

ELSE

MOV SP, R0
SUB SL, SP, #USR_Stack_Size

  ENDIF

вот последний MSR, дальше вход в main

после него при симуляции бит I в CPSR сбрасывается в 0.
aaarrr
Цитата(artur_off @ Jan 5 2010, 14:56) *
после него при симуляции бит I в CPSR сбрасывается в 0.

Значит все в порядке, прерывания глобально разрешены.
artur_off
А вот при отладке флаг I не сбрасывается.
aaarrr
Цитата(artur_off @ Jan 5 2010, 15:08) *
А вот при отладке флаг I не сбрасывается.

Т.е. после команды MSR CPSR_c, #Mode_USR, в младшем байте CPSR оказывается 0xD0?
artur_off
Цитата(aaarrr @ Jan 5 2010, 14:18) *
Т.е. после команды MSR CPSR_c, #Mode_USR, в младшем байте CPSR оказывается 0xD0?

0xD3

То есть вы стыкались с таким?
aaarrr
Цитата(artur_off @ Jan 5 2010, 15:40) *
То есть вы стыкались с таким?

Нет. У вас вообще получается, что последняя команда MSR не выполнена. Честно говоря, не знаю, как такое может быть sad.gif
А что происходит с CPSR в реальном железе, без отладчика?
artur_off
Цитата(aaarrr @ Jan 5 2010, 14:46) *
Нет. У вас вообще получается, что последняя команда MSR не выполнена. Честно говоря, не знаю, как такое может быть sad.gif
А что происходит с CPSR в реальном железе, без отладчика?


Вот то и получается, что в CPSR оказывается 0xD3

Вопрос. Что надо сделать, чтобы после загрузки в контроллер, можно было начать отладку не с main, а с стартапа.

Убирание галочки с Run to main() не помогает.



А не может H-JTAG при отладке как то прерывания отключать?
aaarrr
Цитата(artur_off @ Jan 5 2010, 16:25) *
А не может H-JTAG при отладке как то прерывания отключать?

А без отладчика не пробовали тот же CPSR прочитать? Под отладчиком, да еще при открытых окошках VIC'а/периферии может быть что угодно.
artur_off
Цитата(aaarrr @ Jan 5 2010, 15:32) *
А без отладчика не пробовали тот же CPSR прочитать? Под отладчиком, да еще при открытых окошках VIC'а/периферии может быть что угодно.


Пробовал и без отладчика. НО все равно не срабатывает.

Вот например поставил, чтобы нога меняла свое состояние по прерыванию. Отключил отладчик, но ничего не происходит.

Судя по отладке, он остается в режиме Supervisor, но разрешение прерываний в этом режим ничего не меняет.
Vladimir_T
Нужно внимательно просмотреть инициализацию переферии (контроллера VIC, Timer) и разрешение их работы (снять Reset), а также тактирование выбранной переферии. В библиотеках ST, действительно, трудно разбираться, потому в отладчике нужно просмотреть инициализацию и тактирование.
artur_off
 Прерывания завелись, но прерывание происходит только один раз. Методом проб и ошибок выяснилось, что при выходе из прерывания он то ли виснет, то ли не может вернуться в main();
MALLOY2
h-jtag тут не причем.

функция обработчик прерывания должна быть специально оформлена с помощью ключевого слова (в IAR "__irq __arm void interrupt_function(void)") или обвертку написать на асме.
artur_off
Цитата(MALLOY2 @ Jan 5 2010, 20:32) *
h-jtag тут не причем.

функция обработчик прерывания должна быть специально оформлена с помощью ключевого слова (в IAR "__irq __arm void interrupt_function(void)") или обвертку написать на асме.


Дело в том, что в прерывание он уже заходит, но прерывание происходит один раз, хотя должно быть каждую секунду(прерывание таймера по совпадению), а потом то ли зависает, то ли чтото не то с стеком, так как дальше абсолютно никаких действий не происходит.
По поводу H-JTAG. При отладке прерывания не работают вобще, то есть надо проверять без отладчика.

Заливаю свежую прошивку, выхожу из отладки, ресет процу, одно прерывание и тишина.



Компилятор у меня KEIL. C ИАРом не дружу.
artur_off
Методом тыка выяснил причину проблемы(спасибо MALLOY2)
в файлах 91x_it.c и 91x_it.h функции для обработки прерываний объявлены так void TIM3_IRQHandler(void),
а надо вот так __irq void TIM3_IRQHandler(void).
Но в таком случае возникает вполне закономерный вопрос, неужели ребята из KEIL и ST могли так лопухнуться?
Или все же я чтото натворил?
aaarrr
Цитата(artur_off @ Jan 5 2010, 23:31) *
Но в таком случае возникает вполне закономерный вопрос, неужели ребята из KEIL и ST могли так лопухнуться?
Или все же я чтото натворил?

Ну так поделитесь с общественностью сначала, что вы натворили, и в результате чего прерывания заработали?

В кейловских примерах для STR910 модификатора для процедур прерываний нет, а вектор из стартапа уводит в ST'шную "бибилиотеку", что наводит на мысль, что в ней уже все предусмотрено. Не думаю, что могли лопухнуться.
artur_off
Дело было вот в чём, прерывание одно появлялось, но я не мог засечь его по одной простой причине, скорость счета таймера была очень высокая. Поставил делители на максимум, появилось одно прерывание и процессор уходил в неизвестность.
Потом после выяснения истории с функциями-обработчиками, прерывания завелись нормально.
Немного позже проверю на остальных прерываниях.
О результатах обязательно отпишусь.
Буду рад услышать замечания и рассуждения по этому поводу, так как сам сомневаюсь, что ошибка в библиотеках. 
artur_off
C остальными прерываниями точно такая же ситуация. Приходится в объявлении обработчика писать __irq void ......().
prussta
Здравствуйте! У меня возникла подобная проблема с STR912. Есть рабочий проект (был создан в старой версии keil v.3.53) Там прерывания работают. А если собрать новый проект в новом кейле (пробовала в keil v.4.13 и v.4.53) с этими же файлами проекта, файлами библиотеки, и с тем же стартапом, то прерывания не отрабатываются. Выполняется один раз и все. Прерывания глобально разрешены, настроены, но программа в прерывания больше не заходит. Хитрость с __irq не работает. Не могу понять в чем причина. У кого-нибудь было подобное? Помогите разобраться. Спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.