|
Проблемы с таймером в AT91SAM7S64 |
|
|
|
Feb 26 2006, 05:53
|
Участник

Группа: Свой
Сообщений: 72
Регистрация: 4-02-05
Пользователь №: 2 424

|
Не получается работать с таймерами в AT91SAM7S64. Точнее с прерываниями от таймеров. Дело вот в чём: Инициализируем таймеры на прерывание при совпадении, запускаем.. При первом совпадении, прерывание происходит, в обработчике делаю: dummy = TC_pt->TC_SR;, всё вроде становится в исходный режим, таймер сбрасывается и продолжает считать, но при совпадении, флаг CPCS устанавливается, но прерывания не происходит.. Почему так?
|
|
|
|
|
Feb 26 2006, 16:23
|
Частый гость
 
Группа: Новичок
Сообщений: 170
Регистрация: 26-05-05
Из: Москва
Пользователь №: 5 405

|
Цитата(Artem @ Feb 26 2006, 08:53)  Не получается работать с таймерами в AT91SAM7S64... Как разберёшься, отпиши, как проблему решил. У меня так же перестают отрабатывать прерывания через некоторое время после запуска. Спасибо. P.S. Вот часть кода моего cstartup.s79: Код ... org 0x18 ldr pc,[pc,#24]; Переход к irq_handler ... org 0x38 dc32 IRQ_Handler_Entry;IRQ_Handler_Entry 0x18 ... ;------------------------------------------------------------------------------ ;- Function : IRQ_Handler_Entry ;- Treatments : IRQ Controller Interrupt Handler. ;- Called Functions : AIC_IVR[interrupt] ;------------------------------------------------------------------------------
IRQ_Handler_Entry:
;- Manage Exception Entry ;- Adjust and save LR_irq in IRQ stack sub lr, lr, #4 stmfd sp!, {lr}
;- Save SPSR need to be saved for nested interrupt mrs r14, SPSR stmfd sp!, {r14}
;- Save and r0 in IRQ stack stmfd sp!, {r0}
;- Write in the IVR to support Protect Mode ;- No effect in Normal Mode ;- De-assert the NIRQ and clear the source in Protect Mode ldr r14, =AT91C_BASE_AIC ldr r0 , [r14, #AIC_IVR] str r14, [r14, #AIC_IVR]
;- Enable Interrupt and Switch in System Mode msr CPSR_c, #ARM_MODE_SYS
;- Save scratch/used registers and LR in User Stack stmfd sp!, { r1-r3, r12, r14}
;- Branch to the routine pointed by the AIC_IVR mov r14, pc bx r0
;- Restore scratch/used registers and LR from User Stack ldmia sp!, { r1-r3, r12, r14}
;- Disable Interrupt and switch back in IRQ mode msr CPSR_c, #I_BIT | ARM_MODE_IRQ
;- Mark the End of Interrupt on the AIC ldr r14, =AT91C_BASE_AIC str r14, [r14, #AIC_EOICR]
;- Restore R0 ldmia sp!, {r0}
;- Restore SPSR_irq and r0 from IRQ stack ldmia sp!, {r14} msr SPSR_cxsf, r14
;- Restore adjusted LR_irq from IRQ stack directly in the PC ldmia sp!, {pc}^
LTORG ENDMOD
END
|
|
|
|
|
Feb 27 2006, 02:41
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(aaarrr @ Feb 26 2006, 23:50)  Цитата(defunct @ Feb 26 2006, 23:43)  А зачем вложенные прерывания делать?! Специально чтобы работало неправильно?
Можно подумать, будто использование вложенных прерываний на ARM кто-то объявил вне закона  Встречный вопрос: поясните, почему неправильно? я не говорю, что неправильно (в постах выше было сказано, что работает неправильно - затыкается таймер). Использование вложенных прерываний значительно усложняет структуру программы, и требует особой внимательности при проектировании программы. Любая неточность при проектировании может привести к тому, что устройство, выполнение обработчика прерывания которого было отложено на случайной команде, может сгенерировать уже следующее прерывание. А это следующее прерывание может потребовать совсем иной обработки, а вернувшись назад к отложенному обработчику мы это учесть не сможем. Собственно, что похоже и имеет место у уважаемого Master 'a: Цитата У меня так же перестают отрабатывать прерывания через некоторое время после запуска.
|
|
|
|
|
Feb 27 2006, 10:02
|
Частый гость
 
Группа: Новичок
Сообщений: 170
Регистрация: 26-05-05
Из: Москва
Пользователь №: 5 405

|
Цитата(defunct @ Feb 27 2006, 05:41)  я не говорю, что неправильно ... Давайте по порядочку. Цитата Использование вложенных прерываний значительно усложняет структуру программы Разве? По мне, так наоборот упрощает. Особенно когда прерывание занимает некоторое время, в течение которого может произойти событие, которое необходимо наверняка обработать. В простейшем случае нужно лишь увеличить соответствующий стек. Цитата и требует особой внимательности при проектировании программы Не надо сгущать краски, любая программа требует внимательности! Точка. Цитата Любая неточность при проектировании может привести к тому, что устройство, выполнение обработчика прерывания которого было отложено на случайной команде, может сгенерировать уже следующее прерывание. Согласен. Но кто мешает написать обработчик, который не допустит срабатывание другого прерывания на СЛУЧАЙНОЙ команде?? Соответственно, пишем код грамотно. Цитата похоже и имеет место у уважаемого Master 'a Спасибо за уважение. Однако мой случай несколько разнится с обсуждаемым. Моя проблема состоит в том, что программа работает, прерывания происходят, входные сообщения UART'а обрабатываются, но через некоторое время прерывания перестают обрабатываться, и дело, как выяснилось, не во вложенности - проверил путём запрещения прерываний перед выполнением функции внутри обработчика прерывания: вместо Код msr CPSR_c, #ARM_MODE_SYS сделал Код msr CPSR_c, #I_BIT | ARM_MODE_SYS Возможно, стоит создать отдельную ветку...
|
|
|
|
|
Feb 27 2006, 11:33
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Master @ Feb 27 2006, 12:02)  Цитата(defunct @ Feb 27 2006, 05:41)  я не говорю, что неправильно ...
Давайте по порядочку. Цитата Использование вложенных прерываний значительно усложняет структуру программы Разве? Конечно! Если вам кажется, что наоборот, так это только кажется. Цитата По мне, так наоборот упрощает. Особенно когда прерывание занимает некоторое время, в течение которого может произойти событие, которое необходимо наверняка обработать. Для такого редкого и важного события существует FIQ. Для всех остальных - IRQ. Цитата Согласен. Но кто мешает написать обработчик, который не допустит срабатывание другого прерывания на СЛУЧАЙНОЙ команде?? Соответственно, пишем код грамотно. Вы уже продемонстрировали, как надо правильно писать обработчик (и вам ведь никто не мешал), странно только почему же прерывания затыкаются? может все-таки что-то не учитытваете? Цитата Моя проблема состоит в том, что программа работает, прерывания происходят, входные сообщения UART'а обрабатываются, но через некоторое время прерывания перестают обрабатываться, Проблема была ясна еще из предыдущего поста, зачем же повторяться? ;> Цитата и дело, как выяснилось, не во вложенности - проверил путём запрещения прерываний перед выполнением функции внутри обработчика прерывания: А в чем же тогда? Не бывает ничего просто так. Проблему ищите только в обработчиках. PS: Если мой пост вам покажется грубым, извините я сегодня очень "не в духе", если можно так выразиться..
Сообщение отредактировал defunct - Feb 27 2006, 11:38
|
|
|
|
|
Feb 27 2006, 13:55
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(defunct @ Feb 27 2006, 14:33)  Вы уже продемонстрировали, как надо правильно писать обработчик (и вам ведь никто не мешал), странно только почему же прерывания затыкаются? может все-таки что-то не учитытваете? ... ...Проблему ищите только в обработчиках. Если Вы имеете в виду приведенный Master'ом фрагмент кода, то это обработчик из примеров Atmel, и написан он вполне корректно. Утверждение, что проблема заключается в обработчиках прерываний, без знания остального кода, мягко говоря, голословно.
|
|
|
|
|
Feb 28 2006, 02:51
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(defunct @ Feb 28 2006, 04:59)  Даже без знания остального кода, этой проблеме больше не откуда взяться.. Я неверно выразился в предыдущем посте - мы не знаем никакого кода, а гадать - занятие неблагодарное. Цитата(defunct @ Feb 28 2006, 04:59)  Для начала можно поробовать сигнализировать (End of int) в самом конце обработчика. Не понял, что имеется в виду - запись в AIC_EOICR?
|
|
|
|
|
Feb 28 2006, 05:06
|
Участник

Группа: Свой
Сообщений: 72
Регистрация: 4-02-05
Пользователь №: 2 424

|
Не понял, что имеется в виду - запись в AIC_EOICR
//******************************************************************** //прерывание от таймера void timer0(void) __irq { AT91PS_TC TC_pt = AT91C_BASE_TC0; unsigned int dummy; dummy = TC_pt->TC_SR; dummy = dummy;
AT91C_BASE_AIC->AIC_EOICR = AT91C_ID_TC0; }
Вот так сделал и всё заработало, причём строку AT91C_BASE_AIC->AIC_EOICR = AT91C_ID_TC0; надо вставлять во все обработчики прерываний AT91C_BASE_AIC->AIC_EOICR = AT91C_ID_TC1;. На счет правильности гарантировать не могу, но всё заработало..
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|