|
|
  |
Приоритет прерываний, и прерывание прерываний |
|
|
|
Aug 31 2008, 22:01
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Rst7 @ Aug 30 2008, 07:31)  Общая идея в том, чтобы не работать с глобальными переменными, а работать с регистровыми. Например, обработчик INT0 после переделки занимает 27 тактов со всеми входами и выходами (это результат IAR'а) Интересно бы взглянуть на код. Хотя по смыслу переменные t, pos должны быть 16-битными, если не 32-битными. У меня для целых (16-битных) на асме получилось 18 тактов. А вообще вывод неутешительный, время выполнения двух прерываний порядка 83 тактов, явно подпадает под расстрельную статью...
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 05:49
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Интересно бы взглянуть на код Код RSEG CODE:CODE:NOROOT(1) // 147 __interrupt void INT0_proc(void) INT0_proc: // 148 { ST -Y, R17 ST -Y, R16 IN R17, 0x3F // 149 unsigned char t=pos-1; LDS R16, pos DEC R16 // 150 if (PIND&0x01) t+=2; SBIC 0x09, 0x00 SUBI R16, 254 // 151 pos=t; ??INT0_proc_0: STS pos, R16 // 152 } OUT 0x3F, R17 LD R16, Y+ LD R17, Y+ RETI REQUIRE _A_PIND // 153 // 154 #pragma vector=TIMER1_OVF_vect
RSEG CODE:CODE:NOROOT(1) // 155 __interrupt void T1_proc(void) T1_proc: // 156 { ST -Y, R18 ST -Y, R17 ST -Y, R16 IN R18, 0x3F // 157 unsigned char t; // 158 __enable_interrupt(); SEI // 159 t=PORTC; IN R16, 0x08 // 160 t<<=1; LSL R16 // 161 if (PORTC&0x08) t=1; SBIC 0x08, 0x03 LDI R16, 1 // 162 PORTC=t; ??T1_proc_0: OUT 0x08, R16 // 163 TCNT1 = 0x10000 - 62500 / Frq; LDI R16, 250 LDI R17, 255 STS 133, R17 STS 132, R16 // 164 } OUT 0x3F, R18 LD R16, Y+ LD R17, Y+ LD R18, Y+ RETI REQUIRE _A_TCNT1 REQUIRE _A_PORTC А старший байт pos (если надо) - лучше править не в процедуре прерывания, а отдельно.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 08:07
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(Dog Pawlowa @ Sep 1 2008, 12:36)  Ну не знаю, кто как, но я зарекся делать системы без запаса 50%. Само собой, 250 кГц, для текущего проека, это запас примерно 1000%. 250 кГц были определены среднепотолочным методом, просто с учетом планов на будущее. Реально прерывания от таймера "шлепают" с частотой 12 кГц, а от INT0 с частотой около 30 кГц, причем это тоже, вероятно с запасом.  p.s. А в WinAVR можно результат работы компилятора как в посте Rst7, да и где взять время выполнения команд? Вообщем как можно быстро расчитать время обработки прерывания?
--------------------
Если все, то не я...
|
|
|
|
|
Sep 1 2008, 09:49
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата И как вы себе представляете правку старшего байта вне прерывания? Вполне просто. Изредка запускаем проверку, не изменился ли старший бит pos и если изменился - меняем старший байт. Заодно там, где необходимо значение pos тоже выполняем такую проверку. Цитата Из вашего кода у меня получилось 28 тактов, да ещё без sei. Код для INT0 не предусматривал SEI. Тактов, кстати, 27, если RJMP c вектора. Цитата Не могу понять почему компайлер у вас не сохраняет SREG? А порт 0x3F - это что по Вашему? Цитата Нельзя ли посмотреть на код с 16-битными t и pos? А смысл? Цитата Ваш код какой-то левый. Выбирайте выражения. ...Чуть позже... С банальной проверкой старшего бита я погорячился малость, там надо проверять изменение 2х старших бит из 00 в 11 и наоборот. Это и будет обозначать инкремент или декремент старшего байта. Но не суть, такую проверку можно выполнить один раз на, скажем, 50 прерываний INT0. Цитата А в WinAVR можно результат работы компилятора как в посте Rst7 Как-то там через зопу. Смотрите elfdump или objdump. Запускаете его с ключиком (не помню каким, в хелпе глянете) и он дампит выходной эльф-файл с включением строк исходника. Цитата да и где взять время выполнения команд? В даташите на контроллер. В табличке с набором команд. Цитата Вообщем как можно быстро расчитать время обработки прерывания? Я руками считаю. Навык, выработанный годами
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 09:52
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

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

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(Rst7 @ Sep 1 2008, 14:49)  А смысл? С точки зрения технических требований задачи переменная pos должна быть 32 битной.
--------------------
Если все, то не я...
|
|
|
|
|
Sep 1 2008, 10:02
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата То есть был 127, стал 128 - меняем старший байт? Я исправился  дописал еще, причем другим постом, дабы пришло уведомление. Цитата Да и что значит изредка? Изредка - это значит при максимальной частоте входного сигнала не реже чем 64 прерывания (вот я и взял с потолка число 50). Вполне можно запустить флаг задачи от таймерного прерывания. Цитата С точки зрения технических требований задачи переменная pos должна быть 32 битной. Ну изменяйте 3 дополнительных байта, не суть. Не надо их в каждом прерывании носить туда-сюда, вот я о чем.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 1 2008, 10:43
|

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

|
Цитата(PhX @ Sep 1 2008, 11:07)  Реально прерывания от таймера "шлепают" с частотой 12 кГц, а от INT0 с частотой около 30 кГц, причем это тоже, вероятно с запасом.  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% загрузка процессора.
|
|
|
|
|
Sep 1 2008, 11:00
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(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 либо листинг одного файла, как указано выше, но иногда бывает нужно потрошить содержимое после линковки.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 1 2008, 11:03
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(defunct @ Sep 1 2008, 09:43)  Если пропорция между частотой таймера и INT0 сохранится при INT0 = 250kHz. То 83 такта достаточно. Система не потеряет ни одного прерывания Вывод такой, если прерывания int0 возникают каждые 64 такта, то само прерывание int0 не должно выполняться более, чем за 64-9=55 тактов. 9 тактов нужны, чтобы войти в прерывание от таймера и разрешить остальные прерывания. При подсчёте тактов не учитывался джиттер от завершения команды перед входом в прерывание. Автору следует посчитать время выполнения int0, особенно в свете новых сведений, что переменная pos должна быть 32-битной.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 1 2008, 11:07
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата 77% загрузка процессора. Необходимо учесть еще периодический вызов проверки переполнения счетчика энкодера и коррекции старшей части. Но это, в принципе, будет пыль. Кстати, где вы там нашли 83 такта на все? 27+36, а если сделать через таймерное прерывание через OCR, то еще меньше. Цитата Автору следует посчитать время выполнения int0, особенно в свете новых сведений, что переменная pos должна быть 32-битной. Не надо трогать все 32 бита
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|