|
Прерывания в компиляторе RealView, IRQ или FIQ? |
|
|
|
Jun 27 2007, 07:17
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 13-09-06
Пользователь №: 20 359

|
Разбирались мы тут с прерываниями и накопали вот что. Компилятор armcc не делает разницы между IRQ и FIQ перываниями, и использует как в IRQ так и в FIQ режимах общие регистры R0-R7, сохраняя их в стеке при входе прерывания. А вот в описании архитектуры ARM7TDMI сказано что в режиме FIQ регистры R8-R14 в нутри прерывания это banked registers, то есть они не пересекаются с регистрами R8-R14 вне прерывания и их не надо класть в стек. Так вот, может кто знает, можно ли как-нибуть указать компилятору, чтобы он пользовался этими banked register, а не общими? Хотя и экономится всего 2 команды, но ради научного интереса хочется выжать из Fast Interrupta все на что он способен!
|
|
|
|
|
Jun 27 2007, 08:15
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(SanyaKID @ Jun 27 2007, 10:17)  Так вот, может кто знает, можно ли как-нибуть указать компилятору Скорее всего, если это он сам не делает, то указать нельзя  . У IAR тоже не совсем хорошо - пользует R8-R10, но если их не хватает, то начинает пользовать младшие, а не R11 и R12  Хотя, я, пожалуй, не прав на счет младших, когда копался в коде, забыл, что используется вызов подпрограмм и соответственно компилятор вынужден ими пользоваться и соответственно пользуется ими и для дугих целей.
Сообщение отредактировал zltigo - Jun 27 2007, 08:41
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 27 2007, 09:29
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 13-09-06
Пользователь №: 20 359

|
Цитата(SpiritDance @ Jun 27 2007, 12:41)  В realView при описании обработчика IRQ на С используется ключевое слово __irq. Для прерываний fiq никаких ключевых слов и средств работы с fiq на С нет. Да, но можно сделать так, чтобы оно вызывалось в режиме FIQ. В стартапе есть FIQ_Handler, содержащий адрес обработчика перываний FIQ. Если ему скормить адрес функции с ключевым словом __irq, и сделать одно из прерываний FIQ, то будет вызываться она. А вообще, похоже всеже нельзя явно указать компилятору какие регистры использовать...
Сообщение отредактировал SanyaKID - Jun 27 2007, 09:31
|
|
|
|
|
Jun 27 2007, 09:50
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 13-09-06
Пользователь №: 20 359

|
Цитата(SpiritDance @ Jun 27 2007, 13:39)  Смысл ключевых слов именно в этом. А контроллеру прерываний вы можете скормить что угодно. Понятно, я не до конца вник во фразу
Сообщение отредактировал SanyaKID - Jun 27 2007, 09:51
|
|
|
|
|
Jul 11 2007, 09:00
|
Группа: Новичок
Сообщений: 9
Регистрация: 29-03-07
Пользователь №: 26 595

|
В STR91x лучше дело обстоит - для FIC выделен "свой собственный банк регистров для минимизации времени контекстного переключения". Вот только что это за регистры не сказано - фик знает.
|
|
|
|
|
Jul 11 2007, 09:30
|
Частый гость
 
Группа: Новичок
Сообщений: 84
Регистрация: 24-05-07
Пользователь №: 27 947

|
Цитата(Andy_ry @ Jul 11 2007, 13:00)  В STR91x лучше дело обстоит - для FIC выделен "свой собственный банк регистров для минимизации времени контекстного переключения". Вот только что это за регистры не сказано - фик знает.  Только не лучше, а так же, как и у остальных процессоров с ARM ядром. Регистры R8-R12.
|
|
|
|
|
Jul 11 2007, 15:09
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Andy_ry @ Jul 11 2007, 12:00)  В STR91x лучше дело обстоит... Если-бы Вы были внимательнее, то поняли, что обсуждается не отсутствие (который на самом деле присутствеет, как уже писалось, во всех ARM и документрован) отдельного банка регистров, а то, что RealView НЕ УМЕЕТ ИМ ПОЛЬЗОВАТЬСЯ.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 16 2007, 10:32
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 13-09-06
Пользователь №: 20 359

|
Цитата(zltigo @ Jul 11 2007, 19:09)  Если-бы Вы были внимательнее, то поняли, что обсуждается не отсутствие (который на самом деле присутствеет, как уже писалось, во всех ARM и документрован) отдельного банка регистров, а то, что RealView НЕ УМЕЕТ ИМ ПОЛЬЗОВАТЬСЯ. Да, пользоваться он ими действительно не умеет. В итоге, у меня получился вариант, когда в Си функция прерывания описана как IRQ, но настроена как FIQ и в стартапе FIQ Handler скормлен адрес этого самого обработчика, помеченного как FIQ. Вызываться обработчик должен немного быстрее, но ,вообще говоря, то, что компилятор не использует специальные регистры этого режима, сводит почти на нет все преимущество FIQ
|
|
|
|
|
Jul 17 2007, 06:40
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 13-09-06
Пользователь №: 20 359

|
Цитата(SergeyDDD @ Jul 16 2007, 15:51)  Далай обработчик FIQ на ассемблере Я долго ждал, когда ж мне это скажут
|
|
|
|
|
Jul 17 2007, 14:33
|
Местный
  
Группа: Свой
Сообщений: 231
Регистрация: 7-12-06
Из: Киев
Пользователь №: 23 248

|
Цитата(SanyaKID @ Jul 17 2007, 10:40)  Я долго ждал, когда ж мне это скажут  Ну так...... Слушай меня....... "Хотя и экономится всего 2 команды, но ради научного интереса хочется выжать из Fast Interrupta все на что он способен!" А ваче то что может быть при такой постановке вопроса? И после всего написанного здесь.
Сообщение отредактировал SergeyDDD - Jul 17 2007, 15:06
|
|
|
|
|
Jul 19 2007, 12:41
|
Местный
  
Группа: Новичок
Сообщений: 239
Регистрация: 5-10-06
Пользователь №: 21 004

|
Цитата(SanyaKID @ Jul 16 2007, 14:32)  у меня получился вариант, когда в Си функция прерывания описана как IRQ, но настроена как FIQ и в стартапе FIQ Handler скормлен адрес этого самого обработчика, помеченного как FIQ. Если нетрудно и возможно прицепите пример ваш.
|
|
|
|
|
Jul 22 2007, 14:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(AlexandrY @ Jul 22 2007, 16:54)  человек поднял проблему не подумавши. Ну а если подумать над словами человека? Это если компилятор знает про FIQ: Код FIQ_ISR_handler: MOV R8,#+4 LDR R9,??FIQ_ISR_handler_0;; 0xffffffffe01fc140 LDR R10,??FIQ_ISR_handler_0+0x4;; fic_counter ??FIQ_ISR_handler_1: LDR R11,[R10, #+0] ADD R11,R11,#+1 STR R11,[R10, #+0] LDR R11,[R9, #+0] ORR R11,R11,#0x4 STR R11,[R9, #+0] STR R8,[R9, #+0] LDR R11,[R9, #+0] AND R11,R11,#0x4 LSRS R11,R11,#+2 BNE ??FIQ_ISR_handler_1 SUBS PC,LR,#+4 ;; return А это если ему что IRQ, что FIQ все едино Код FIQ_ISR_handler: PUSH {R0-R3} MOV R0,#+4 LDR R1,??FIQ_ISR_handler_0;; 0xffffffffe01fc140 LDR R2,??FIQ_ISR_handler_0+0x4;; fic_counter ??FIQ_ISR_handler_1: LDR R3,[R2, #+0] ADD R3,R3,#+1 STR R3,[R2, #+0] LDR R3,[R1, #+0] ORR R3,R3,#0x4 STR R3,[R1, #+0] STR R0,[R1, #+0] LDR R3,[R1, #+0] AND R3,R3,#0x4 LSRS R3,R3,#+2 BNE ??FIQ_ISR_handler_1 POP {R0-R3} SUBS PC,LR,#+4 ;; return
Сообщение отредактировал zltigo - Jul 22 2007, 14:34
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 22 2007, 19:29
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergeeff @ Jul 22 2007, 22:18)  Но на практике навар будут только в случае, если для обработки fiq хватает четырех регистров на все про все. Нет. 1. Регистров 7; 2. Навар в виде экономии времени и стека на пушировании семи регистров FIQ банка будет абсолютно всегда, даже если потребуются все регистры, экономия почти двойная. P.S. Избегайте ненужного цитрования.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 22 2007, 19:53
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Этот пример содержит подвох. Достаточно юзеру снова резрешить FIQ прерывания на входе в такой обработчик и он получит глюков по полной. И при этом он будет иметь право требовать от ARM возмещения убытков. Не забываем, что юзер будет писать на C и не подозревать как используются регистры. А компилятор не будет пытаться расшифровать программу юзера на тему разрешил или нет он FIQ на входе в обработчик. Вообщем есть стандарт "Procedure Call Standard for the ARM® Architecture" Принебрегать им могут только компиляторы низкого уровня. Скажите в каком компиляторе вы видели такой код, и я буду знать какой компилятор даже пробывать не стоит. Цитата(zltigo @ Jul 22 2007, 22:59)  Навар в виде экономии времени и стека на пушировании семи регистров FIQ банка будет абсолютно всегда, даже если потребуются все регистры, экономия почти двойная.
|
|
|
|
|
Jul 22 2007, 20:23
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(AlexandrY @ Jul 22 2007, 22:53)  Этот пример содержит подвох. Не больше, чем IRQ, который тоже не поддерживает вложенных прерываний без принятия дополнительных мер. Цитата Достаточно юзеру снова резрешить FIQ прерывания на входе в такой обработчик и он получит глюков по полной. Как и при вложеных прерываниях в обработчик IRQ, и мириадах других случаев, если мифический юзер не будет ведать, что творит. Цитата Вообщем есть стандарт "Procedure Call Standard for the ARM® Architecture" Который к обработчикам прерываний ни сном ни духом, однако. Цитата Скажите в каком компиляторе вы видели такой код Любой, который имеет квалификатор __fiq. В данном конкретном случае IAR.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 22 2007, 21:34
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(AlexandrY @ Jul 22 2007, 23:35)  Юзер на C не успеет вновь разрешить прерывания до сохранения регистров, так что здесь все чисто. Чисто?  А с SPSR_irq и LR_sys, что будет, если неразумный юзер их не сохранит 'просто' разрешив прерывания в обработчике? Короче, юзер должен быть разумным - без этого никак. Ну а разумный юзер для начала: 1. не будет в обработчик самого приоритетного прерывания вкладывать какие попало IRQ; 2. думать зачем иметь несколько FIQ; 3. очень крепко думать, зачем их делать вложенными; 4. и если вдруг придучает зачем, что будет очень странным для разумного юзера, поймет, что этот обработчик вовсе и не __fiq у него получися  и скажет компилятору, что это __irq. За то, что мне, "разумному юзеру" не дают воспользоваться банком регистров FIQ я не скажу спасибо разработчикам такого компилятора. Ваши попытки оправдать отсутствие такой возможности у компилятора заботой о "неразумном юзере" очень неуклюжи  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 22 2007, 21:49
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Ok! Согласен. В принципе цели мы добились. Человек должен понять, что корректно написать быстрый обработчик без asm-а он не сможет. Цитата(zltigo @ Jul 23 2007, 01:04)  Чисто?  А с SPSR_irq и LR_sys, что будет, если неразумный юзер их не сохранит 'просто' разрешив прерывания в обработчике? Короче, юзер должен быть разумным - без этого никак. Ну а разумный юзер для начала: 1. не будет в обработчик самого приоритетного прерывания вкладывать какие попало IRQ; 2. думать зачем иметь несколько FIQ; 3. очень крепко думать, зачем их делать вложенными; 4. и если вдруг придучает зачем, что будет очень странным для разумного юзера, поймет, что этот обработчик вовсе и не __fiq у него получися  и скажет компилятору, что это __irq. За то, что мне, "разумному юзеру" не дают воспользоваться банком регистров FIQ я не скажу спасибо разработчикам такого компилятора. Ваши попытки оправдать отсутствие такой возможности у компилятора заботой о "неразумном юзере" очень неуклюжи  .
|
|
|
|
|
Jul 23 2007, 09:44
|

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

|
Цитата(sergeeff @ Jul 21 2007, 14:05)  Не понимаю. Согласно стандарту вызова функций scratch регистры не сохраняются. Прерывание может прийти в любой момент времени. Значит обработчик должен сохранить именно scratch - остальные при необходимости и так сохранятся при вызове функции, если функции это надо. Ключевые слова типа __irq именно это и заставляют компилятор делать. Или нет? Возможно я был не прав в своих заблуждениях. Давайте разбираться. То, что остальные регистры сохранятся при вызове функции вовсе не значит, что прерывание может их испортить. К scratch относятся R0-R3, R12. При возникновении исключения IRQ (а именно о нем шла речь в контексте многих обработчиков) переключаются только R13, R14 и значит общая "обертка" должна сложить на стек все 5 scratch регистров, ибо не имеет информации какой из них будет испорчен в конкретном обработчике. Если же мы даем компилятору возможность для каждого обработчика сгенерить свои пролог/эпилог, то для некоторых прерываний, в которых не все scratch регистры портятся, компилятор имеет право сохранять/восстанавливать только используемые (экономятся такты и место на стеке). Едем далее - в каждой самой "внешней" функции обработчика компилятор должен сохранить preserved регистры, которые используются. В случае индивидуального пролога/эпилога он может объединить в одну команду сохранение scratched и preserved регистров (сэкономив такты и код), а в случае общего пролога/эпилога ему придется делать две команды - сохранение scratched в прологе и сохранение preserved в теле обработчика. Аналогичные выкладки для эпилога. Где ошибка в рассуждениях? Цитата(AlexandrY @ Jul 22 2007, 16:54)  Вы правы, человек поднял проблему не подумавши. Если вы это про мой пост, то особенно хотелось бы услышать Ваши контр-аргументы.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 24 2007, 06:25
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergeeff @ Jul 24 2007, 09:01)  Но. Предположим, что из функции обраб отчика прерывания вызывается еще какая-то "не умная" функция, которая обычным образом использует scratch регистры. Тогда будут использоватся наряду с собственными регистрами и R0..R3. Эффект от использования FIQ уменьшится, но не исчезнет. Кроме того, 'развесистые' обработчики FIQ так или иначе не влезают только в FIQ регистры и использование общих регистров этом случае начинается с scratch регистров. Все вполне эффективно получается и без 'изощренного анализа'. Цитата И что делать тогда? Запретить вызовы функций? Кроме того, если действительно это действительно быстрый обработчик, то действительно избегать вызовов функций и не только по причине использования ими регистров. Цитата Думается, что это одно из объяснений, почему многие производители компиляторов это дело похоронили. 'Обьяснений' ничего не объясняющих было уже много. Может достаточно?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 24 2007, 09:05
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 13-09-06
Пользователь №: 20 359

|
Ничего себе сколько тут уже понаписали... Вообщем-то вопрос насколько я помню, ставился так: умеет ли RealView работать с FIQ или нет. Оказалось что нет. И вполне понятно, что чтобы полностью использовать все прелести FIQ в данном компиляторе надо писать на ASM. Тут кто-то просил исходники... Это что касается обработчика Код void i2c_init() { PINSEL0 = 0x50; //Switch GPIO to I2C pins I2C0ADR = SLAVE_ADR; I2C0CONSET = 0x44; VICIntSelect = 0x00000200; //VICVectCntl1 = 0x00000029; //VICVectAddr1 = (unsigned)I2CISR;
I2C_ENABLE; }
void I2CISR (void) __irq //I2C interrupt routine { ... } А это в стартапе Код FIQ_Addr DCD FIQ_Handler ... FIQ_Handler B I2CISR ... IMPORT I2CISR Так вот, у такого подхода, кроме того что такой обработчик будет вызываться немного быстрее чем просто IRQ, неожиданно появился новый плюс. В проекте используется операционка RTX от Keil, в которой соответственно используются прерывания от таймера. Мне необходимо записывать во внутреннюю флеш. В IAP в момент записи нужно запрещать прерывания или убирать их в RAM. Однако нужно чтобы I2C все равно работал в момент записи. В итоге, в теории, чтобы не ковыряться с прерыванием от таймера в RTX, можно запретить все IRQ на время записи/стирания флеша, а обработчик FIQ для I2c поместить в RAM. Кроме того для работы FIQ достаточно в RAM поместить только сам обработчик, так как его адрес лежит в регистре. Щас попробую све это забацать. Посмотрим как будет работать.
|
|
|
|
|
Jul 24 2007, 10:48
|

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

|
Цитата(sergeeff @ Jul 24 2007, 09:01)  Предположим, что из функции обработчика прерывания вызывается еще какая-то "не умная" функция, которая обычным образом использует scratch регистры. И что делать тогда? Дальше действует Procedure Call Standard for the ARM® Architecture. Т.е. необходимые scratch регистры сохраняет вызывающая функция, preserved регистры - вызывающая. Все равно остается поле для оптимизации. Собственно я защищаю только одну фразу: Цитата(Сергей Борщ @ Jul 21 2007, 10:54)  Индивидуальный обработчик на каждый источник позволяет компилятору сохранять на стеке только необходимые регистры. В общем же придется сохранять все. Именно это является преимуществом индивидуального пролога/эпилога. Недостатком является увеличение кода.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 24 2007, 15:02
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(SanyaKID) В итоге, в теории, чтобы не ковыряться с прерыванием от таймера в RTX, можно запретить все IRQ на время записи/стирания флеша, а обработчик FIQ для I2c поместить в RAM. Кроме того для работы FIQ достаточно в RAM поместить только сам обработчик, так как его адрес лежит в регистре.
Щас попробую све это забацать. Посмотрим как будет работать. Ну а процессор настолько умный, что сам из регистра вектор копирует в R15 :-) PS. При одном FIQе прописывать VICVectAddrX вообще-то не обязательно.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 25 2007, 09:43
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 13-09-06
Пользователь №: 20 359

|
Цитата(GetSmart @ Jul 24 2007, 19:02)  Ну а процессор настолько умный, что сам из регистра вектор копирует в R15 :-)
PS. При одном FIQе прописывать VICVectAddrX вообще-то не обязательно. Да, насчет векторов я неправ. Адрес обработчика FIQ тоже во FLASH лежит... А в VICVectAddrX я ниче и не писал.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|