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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> AVR Studio эмуляция прерываний, После отработки подпрограммы перескакивает в конец цикла
RAmsi
сообщение Apr 25 2009, 15:35
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-04-09
Пользователь №: 47 200



В теле блока main алгоритм внутри цикла while (1) {...};
За время счета алгоритма несколько раз срабатывает прерывание по таймеру.
При эмуляции после первого прерывания курсор не возвращается на прежнее место в алгоритме, а перескакивает на последнюю строчку в цикле while (1). Повторного прогона цикла не происходит, а далее работают только прерывания.
Как заставить программу продолжаться с того места, где произошло прерывание и заставить её крутиться в цикле while (1) ?
Перешел на AVR Studio и WinAVR и подобного рода проблемы на уже отлаженных алгоритмах вылезают на ровном месте одна за другой crying.gif

Сообщение отредактировал RAmsi - Apr 25 2009, 15:37
Go to the top of the page
 
+Quote Post
smac
сообщение Apr 25 2009, 17:27
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003



Цитата(RAmsi @ Apr 25 2009, 19:35) *
В теле блока main алгоритм внутри цикла while (1) {...};
....
Перешел на AVR Studio и WinAVR и подобного рода проблемы на уже отлаженных алгоритмах вылезают на ровном месте одна за другой crying.gif

Наверное со стеком проблемы, Вы модель контроллера в опциях симулятора и в опциях проекта (make файла) правильно установили? Телепаты, как обычно, в отпуске, поэтому неплохо бы на код глянуть и на настройки проекта тоже.

Сообщение отредактировал smac - Apr 25 2009, 17:27
Go to the top of the page
 
+Quote Post
RAmsi
сообщение Apr 26 2009, 16:47
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-04-09
Пользователь №: 47 200



Прогнал эмуляцию до упора.
Проблема оказалась не в прерываниях.
Вопрос к тем, кто использовал CVAVR и WinAVR.

Кратко алгоритм следующий.
Таймер 0 настроен так, что делает 32 прерывания за 1/500 секунды. По прерыванию таймера происходит оцифровка входящего сигнала. За время следующего промежутка времени в 1\500 секунды вычисляется среднее значение за предыдущие 32 оцифровки, потом оно прогоняется через 7 каскадов цифровых фильтров и выводится через UART на компьютер. Параллельно происходят новые 32 оцифровки для расчета следующего значения.

При эмуляции с CVAVR весь цикл (прогонка через фильтры, передача по UART, параллельные 32 оцифровки в прерываниях) укладывался в тютельку в 1/500 секунды. Это 2 мс. Прекрасно этот алгоритм работал в железе.
При эмуляции в WinAVR на один цикл уходит примерно 30,5 мс. За это время таймер успевает сделать чуть более 120 прерываний. В настройках вроде везде выставил нужную частоту - 18,432 МГц.

Очень хочется верить, что я где-то ошибся в настройках. И не хочется верить, что после компиляции в WinAVR алгоритм так тормозит. Кто-нибудь может поделиться опытом сравнения скорости вычисления в разных компиляторах?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 28 2009, 08:01
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Видите ли. Отмечу несколько моментов.

1) Как ни старайся - результирующий код после разных компиляторов будет разный. Соответственно и скорость выполнения.
Это зависит от выставленного уровня оптимизации, к примеру. Также от качества компилятора.
По отзывам, WinGCC, как минимум не хуже чем CVAVR.
В то же время, если хорошо знать особенности компилятора, то можно так "подправить" прогу на Си, что результирующий код будет намного лучше. При этом, как правило, код скомпилированный другим компилятором будет хуже.

Таким образом, не зная предысторию проекта, а также не видя его, не зная настроек, трудно оценить возможности по оптимизации.

2) сходя из вашего описания могу смело утверждать что у вас ошибка в самом алгоритме. Необходим приличный запас по производительности процессора, либо проект должен быть переработан таким образом, чтобы "не успевание" обработки не приводило к краху системы. Хотя так как вы делаете - вполне возможный и реальный подход. Сам иногда так поступаю. Только запас должен быть.

На вскидку можно предложить следующее.
Прерывание измеряет само по себе. Усреднение и фильтрация - сама по себе. Вывод сам по себе. То есть цикл измерения будет больше чем цикл вывода.
Go to the top of the page
 
+Quote Post
RAmsi
сообщение Apr 28 2009, 12:12
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-04-09
Пользователь №: 47 200



Уровень оптимизации выставлял разный. Разницы почти никакой. В предыдущем сообщении я допустил ошибку - не 30,5 мс, а 7,16 мс в WinAVR против 2 мс в CVAVR.

Ошибки в коде маловероятны т.к. оба проекта как две капли воды.

Общее время 32-х оцифровок - 312-313 мкс.
Основное время счета приходится на блоки фильтров:

xlp1[0]=xlp1[1]; xlp1[1]=xlp1[2]; xlp1[2]=xlp1[3]; xlp1[3]=xlp1[4];
xlp1[4]=input_data/21.46710182;
ylp1[0]=ylp1[1]; ylp1[1]=ylp1[2]; ylp1[2]=ylp1[3]; ylp1[3]=ylp1[4];
ylp1[4]=(xlp1[0]+xlp1[4]+4*(xlp1[1]+xlp1[3])+6*xlp1[2])-
(0.0301188750*ylp1[0])+(0.1826756978*ylp1[1])-
(0.6799785269*ylp1[2])+(0.7820951980*ylp1[3]);

Таких 5 штук и еще 2 поменьше.
Пробовал перевести счет на int (представлять дробные в виде результата деления двух больших целых) - точность сильно падает. Отказался.
Склоняюсь к переходу на CVAVR.

Если будет время и желание посмотреть оба проекта - дайте Ваш адрес.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 28 2009, 12:48
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Я работаю вообще в IARе.
Речь не идёт об ошибках. Просто надо смотреть результирующий листинг. Разбираться в чём дело.
Может быть приведение разное и размерность. Трудно сказать. Уж больно велика разница.

Так а почему не изменить алгоритм?
Go to the top of the page
 
+Quote Post
GDI
сообщение Apr 28 2009, 12:51
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Выполните код пошагово и посмотрите где у вас набегают лишние миллисекунды. Подозреваю что на вычислении фильтров и происходит это.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
Верталь
сообщение Apr 28 2009, 15:20
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 25
Регистрация: 17-05-08
Из: г.Монте Карло
Пользователь №: 37 579



RAmsi Как понять Ваше высказывание:

Ошибки в коде маловероятны т.к. оба проекта как две капли воды.

а листинги программ - тоже как две капли воды?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 28 2009, 17:16
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



А массивы xlp,ylp объявлены как int или как float?

Можно было бы высчитать результаты по каждому компилятору. smile.gif Ради любопытства.
Go to the top of the page
 
+Quote Post
aesok
сообщение Apr 29 2009, 07:32
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(RAmsi @ Apr 25 2009, 19:35) *
В теле блока main алгоритм внутри цикла while (1) {...};
За время счета алгоритма несколько раз срабатывает прерывание по таймеру.
При эмуляции после первого прерывания курсор не возвращается на прежнее место в алгоритме, а перескакивает на последнюю строчку в цикле while (1). Повторного прогона цикла не происходит, а далее работают только прерывания.
Как заставить программу продолжаться с того места, где произошло прерывание и заставить её крутиться в цикле while (1) ?
Перешел на AVR Studio и WinAVR и подобного рода проблемы на уже отлаженных алгоритмах вылезают на ровном месте одна за другой crying.gif


Симптомы указывают на неприменение 'volatile'.

Анатолий.
Go to the top of the page
 
+Quote Post
RAmsi
сообщение Apr 30 2009, 11:37
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-04-09
Пользователь №: 47 200



Листинги программ естественно разные с учетом стандартов каждого компилятора. Проекты одинаковые в смысле алгоритма. Второй строился на базе первого.

Отключил все прерывания. В CVAVR в начале и в конце каждого блока добавил по инвертированию одной ноги свободного порта чтобы в VMLAB измерить интервал на осциллографе. Для чистоты эксперимента такое же инвертирование добавил и в WinAVR.

Куски кода:

CVAVR, VMLAB:
PORTC.3^=1;
xlp1[0]=xlp1[1]; xlp1[1]=xlp1[2]; xlp1[2]=xlp1[3]; xlp1[3]=xlp1[4];
xlp1[4]=input_data/21.46710182;
ylp1[0]=ylp1[1]; ylp1[1]=ylp1[2]; ylp1[2]=ylp1[3]; ylp1[3]=ylp1[4];
ylp1[4]=(xlp1[0]+xlp1[4]+4*(xlp1[1]+xlp1[3])+6*xlp1[2])-
(0.0301188750*ylp1[0])+(0.1826756978*ylp1[1])-
(0.6799785269*ylp1[2])+(0.7820951980*ylp1[3]);
PORTC.3^=1;

WinAVR, AVR Studio:
PORTC |= 1<<3;
xlp1[0]=xlp1[1]; xlp1[1]=xlp1[2]; xlp1[2]=xlp1[3]; xlp1[3]=xlp1[4];
xlp1[4]=input_data/21.46710182;
ylp1[0]=ylp1[1]; ylp1[1]=ylp1[2]; ylp1[2]=ylp1[3]; ylp1[3]=ylp1[4];
ylp1[4]=(xlp1[0]+xlp1[4]+4*(xlp1[1]+xlp1[3])+6*xlp1[2])-
(0.0301188750*ylp1[0])+(0.1826756978*ylp1[1])-
(0.6799785269*ylp1[2])+(0.7820951980*ylp1[3]);
PORTC |= 0<<3;

На выполнение первого по эмулятору ушло 145 мкс.
На выполнение второго в зависимости от оптимизации 946-949 мкс.
Львиная доля времени ушла на вычисление последней строчки фильтра.
В одном и другом проекте массив определен как double.
Go to the top of the page
 
+Quote Post
RAmsi
сообщение Apr 30 2009, 13:36
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-04-09
Пользователь №: 47 200



Прошу прощения. Массивы не double, а float.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Apr 30 2009, 13:48
Сообщение #13


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(RAmsi @ Apr 30 2009, 14:37) *
Куски кода:
WinAVR, AVR Studio:
PORTC |= 1<<3;
*************
PORTC |= 0<<3;
На выполнение второго в зависимости от оптимизации 946-949 мкс.


Я вот из Ваших сообщений немного бреда выжал. Почитайте и посмейтесь над собой.
По делу: выложите листинг WinAVRовского кода. Без него ничего не понять. Оптимизацию оставьте -Os, с ней уж точно играться смысла нету.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Apr 30 2009, 13:56
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(RAmsi @ Apr 30 2009, 14:37) *
xlp1[0]=xlp1[1]; xlp1[1]=xlp1[2]; xlp1[2]=xlp1[3]; xlp1[3]=xlp1[4];
xlp1[4]=input_data/21.46710182;
ylp1[0]=ylp1[1]; ylp1[1]=ylp1[2]; ylp1[2]=ylp1[3]; ylp1[3]=ylp1[4];
ylp1[4]=(xlp1[0]+xlp1[4]+4*(xlp1[1]+xlp1[3])+6*xlp1[2])-
(0.0301188750*ylp1[0])+(0.1826756978*ylp1[1])-
(0.6799785269*ylp1[2])+(0.7820951980*ylp1[3]);

Ужос! Сплошные магические числа cranky.gif
Пожалейте АВР. Если эти все коэффициенты так важны, то выберите другой контроллер.
Только я в этом очень сомневаюсь. Можно с небольшой потерей точности перевести все на целочисленную арифметику и ускорить на порядок.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
RAmsi
сообщение Apr 30 2009, 14:59
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 5-04-09
Пользователь №: 47 200



Смеяться пока могу над тем, что я еще не такой опытный чтобы понимать над чем смеяться. Поэтому и пришел на этот форум. laughing.gif

AVR с CVAVR перемалывает пять таких блоков меньше чем за 2 мс и еще кучу оцифровок при этом делает и успевает еще данные через UART отправлять. И не только в эмуляторе но и в железе.
В будущем процессор может и поменяю. Разрядность АЦП и ШИМ не устраивает.

Целочисленную арифметику в WinAVR не пробовал. В CV точность коэффициентов с целочисленной арифметикой обеспечивал до 5-го или 6-го знака. Точно не припомню сколько был выигрыш по времени, но не больше 30%. А качество графиков на мониторе было отвратительным (шумы + смещение средней линии). Может и можно будет 2 или 3 знака убрать, но на данный момент это глобально ничего не решит.

Если у кого-то возникнет желание помочь - жду адрес.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 28th June 2025 - 20:06
Рейтинг@Mail.ru


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