реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> SAM7S256 Системные прерывания перестают работать через 2-4часа, Помогите.
Димон Безпарольн...
сообщение Apr 1 2015, 07:49
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Основной процесс работает. Проверял так:
Код
        *PIO_SODR = (1<<18);
        *PIO_CODR = (1<<18);


иосцилографом.

Используются прерывания от Real-time Timer и PITS
Код
__irq void SYS_int (void) {            //Прерывание от System Controller. Время выполнения 1мкс на частоте 48МГц
    if (*PIT_SR & 1) {                //Проверка бита PITS(0) из PIT_SR - регистр статуса интервального таймера
        *PIO_SODR = (1<<18);
        *PIO_CODR = (1<<18);


    if (!(*PIO_PDSR&(1<<28))) {KnobCNT++;}//Если кнопка нажата - считаем время нажатия
    else if (KnobCNT) {Knob = KnobCNT; KnobCNT=0; Beep = 1;}//Если отжата и счетчик ненулевой - перезаписываем
        if (Beep) {                    //Прерывание по Periodic Interval Timer (PIT) стр77. P2.0
            Beep--;                    //
            *PWM_ENA = 2;}            //Разрешить работу канала PWM1 (CHID2) P2.0        
        else {*PWM_DIS = 2;}         //Запретить работу канала PWM1 (CHID2)
        *AIC_EOICR = *PIT_PIVR;    }    //Чтение PIT_PIVR сбрасывает бит PITS в PIT_SR
    if (*RTT_SR & 2) {                //Время выполнения 450нс на частоте 48МГц
        Strob = 1;                    //Прерывание по Real-time Timer (RTT) (для подсчёта секунд) стр71.
        *AIC_EOICR = 1;}            //
        }                            //__irq void SYS_int (void)


Инициализация системного прерывания:
Код
[/code]    *AIC_SMR1    =    (1 << 5) | 1;    //Positive edge triggered (5), 1-й уровень пиоритета
    *AIC_SVR1    =    (unsigned long) SYS_int; //Адрес обработчика прерывания
    *AIC_IECR    =    (1 << 1);        //Разрешить системное прерывание SYS(1)

Инициализация RTT:
[code]    *RTT_MR=0x00008000 | (1<<17);    //Секундный интервал и прерывания RTTINCIEN(17) = 1

Инициализация PIT:
Код
  *PIT_MR =    (1 << 25)|                //Разрешить прерывание от PIT
            (1 << 24)|                //Разрешить работу PIT
            0xAFFFF;                //Потолок счета PIT. Максимальное значение 1 048 575(FFFFFh)(20 бит)


Через произвольное время 2-4 часа колом встает системное прерывание - оно не вызывается. Не могу понять куда копать, какие регистры вывести чтобы проверить. Помогите советом, добрые люди.

Сообщение отредактировал Димон Безпарольный - Apr 1 2015, 07:51
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 1 2015, 08:18
Сообщение #2


Гуру
******

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



Видимо происходит какое-то совпадение условий, при котором ваша программа выходит из обработчика прерывания не записав AIC_EOICR. Контроллер прерываний считает, что обработка не закончилась и другие прерывания не генерятся.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Apr 1 2015, 08:20
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(Сергей Борщ @ Apr 1 2015, 11:18) *
Видимо происходит какое-то совпадение условий, при котором ваша программа выходит из прерывания не записав AIC_EOICR. Контроллер прерываний считает, что обработка не закончилась и другие прерывания не генерятся.

Нет таких условий. Код системного прерывания я представил. Это было бы слишком просто. А у меня уже мозги закипают.
Go to the top of the page
 
+Quote Post
scifi
сообщение Apr 1 2015, 08:32
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Внутрисхемным отладчиком подцепиться нет возможности?
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Apr 1 2015, 08:32
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(scifi @ Apr 1 2015, 11:32) *
Внутрисхемным отладчиком подцепиться нет возможности?

К сожалению нет.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 1 2015, 08:36
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата
The status register flags reset is taken into account only 2 slow clock cycles after the read of the RTT_SR (Status Register)

Пример зависания:
1. сработал RTT
2. вошли в прерывание, прочитали RTT_SR
3. после выхода из прерывания линия остается активной еще 2 цикла slow clock
4. в этот момент пришло прерывание PIT
5. фронта нет и больше не будет, линия активна - висим
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Apr 1 2015, 08:54
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(aaarrr @ Apr 1 2015, 11:36) *
3. после выхода из прерывания линия остается активной еще 2 цикла slow clock

А разве прерывание срабатывает не по переднему фронту?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 1 2015, 08:59
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Димон Безпарольный @ Apr 1 2015, 11:54) *
А разве прерывание срабатывает не по переднему фронту?

По переднему, а что это меняет?
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Apr 1 2015, 09:01
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(aaarrr @ Apr 1 2015, 11:59) *
По переднему, а что это меняет?

Понял. Т.е. линия остается активной и не дает другому прерыванию просигнализировать. Попробую отключить RTT. Как бороться с таким недугом пока не знаю. Таймаут 4 часа. Тестирую.

Сообщение отредактировал Димон Безпарольный - Apr 1 2015, 09:02
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 1 2015, 09:04
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



ИМХО, для прерывания с множеством источников не стоит использовать работу по фронту. Для RTT не стоит использовать прерывание вообще.
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Apr 1 2015, 09:05
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(aaarrr @ Apr 1 2015, 12:04) *
ИМХО, для прерывания с множеством источников не стоит использовать работу по фронту. Для RTT не стоит использовать прерывание вообще.

Получается так. Секундный интервал я могу получать и с PIT.
Go to the top of the page
 
+Quote Post
Obam
сообщение Apr 1 2015, 10:11
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



В первом посте меня смущает наличие *AIC_EOICR = 1 в обработчике прерывания от SYSC (PIT и RTT - составные части системного контроллера, как впрочем и AIC).

Если мы посмотрим на "потроха" SYSC, то мы увидим:

Прикрепленное изображение


прерывания от составных частей являются "вложенными" для прерывания от AIC.
Мне "к-а-а-атца", что *AIC_EOICR = 1 должно быть в обработчике прерывания от AIC и в единственном эеземпляре


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Apr 1 2015, 11:15
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Чего то я совсем запутался. Я думал что для запрещения прерываний от RTT достаточно не программировать это:

Код
*RTT_MR=0x00008000 | (1<<17);


Но прерывания от RTT все равно идут! Я не могу убрать ветку:

Код
    if (*RTT_SR & 2) {                //Время выполнения 450нс на частоте 48МГц
        *AIC_EOICR = 1;}            //


поскольку тогда прерывания вообще не работают. Прерывания от RTT все равно вызываются! Проверено. Как отключить прерывания от RTT?

Сообщение отредактировал Димон Безпарольный - Apr 1 2015, 11:39
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 1 2015, 11:29
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Димон Безпарольный @ Apr 1 2015, 14:15) *
В настоящее время прерывание единственное. И запись в *AIC_EOICR уже единственная. Но!

Вынесите запись из блока if(){}. Правильно заметили, что она должна быть единственная и выполняться без всяких условий: попали в прерывание - на выходе всегда запись EOICR.

AIC, случайно, не в protect mode? Как вообще оформлен вектор на "нижнем уровне"?
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Apr 1 2015, 11:43
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(aaarrr @ Apr 1 2015, 14:29) *
Вынесите запись из блока if(){}. Правильно заметили, что она должна быть единственная и выполняться без всяких условий: попали в прерывание - на выходе всегда запись EOICR.

AIC, случайно, не в protect mode? Как вообще оформлен вектор на "нижнем уровне"?

Как проверить protect mode прерывания?

Я бы вынес запись EOICR, но как быть с PIT_PIVR? Читать его в какую - нибудь переменную?

Код
*AIC_EOICR = *PIT_PIVR;


Чтение PIT_PIVR сбрасывает бит PITS в PIT_SR. К тому же я так и не смог отключить RTT и всех запутал. Пост 13.

Сообщение отредактировал Димон Безпарольный - Apr 1 2015, 11:43
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 06:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01501 секунд с 7
ELECTRONIX ©2004-2016