|
вопрос по работе с тремя прерываниями одинакового приоритета,, которые могут возникнуть одновременно. at91sam7s |
|
|
|
Nov 23 2009, 12:49
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
по прерыванию от порта PIO считываются последовательные данные, то есть при каждом прерывании считывается один бит: Код __ramfunc void irq_Receive() { PauseTimerBase->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase->TC_CCR = AT91C_TC_SWTRG; source = regs->PIOA_PDSR&0x600; if(source==0x200) {recA = recA>>1; i_shA++; recA = recA|0x80000000;} //A1 if(source==0x400) {recA = recA>>1; i_shA++; recA = recA&0x7FFFFFFF;} //B1 dummy = AT91C_BASE_PIOA->PIO_ISR; } при этом перезапускается таймер, который остчитывает паузу между принимаемыми словами. как только пришла пауза, таймер срабатывает и по прерыванию: Код __ramfunc void pause_timer_irq() { if(i_shA==32) { recDA[kA] = recA; kA++; } if(kA==12) send_to_host(); i_shA=0; dummy = PauseTimerBase->TC_SR; } записывает данные в некий буфер. но помимо этого одновременно может идти передача данных по прерываниюот другого таймера, работающего в режиме генератора: Код __ramfunc void timer0_irq_handler() { ii--; //счетчик переданных бит if(ii==1) {MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;} MipsTimerBase->TC_RA = 30; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = 60; if(datA&0x80000000) regA = 0x20000; else regA = 0x0; regs->PIOA_ODSR = regA|front; datA = datA<<1; dummy = MipsTimerBase->TC_SR; } Передача и прием идут с частотой 100 кГц. Приоритеты всех прерываний 7, то есть по идее они должны выполняться по очереди. Но при этом обработчик таймера паузы должен успеть все сделать до прихода следующего слова. Передача и прием по отдельности работают нормально, без сбоев. Но при их одновременной работе прием не нарушается, а передача происходит с ошибками и в дальнейшем вовсе останавливается. Поэтому я и решил оптимизировать обработчики прерываний. Для начала я решил все обработчики поместить в RAM, но тут столкнулся с интересной особенностью, если обработчик приемника void irq_Receive() не помещать в ОЗУ, то прием идет очень медленно, не успевает. Но, если обработчик передатчика void timer0_irq_handler() поместить в ОЗУ, то при одновременной работе приемника и передатчика (замыкание выхода передатчика на вход приемника) данные вообще не передаются, а если не помещать в ОЗУ то немного данных передаются. Как правильно размещать обработчики прерываний в ОЗУ и значительно ли это ускоряет работу?
|
|
|
|
|
 |
Ответов
|
Nov 24 2009, 08:10
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(GetSmart @ Nov 24 2009, 12:15)  Ну понятно. Значит ни входа/выхода в прерывание не организовано (__arm __irq), ни сброса VIC/AIC на выходе из прерывания. Удивительно, что что-то вообще работает. так выход же у меня происходит путем считывания статусного регистра dummy = AT91C_BASE_PIOA->PIO_ISR или еще нужно в конце обработчика делать запись AT91C_BASE_AIC->AIC_EOICR = 1 ? по поводу (__arm __irq), я так делал, но у меня возникала ошибка: Error[Pe167]: argument of type "void (__arm __irq __atpcs *)()" is incompatible with parameter of type "void и компилятор ссылался на функцию конфигурации прерывания: AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, MipsTimer.Id, TIMER_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE, timer0_irq_handler);
|
|
|
|
|
Nov 24 2009, 09:39
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Bulat @ Nov 24 2009, 14:10)  или еще нужно в конце обработчика делать запись AT91C_BASE_AIC->AIC_EOICR = 1 ? Именно это должно быть в конце каждого обработчика. Цитата(Bulat @ Nov 24 2009, 14:10)  по поводу (__arm __irq), я так делал, но у меня возникала ошибка: Error[Pe167]: Не знаю что там за проблема, но без __arm __irq (когда нет одного общего на всех хэндлера) нормально прога работать не будет.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 24 2009, 11:20
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(GetSmart @ Nov 24 2009, 14:39)  Именно это должно быть в конце каждого обработчика.
Не знаю что там за проблема, но без __arm __irq (когда нет одного общего на всех хэндлера) нормально прога работать не будет. дело в том, что все это уже прописано в моем стартапе: -вход в прерывание B IRQ_Handler_Entry ; 0x18 IRQ - и конец прерывания str r14, [r14, #AIC_EOICR] Прикрепляю Cstartup. Цитата(aaarrr @ Nov 24 2009, 14:43)  Тип преобразуйте: Код AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, MipsTimer.Id, TIMER_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (void*)timer0_irq_handler); Вообще замечательный подход - вместо того, чтобы разобраться в проблеме, боремся с сообщениями об ошибках  AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE - почему EXT, на кой хрен, простите, EDGE???? Да, извините, тут я упустил. Сейчас во всех 3-х прерываниях поставил AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL. Только проблема не решилась. А почему у этого контроллера прерывания от порта срабатывают 2 раза - по фронту и по спаду? Для чего тогда ставить AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL или AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE? Может из-за этого контроллер не успевает обработать все прерывания друг за другом. У всех жи одинаковый приоритет.
|
|
|
|
|
Nov 24 2009, 12:01
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Bulat @ Nov 24 2009, 14:20)  А почему у этого контроллера прерывания от порта срабатывают 2 раза - по фронту и по спаду? Потому что так устроен контроллер PIO - генерирует прерывание по любому фронту. Цитата(Bulat @ Nov 24 2009, 14:20)  Для чего тогда ставить AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL или AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE? А для чего вообще работать с внутренними источниками прерываний по фронту?
|
|
|
|
|
Nov 24 2009, 12:18
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Nov 24 2009, 17:01)  Потому что так устроен контроллер PIO - генерирует прерывание по любому фронту.
А для чего вообще работать с внутренними источниками прерываний по фронту? Значит я правильно пользуюсь прерываниями с моим стартапом? Конфликтов между прерываниями никаких не может возникнуть в случае одновременного вызова, учитывая, что приоритеты однинаковы?
|
|
|
|
|
Nov 24 2009, 12:44
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Nov 24 2009, 17:30)  Правильно - понятие относительное  Да, пользуетесь правильно: для прерываний не нужны модификаторы __irq и запись EOICR, конфликтов не будет. Но само по себе использование такого кащенитского стартапа является большой ошибкой. то есть из-за этого стартапа могут проблемы возникнуть? а могут проблемы быть из-за того, что прерывания от порта 2 раза возникают при приходе одного бита? это же дополнительное аремя на вызов и обработку прерывания.
|
|
|
|
|
Nov 24 2009, 13:02
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Bulat @ Nov 24 2009, 15:44)  то есть из-за этого стартапа могут проблемы возникнуть? Главная его проблема в том, что он тупо сохраняет контекст и переключает режим для всех подряд прерываний, в том числе и для прерываний с максимальным приоритетом. В подавляющем большинстве случаев работать будет, просто подобное построение выдает совершенную бездумность подхода. Цитата(Bulat @ Nov 24 2009, 15:44)  а могут проблемы быть из-за того, что прерывания от порта 2 раза возникают при приходе одного бита? это же дополнительное аремя на вызов и обработку прерывания. Вы с оптимизацией разобрались? Пока компилятор генерирует код вроде того, что вчера публиковался, о прерываниях с частотой 100кГц лучше забыть.
|
|
|
|
Сообщений в этой теме
Bulat вопрос по работе с тремя прерываниями одинакового приоритета, Nov 23 2009, 12:49 GetSmart А где код, который вызывает все эти обработчики? У... Nov 23 2009, 15:23 Bulat Цитата(GetSmart @ Nov 23 2009, 20:23) А г... Nov 24 2009, 04:44         Bulat Цитата(aaarrr @ Nov 24 2009, 18:02) Главн... Nov 24 2009, 13:11          aaarrr Цитата(Bulat @ Nov 24 2009, 16:11) Но вед... Nov 24 2009, 13:27           Bulat Цитата(aaarrr @ Nov 24 2009, 18:27) И зач... Nov 24 2009, 14:00            aaarrr Цитата(Bulat @ Nov 24 2009, 17:00) -Когда... Nov 24 2009, 15:02             Bulat Цитата(aaarrr @ Nov 24 2009, 20:02) Вот с... Nov 25 2009, 12:02              aaarrr Цитата(Bulat @ Nov 25 2009, 15:02) Таймер... Nov 25 2009, 12:12               Bulat Цитата(aaarrr @ Nov 25 2009, 17:12) И что... Nov 25 2009, 12:45                aaarrr Цитата(Bulat @ Nov 25 2009, 15:45) потому... Nov 25 2009, 14:08 aaarrr Тип преобразуйте:
КодAT91F_AIC_ConfigureIt ( A... Nov 24 2009, 09:43
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|