|
Прерывания в компиляторе RealView, 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
|
|
|