Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Приоритет прерываний
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
=GM=
Цитата(Rst7 @ Sep 1 2008, 04:49) *
А старший байт pos (если надо) - лучше править не в процедуре прерывания, а отдельно

Похоже мосье знает толк в сишных извращениях(:-). И как вы себе представляете правку старшего байта вне прерывания?

Кажется вы не учли команду sei. Ваш код какой-то левый. Не могу понять почему компайлер у вас не сохраняет SREG? А это ведь тактов не убавляет. Или я что-то пропустил? Нельзя ли посмотреть на код с 16-битными t и pos?
Rst7
Цитата
И как вы себе представляете правку старшего байта вне прерывания?


Вполне просто. Изредка запускаем проверку, не изменился ли старший бит pos и если изменился - меняем старший байт. Заодно там, где необходимо значение pos тоже выполняем такую проверку.

Цитата
Из вашего кода у меня получилось 28 тактов, да ещё без sei.


Код для INT0 не предусматривал SEI. Тактов, кстати, 27, если RJMP c вектора.

Цитата
Не могу понять почему компайлер у вас не сохраняет SREG?


А порт 0x3F - это что по Вашему?

Цитата
Нельзя ли посмотреть на код с 16-битными t и pos?


А смысл?

Цитата
Ваш код какой-то левый.


Выбирайте выражения.

...Чуть позже...

С банальной проверкой старшего бита я погорячился малость, там надо проверять изменение 2х старших бит из 00 в 11 и наоборот. Это и будет обозначать инкремент или декремент старшего байта. Но не суть, такую проверку можно выполнить один раз на, скажем, 50 прерываний INT0.

Цитата
А в WinAVR можно результат работы компилятора как в посте Rst7


Как-то там через зопу. Смотрите elfdump или objdump. Запускаете его с ключиком (не помню каким, в хелпе глянете) и он дампит выходной эльф-файл с включением строк исходника.

Цитата
да и где взять время выполнения команд?


В даташите на контроллер. В табличке с набором команд.

Цитата
Вообщем как можно быстро расчитать время обработки прерывания?


Я руками считаю. Навык, выработанный годами smile.gif
=GM=
Цитата(Rst7 @ Sep 1 2008, 08:35) *
Вполне просто. Изредка запускаем проверку, не изменился ли старший бит pos и если изменился - меняем старший байт. Заодно там, где необходимо значение pos тоже выполняем такую проверку

То есть был 127, стал 128 - меняем старший байт? А как тогда быть с полным 16-битным pos? В 7 бите pos будет знак? Да и что значит изредка? А вдруг пропустим, а пропуск означает катастрофу.
Цитата(Rst7 @ Sep 1 2008, 08:35) *
А порт 0x3F - это что по Вашему?

Прошу пардону, слона-то я и не приметил.
PhX
Цитата(Rst7 @ Sep 1 2008, 14:49) *
А смысл?

С точки зрения технических требований задачи переменная pos должна быть 32 битной.
Rst7
Цитата
То есть был 127, стал 128 - меняем старший байт?


Я исправился smile.gif дописал еще, причем другим постом, дабы пришло уведомление.

Цитата
Да и что значит изредка?


Изредка - это значит при максимальной частоте входного сигнала не реже чем 64 прерывания (вот я и взял с потолка число 50). Вполне можно запустить флаг задачи от таймерного прерывания.

Цитата
С точки зрения технических требований задачи переменная pos должна быть 32 битной.


Ну изменяйте 3 дополнительных байта, не суть. Не надо их в каждом прерывании носить туда-сюда, вот я о чем.
defunct
Цитата(PhX @ Sep 1 2008, 11:07) *
Реально прерывания от таймера "шлепают" с частотой 12 кГц, а от INT0 с частотой около 30 кГц, причем это тоже, вероятно с запасом. smile.gif

Ft / Fi = 2/5

Если пропорция между частотой таймера и INT0 сохранится при INT0 = 250kHz. То 83 такта достаточно. Система не потеряет ни одного прерывания.

используя цифры приведенные уважаемыми форумчанами выше
обработка INT0 - 27 тактов, INT0 + таймера = 83 такта, мин. период Fosc / Fint0 = 16Mhz/0.25Mhz = 64 такта. Получаем:

64 * 5 = 320 всего тактов на 7 событий.

обработка этих событий:

83 * 2 + 27 * 3 = 166 + 81 = 247.

247 / 320 = 77% загрузка процессора.
ReAl
Цитата(PhX @ Sep 1 2008, 11:07) *
p.s. А в WinAVR можно результат работы компилятора как в посте Rst7, да и где взять время выполнения команд? Вообщем как можно быстро расчитать время обработки прерывания?

Код
avr-gcc ключи_как_при_компиляции -S foo.c

Получите файл foo.S, который можно при большом желании подредактировать отдать avr-as на обработку (что и делает gcc без ключа -S).
Либо в ключи компиляции добавить
Код
-Wa,-ahlmsd=$(<:.c=.lst)

это если оно пойдёт в правило в makefile, а если вручную, то тогда
Код
-Wa,-ahlmsd=foo.lst

для файла foo.
Это будет именно листинг, а не ассемблерный исходник.

Предупреждаю сразу, мелкий обработчик прерывания после avr-gcc выглядит несколько грустнее, чем после IAR - avr-gcc делает лишнее для мелкого обработчика сохранение/восстановление __temp_reg__ и сохранение/очистку/восстановление __zero_reg__ (в мелких обработчиках они, как правило, невостребованы, так как являются "нижними" регистрами и с ними не всё можно сделать). Этот десяток циклов avr-gcc-шный обработчик и проиграет IAR-овскому.

Я бы рекомендовал очень критичные обработчики писать на асме в отдельном асм-файле.


Да, Rst7 праивльно напомнил ещё и про avr-objdump
Это даст листинг полностью собранной программы вместе со стартапом и библиотеками да вдобавок с реальными адресами.
Код
avr-objdump -d -S project.elf >project.dump

Как правило достаточно посмореть выдачу компилятора по -S либо листинг одного файла, как указано выше, но иногда бывает нужно потрошить содержимое после линковки.
Rst7
Цитата
avr-gcc делает лишнее


Кстати, не пора ли любителям гнуся озаботиться патчем для него, дабы он смотрел, востребованы ли в обработчике эти регистры?
=GM=
Цитата(defunct @ Sep 1 2008, 09:43) *
Если пропорция между частотой таймера и INT0 сохранится при INT0 = 250kHz. То 83 такта достаточно. Система не потеряет ни одного прерывания

Вывод такой, если прерывания int0 возникают каждые 64 такта, то само прерывание int0 не должно выполняться более, чем за 64-9=55 тактов. 9 тактов нужны, чтобы войти в прерывание от таймера и разрешить остальные прерывания. При подсчёте тактов не учитывался джиттер от завершения команды перед входом в прерывание.

Автору следует посчитать время выполнения int0, особенно в свете новых сведений, что переменная pos должна быть 32-битной.
Rst7
Цитата
77% загрузка процессора.


Необходимо учесть еще периодический вызов проверки переполнения счетчика энкодера и коррекции старшей части. Но это, в принципе, будет пыль. Кстати, где вы там нашли 83 такта на все? 27+36, а если сделать через таймерное прерывание через OCR, то еще меньше.

Цитата
Автору следует посчитать время выполнения int0, особенно в свете новых сведений, что переменная pos должна быть 32-битной.


Не надо трогать все 32 бита wink.gif
ReAl
Цитата(Rst7 @ Sep 1 2008, 14:02) *
Кстати, не пора ли любителям гнуся озаботиться патчем для него, дабы он смотрел, востребованы ли в обработчике эти регистры?
Да давно пора, но некому :-(
Я вон обещал потестить один патч и то утонул на несколько недель, даже на форумы почти не заглядывал. Что-то тормозить голова начинает :-( Куда уж в потрохах разбираться.
А тот небольшой коллектив, который что-то реальное делает - просто не успевает всё.
=GM=
Цитата(Rst7 @ Sep 1 2008, 10:07) *
Кстати, где вы там нашли 83 такта на все?

Кодвижн такие времена даёт для интиджер.
Rst7
Цитата
Кодвижн такие времена даёт для интиджер.


Дык пользуйте вменяемые компиляторы smile.gif

И не лобовые алгоритмы wink.gif
defunct
Цитата(PhX @ Sep 1 2008, 11:07) *
p.s. А в WinAVR можно результат работы компилятора как в посте Rst7, да и где взять время выполнения команд? Вообщем как можно быстро расчитать время обработки прерывания?

Проэмулировать прерывание в AVR-Studio.

Запускаем отладку, открываем окно дизассемблера. Запускаем выполнение программы.

Жмем паузу. убеждаемся что стоим не на команде ®JMP/®CALL/RET. Ставим точку останова на сл. команду. Выставляем условия для возбуждения проверяемого обработчика. Запоминаем показания счетчика циклов в отладчике как C0. жмем "run". считываем показания счетчика циклов как C1. Время выполнения обработчика соответвенно (C1 - C0) + 4 такта макс длинная команда во время выполнения которой произошло прерывание.

еще вариант:
Открываем дизассемблер в отладчике, ставим break point на вектор интересующего прерывания. Запускаем отладку. Запоминаем C0 когда отладчик остановится, по шагам проходим обработчик прерывания пока из него не выйдем, тогда запоминаем C1. Время работы обработчика будет C1 - C0 + Tcall + 3такта => C1 - C0 + 8


PS: Cycle Counter находится в view->toolbars->processor.

Цитата(Rst7 @ Sep 1 2008, 14:07) *
Кстати, где вы там нашли 83 такта на все? 27+36, а если сделать через таймерное прерывание через OCR, то еще меньше.

Это не я нашел, это =GM= нашел в #46, его спросите wink.gif
Если меньше тогда вообще никаких вопросов.
=GM=
Цитата(Rst7 @ Sep 1 2008, 10:24) *
Дык пользуйте вменяемые компиляторы smile.gif

А я на асме, по старинке (:-). Хочется тратить время на задачу, а не на борьбу с компилятором, пусть и вменяемым. К примеру, у вас прерывание выполняется за 27 тактов для 8-битных переменных, а у меня на асме - за 17 для 16-битных, прямо в лоб, даже без оптимизации. Потому и спрашивал код для 16-битных. А уж что будет для 32-битных, даже не могу представить.
Rst7
Цитата
К примеру, у вас прерывание выполняется за 27 тактов для 8-битных переменных, а у меня на асме - за 17 для 16-битных, прямо в лоб, даже без оптимизации.


Ага, знаем. Значения уже в регистрах, читать их из ОЗУ не надо, SREG сохраняем прямо в отведенный только для этих целей регистр. Я так тоже могу. Только неспортивно. Добавьте все сохранение/восстановление - и резултат будет тем-же.
PhX
Цитата(Rst7 @ Sep 1 2008, 16:24) *
Дык пользуйте вменяемые компиляторы smile.gif

Если не жалко пульните в PM ссылку где можно скачать свежий пролеченный IAR, а то на ftp какой-то старенький лежит.

Цитата
А я на асме, по старинке (:-).

Асм это хорошо, но голова одна, а разновидностей процессоров все больше и больше...
defunct
Цитата(PhX @ Sep 1 2008, 14:50) *
где можно скачать свежий пролеченный IAR

eval
лечение делается отдельно и для всех одинаково (см. соотв. ветки в форуме по IAR).
=GM=
Цитата(Rst7 @ Sep 1 2008, 10:45) *
Значения уже в регистрах, читать их из ОЗУ не надо, SREG сохраняем прямо в отведенный только для этих целей регистр. Я так тоже могу. Только неспортивно. Добавьте все сохранение/восстановление - и результат будет тем-же

При чём здесь вы? Это должен делать компилятор, причём во всех мыслимых и немыслимых ситуациях, тогда так и быть, буду его использовать.

Спортивно, неспортивно...чтобы прочувствовать разницу между 17 тактами и 27, представьте вашу зарплату 17000 или 27000 гривен...
Rst7
Цитата
Это должен делать компилятор, причём во всех мыслимых и немыслимых ситуациях, тогда так и быть, буду его использовать.


Хорошее желание. Вот только качество кода, когда будет отнято минимум 2 верхних регистра у остальной программы оставит желать лучшего...

Цитата
чтобы прочувствовать разницу между 17 тактами и 27, представьте вашу зарплату 17000 или 27000 гривен...


Именно. За 27 тактов я заработаю 27000 гривен. Потому как кроме этого прерывания есть еще остальная программа, наверняка намного объемнее. И ее я буду очень долго ваять на асме. Было бы всего 30 строк - нет проблем... Обычная проблема time-to-market.

Давайте не будем спорить C vs Asm...
=GM=
Цитата(PhX @ Sep 1 2008, 10:50) *
Асм это хорошо, но голова одна, а разновидностей процессоров все больше и больше...

То-то все сишники то и дело рассматривают ассемблерный код (:-). А чего на него смотреть, если вы пишете на си?

Или вот, попробуйте перенести ваш сишный код двух прерываний на пик18. Думаете не надо будет ничего делать? Как бы не так.

Или вы думаете, заменив одни трудности другими, будет легче? Вот на вскидку два сообщения о глюках в компиляторе иар http://electronix.ru/forum/index.php?showtopic=40698, http://electronix.ru/forum/index.php?showtopic=40231.

Ещё раз повторю, хочется тратить время на задачу, а не на борьбу с компилятором.
Сергей Борщ
Цитата(=GM= @ Sep 1 2008, 15:56) *
Ещё раз повторю, хочется тратить время на задачу, а не на борьбу с компилятором.
Тратьте, кто ж вам не дает? Только не нужно агитировать за свою веру.
defunct
Цитата(=GM= @ Sep 1 2008, 15:56) *
То-то все сишники то и дело рассматривают ассемблерный код (:-). А чего на него смотреть, если вы пишете на си?

Вообще-то это очень редкое занятие. Я например в своих проектах практически никогда не рассматриваю асм код, про причине "нахренненужности" © zltigo. На глаз видно потянет или не потянет тот или иной проц, ту или иную задачу.
Цитата
Или вот, попробуйте перенести ваш сишный код двух прерываний на пик18. Думаете не надо будет ничего делать? Как бы не так.

Конечно настройку периферии нужно будет переделать.
А в остальном (при организации программы, как приводил выше в #24 ничего менять не придется).
Цитата
Или вы думаете, заменив одни трудности другими, будет легче?

Определенно.
sKWO
Цитата(PhX @ Sep 1 2008, 14:50) *
Если не жалко пульните ссылку где можно скачать свежий IAR

пулька на полную рабочую с к-р-я-к-о-м внутри
=GM=
Цитата(defunct @ Sep 1 2008, 12:12) *
Определенно

Ну, прекрасно, раз трудностей нет. Предлагаю в качестве эксперимента написать для авр на си программную выдачу 37-бит данных, сопровождаемых стробом:
1) смена бита на линии D
2) выждатьТо
3) строб=1 на линии C
4) выждать 2*То
5) строб=0 на линии C
6) выждатьТо
7) повторить пп1-6 N=37 раз
Простая задача, раз плюнуть.
А потом перенести сишный код на другую платформу - ЦСП TMS320F2808, To=50нс.
Вот мой код для референса
Код
sndbit:
   mov    *xar5,ah
   mov    @th,ah
   nop    
   nop    
   or     @th,#0x0002
   mov    *xar5,t
   lsr    ah,#1
   lsl64  acc:p,#1
   rpt    #6-2
   ||nop
   and    @th,#~0x0002
   mov    *xar5,t
   banz   sndbit,ar0--
   tset   *xar5,#2

Клок 100 МГц, 1такт=10нс, 20 тактов на бит, битовая скорость 5Мбит/с. Для авр 20 МГц клок ожидается 5=100/20 раз меньшую скорость, т.е. 1 МГц.
defunct
Цитата(=GM= @ Sep 1 2008, 18:25) *
Ну, прекрасно, раз трудностей нет. Предлагаю в качестве эксперимента написать для авр на си программную выдачу 37-бит данных, сопровождаемых стробом:

Клок 100 МГц, 1такт=10нс, 20 тактов на бит, битовая скорость 5Мбит/с. Для авр 20 МГц клок ожидается 5=100/20 раз меньшую скорость, т.е. 1 МГц.

ОК smile.gif Что может быть проще.
Берем M8515 @16Mhz. Включаем внешнюю шину. Стоит ли продолжать? smile.gif

Код
// сразу 8 каналов, скорость порядка 4Mbps
void IO_Transfer( U8 *p )
{
     U8 size = 37;

     __disable_interrupt();
     while(size--)
     {
        *(volatile U8 *)0x8000 = *p++;
        delay_cycles( еще и тормозить придется чтобы 1Mbps получить);
     }
     __enable_interrupt();
}

предварительно заполняем массив из 37 элементов данными которые хотим слать и передаем указатель на этот массив в IO_Transfer. PC7 - признак работы нашего "serial" канала.

Строб снимаем с сигнала W. Данные с ШД.
=GM=
Цитата(defunct @ Sep 1 2008, 14:47) *
ОК smile.gif Что может быть проще. Строб снимаем с сигнала W. Данные с ШД

Ну, а если перенести на другой проц, будет та же самая программа? А там ШД нет, и W тоже нет, как быть? Да и на "нарезку" данных у вас уйдёт вагон времени, мы так не договаривались(:-).
zltigo
Цитата(=GM= @ Sep 1 2008, 18:14) *
...как быть?

Думать. В каждом конкретном случае - думать. И написав десяток строк даже самых лучших строк на ASM не закрывать глаза и уши на то, что программы по нынешним временам не состоят из нескольких десятков команд и занимаются не только ногомаханием. И контроллеров вокруг изрядное количество всяких и выбирать нужно подходящий не только по приципу знакомого ASM.
P.S.
Сейчас глянул, какой максимальный функциональный кусок на ASM я написал за последние несколько лет - ровно 50 команд smile.gif. Причем это не из-за скоростных наворотов - это минимальный обработчик exceptions для ARM. На алгоритмических языках такое просто нормально не пишется.
defunct
Цитата(=GM= @ Sep 1 2008, 19:14) *
Ну, а если перенести на другой проц, будет та же самая программа? А там ШД нет, и W тоже нет, как быть?

Задачи такого рода, можно сказать классический пример задач для FPGA/CPLD.
Отдавать всю производительность МК под эмуляцию железа конечно можно, но это не всега будет рациональным решением.

Если эта функция - самоцель (i.e. это ВСЯ или значительная часть работы которую должен делать МК), то я не побрезгую написать всю такую небольшую программу на асм'е. Если же это только 1% или меньше от всего задания, я предпочту аппаратное решение интерфейса и простую программную обертку на C.
=GM=
Краткие выводы из всех наших долгих разговоров.

1) Эксперимент показал (Юра, извини), что сишные программы не так уж и переносимы, как принято думать.
2) На переносимость влияет не только периферия, но и архитектура процессора. Например, один из самых простых алгоритмов в моём проекте - вычисление комплексного спектра аналитической функции - практически невозможно переложить с си-программы авр на си-программу дсп, ручками придётся добиваться "адекватности" алгоритма системе команд и архитектуре.
3) Из порядка 100 файлов проекта примерно 70 написаны на асме, причем последние занимают 90% процессорного времени. Поэтому каждую асм-программу приходилось тщательно вылизывать.
4) Применение аппаратных решений в виде FPGA приветствуется, но дорого, особенно для больших серий.
5) Пожелание начинающим имбеддерам: знание ассемблера применённого проца обязательно.
6) Из моего опыта. Все асм-программы я оформляю в соответствии с конвенциями вызова из си-программы, очень удобно, не надо беспокоиться, из какой программы они вызываются.
zltigo
Цитата(=GM= @ Sep 1 2008, 22:32) *
3) Из порядка 100 файлов проекта примерно 70 написаны на асме, причем последние занимают 90% процессорного времени. Поэтому каждую асм-программу приходилось тщательно вылизывать.

Из 138 файлов текущего проекта c размером бинарника 202623 байта работающего на контроллере ценою менее 6USD на ASM писаны три:
- стартап;
- переключатель контекста;
- memcpy/memmove/memset (на самои деле традиция оставшиеся со времен хреновенькой библиотеки IAR V4 - убрать можно)
В сумме байт 300. Процентов 55 проекта это просто ранее работавший код на 51, 186 контроллерах и 486 под линуксом. Остальной просто новый smile.gif. Дописав/переписав не более 1000 строк из 65333 я перенесу его на, практически любой приличный контроллер.

Вот такие выводы smile.gif, понимаш.... Посему с очередными рассуждениями о писательстве на ASM, тем более в совершенно не для этого созданной ветке завязываем.
SasaVitebsk
Я бы ещё отметил, в дополнение к сказанному, что есть мелкие камни стоимостью менее 1$. Та же м8 к примеру. Есть и другие аппаратные решения. В связи с этим необходимо осмыслить необходимость вылизывания задачи до уровня загрузки проца 99%, что приведёт к некоторым сложностям по развитию проекта. А попробовать разбить задачу на несколько. Либо подобрать такой МК, который будет соответствовать решаемой задаче с некоторым запасом производительности.

Безусловно, что выбор за разработчиком.
=GM=
Цитата(SasaVitebsk @ Sep 2 2008, 08:58) *
В связи с этим необходимо осмыслить необходимость вылизывания задачи до уровня загрузки проца 99%, что приведёт к некоторым сложностям по развитию проекта. А попробовать разбить задачу на несколько. Либо подобрать такой МК, который будет соответствовать решаемой задаче с некоторым запасом производительности

Вообще, так и делалось. Сначала был выбран TMS320F2812, 150 МГц такт, 128 Кб флеши, потом по мере выработки и устаканивания концепции плавно опустились до TMS320F2810 и TMS320F2808, и наконец, до TMS320F2801, куда планируется заливать фирменный софт, уже масочный. Даже в последнем проце ресурсы задействованы примерно на 80%. По стоимости первый проц и последний различаются раза в 4. А вылизывания особого не было, как писалось, так и писалось, с максимальным быстродействием по возможности.
SasaVitebsk
В массовых изделиях, совершенно обосновано максимальное вылизывание проекта, включая ассемберные вставки. Безусловно это оправдано только в случае стопроцентной уверенности в "правильности прошивки". А это предполагает чёткий алгоритм тестирования всего изделия.

Если брать саму тему, то приятно что в моделях XMEGA данная проблема решена со всех сторон.
1) Предусмотрены приоритеты прерывания, что избавляет от необходимости разрешать вручную влож. прерывания
2) Увеличена тактовая частота, что позволяет быстрее обработать прерывание
3) Тактирование таймера предусматривает возможность умножения частоты
(Я о первоначальной задаче)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.