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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Вложенные прерывания, GCC и ARM7
Novichok1
сообщение Mar 5 2010, 12:23
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



Цитата(aaarrr @ Mar 5 2010, 13:04) *
Вложенные прерывания предполагают, что выполнение процедуры обработки прерывания с приоритетом 5 может быть прервано прерыванием с приоритетом 6 или выше. Прерывание с меньшим приоритетом (4) может отработать только после записи VicVectAddr.

А не наоборот? Из мануала по LPC24xx
Цитата
There are 16 priority levels, corresponding to the values 0 through 15 decimal, of which 15 is the lowest priority.

То есть четвертый приоритет выше пятого.

Цитата
Кроме того, следует обратить внимание на некорректное выравнивание стека - должно быть четное число слов

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

Сообщение отредактировал Novichok1 - Mar 5 2010, 12:25
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 5 2010, 12:35
Сообщение #17


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
Все-таки кажется странным, что некорректный код публиковали бы под столь серьезным названием.

Не парьтесь, выравнивание на ARM7 не влияет ни на что. На LPC2xxx даже можно SP по модулю 4 не выравнивать smile.gif (Хотя не проверял, но по всем признакам это так)


Цитата(Novichok1)
А что на счет r3, это нормально, что она не сохраняется в стек?

Вероятнее всего функция объявлена не как прерывание, а как просто функция. Там в атрибутах ещё должно указываться тип IRQ или FIQ, но точно не проверял как это влияет на прологи/эпилоги. Просто ставил всегда, когда не ставил свои обёртки. Со своими обёртками использовал атрибут naked.

Сообщение отредактировал GetSmart - Mar 5 2010, 12:38


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 5 2010, 12:41
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Novichok1 @ Mar 5 2010, 15:23) *
А не наоборот? Из мануала по LPC24xx

То есть четвертый приоритет выше пятого.

Наоборот, не важно, уберите цифры и читайте больший-меньший.

Цитата(Novichok1 @ Mar 5 2010, 15:23) *
Все-таки кажется странным, что некорректный код публиковали бы под столь серьезным названием.

Легко. Вы думаете, этот код великие корифеи пишут? Да и на старуху бывает проруха.

Цитата(GetSmart @ Mar 5 2010, 15:35) *
Не парьтесь, выравнивание на ARM7 не влияет ни на что. На LPC2xxx даже можно SP по модулю 4 не выравнивать smile.gif (Хотя не проверял, но по всем признакам это так)

Ну, когда наткнетесь на некорректную работу плавучки, вспомните про выравнивание стека wink.gif
Go to the top of the page
 
+Quote Post
Novichok1
сообщение Mar 5 2010, 12:43
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



Цитата(GetSmart @ Mar 5 2010, 15:14) *
Это точно пролог/эпилог функции с атрибутом interrupt ?

Ох, виновен, виновен. Вот пролог:
Код
@ Interrupt Service Routine.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
sub    lr, lr, #4
stmfd    sp!, {r0, r1, r2, r3, ip, lr}

и эпилог:
Код
ldmfd    sp!, {r0, r1, r2, r3, ip, lr}
subs    pc, lr, #4

То есть вроде все нормально. Но глюк то есть.

Но опять таки, если применять свои ассемблерные вставки входа и выхода из обработчиков, то все в порядке. Но чтобы в одном обработчике прерывания можно было перейти в другое с более высоким приоритетом, нужно совершить запись в VicVectAddr, что не есть правильно. Посмотрел ассемблерные вставки, предложенные Вами, GetSmart, но они вроде ничем принципиальным не отличаются от тех, которыми пользуюсь я, то есть, тоже сохранение контекста, переход в другой режим работы процессора с разрешенными прерываниями, и вызов функции. Так чего же не хватает?

Сообщение отредактировал Novichok1 - Mar 5 2010, 12:48
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 5 2010, 12:54
Сообщение #20


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Novichok1 @ Mar 5 2010, 17:43) *
То есть вроде все нормально. Но глюк то есть.

Нихрена не нормально. Это бага GCC. Оно два раза вычетает из LR (адрес возврата в основную прогу) число 4. Кстати, я сразу не заметил, но и в первом прерывании та же самая беда.

Цитата
Но чтобы в одном обработчике прерывания можно было перейти в другое с более высоким приоритетом, нужно совершить запись в VicVectAddr, что не есть правильно.

Такого не должно быть. Эта вещь реализована аппаратно в контроллере прерываний. Единственная причина по которой проц не может улететь на более высокоприоритетное прерывание - запрещённые глобально прерывания (все). То бишь установленный в "1" флаг I в регистре флагов.

Сообщение отредактировал GetSmart - Mar 5 2010, 12:57


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Novichok1
сообщение Mar 5 2010, 12:55
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



Цитата(GetSmart @ Mar 5 2010, 15:35) *
Со своими обёртками использовал атрибут naked.

О! А этот вопрос был у меня в начале этой темы, не подскажете, как в GCC создавать свои атрибуты? Очень интересно и думаю будет полезно.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 5 2010, 13:03
Сообщение #22


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Это не свой атрибут, а стандартный. Используется так:
void AdcIntr_Wrapper() __attribute__((naked));
Но очень желательно в GCC с такой обёрткой делать пустую функцию (пустышку) из которой будет вызываться основная функция обработчика. Иначе можно встать на другие грабли, когда из кода выкинется выделение фрейма в стеке.

И ещё вопрос. В тестируемом коде по адресу 0x18 стоит команда LDR PC,[PC,#-0x120] ?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Novichok1
сообщение Mar 5 2010, 13:12
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



Цитата(GetSmart @ Mar 5 2010, 15:54) *
То бишь установленный в "1" флаг I в регистре флагов.

Странно, я же сбрасываю его в ноль:

/* (4) Change to SYS mode and enable IRQ */
msr cpsr_c, #0x1F

Цитата
Это не свой атрибут, а стандартный. Используется так:
void AdcIntr_Wrapper() __attribute__((naked));

Спасибо, а не в курсе, в GCC все-таки можно создавать свои атрибуты?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 5 2010, 14:03
Сообщение #24


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Novichok1)
Спасибо, а не в курсе,

Не, не в курсе. Я с GCC недавно пересёкся и не знаю что там к чему. Есть здесь такой чел klen он должен быть в курсах.

Кстати, пустышку-обработчик не стоит обзывать static иначе она оптимизируется и выкинется.

Если глобальные прерывания разрешены, значит что-то другое делаете не так. Может приоритеты неправильно задаёте. Вы тут периодически ошибаетесь, а мне гадать не интересно.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 11 2010, 12:21
Сообщение #25


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Novichok1, хотел ещё спросить, зачем было делать обработчик функцией класса? Ведь изнутри обработчика всё равно доступа к классу не будет.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Novichok1
сообщение Mar 11 2010, 15:07
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



А разве к статическим членам нет доступа? Ведь обработчик-это просто функция (в моем случае-статический метод класса), у которой есть определенная отличная последовательность загрузки выгрузки. По сути, это низкоуровневый эквивалент событий(точнее, события-высокоуровневый эквивалент прерываний), по крайней мере по моим представлениям. Ну а к экземпляру класса, да, прямого доступа не будет.
А сделал так, чтобы не нарушать стройность классовой модели, не хочу смешивать чисто сишные функции с классами. Это дает дополнительные преимущества по областям видимости данных и методов, а минусов я пока не нашел, если Вы их видите, то прошу ими поделиться.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 11 2010, 16:35
Сообщение #27


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Я бы всё таки выделил прерывания из класса. ИМХО это логичнее, так как действует по другому механизму вызова/передачи параметров. А уже из прерывания можно вызывать функцию(и) любого статического экземпляра, либо из статического указателя. В частности только для этого можно создать функцию класса, вызываемую из обработчика. Но сам обработчик будет вне класса. Во-первых из-за глюков компилятора и обходных путей этих глюков. Я пару постов назад описывал обходной путь именно для сишных функций (хоть с++ вне класса). На функциях класса этот путь не проверял. Знаю только что обычным функциям класса передаётся "невидимый" параметр с указателем на текущий экземпляр класса. Как работает этот механизм со статическими функциями не знаю, может оказаться что им тоже должен передаваться какой-то параметр, который при вызове обработчика прерывания отсутствует.

Да и само по себе прерывание ни к какому классу не должно относиться. Это функция процессора и процессор (если считать его классом) существует в единственном экземпляре, как и конкретное прерывание. Даже со стороны ООП подхода к проге я не вижу причин делать прерывание функцией класса. Но это моё сугубо личное мнение.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Novichok1
сообщение Mar 11 2010, 18:22
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



Цитата(GetSmart @ Mar 11 2010, 20:35) *
Знаю только что обычным функциям класса передаётся "невидимый" параметр с указателем на текущий экземпляр класса.


Это верно, но только для нестатических методов, то есть которые привязаны к конкретному экземпляру класса, на статические методы, которые принадлежат типу, а не конкретному экземпляру данного типа, это не распространяется, никаких невидимых параметров, типа параметра "this" туда не передается.

Цитата(GetSmart @ Mar 11 2010, 20:35) *
А уже из прерывания можно вызывать функцию(и) любого статического экземпляра, либо из статического указателя.

О, а это очень даже полезная идея! Насколько я Вас понял, Вы предлагаете примерно следующее: этот главный обработчик обернуть в нечто подобное делегату из C#. В итоге это даст возможность легко подписываться на это прерывание из разных мест разным классам. Правда неизбежны некоторые накладные расходы на вызовы функций и дополнительные проверки.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 11 2010, 19:02
Сообщение #29


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Вообще, излишняя универсальность, которая не понадобится в проге мне не нравится. Но как вариант, имеется класс низкого уровня с виртуальной функцией обработчика прерывания. Обработчик прерывания использует статическую переменную с указателем на этот класс. При входе в обработчик он вызывает эту функцию. Указатель можно инициализировать и менять в процессе любым совместимым экземпляром класса.

А минимально, по простому:
Код
void MyIrq()
{
MyClassPtr->IrqHandler();  // функция класса, не статическая, статический указатель на экземпляр класса
}

void MyIrq_Wrapper() // адрес этой функции будет записан в обработчик прерывания, должен быть атрибут (naked)
{
asm("пролог");
MyIrq();
asm("эпилог");
}

Накладных расходов здесь почти нет. Главный накладной расход - компилятор GCC, так как у него не самый оптимальный код.

В принципе, можно даже MyIrq() сократить, только предворительно проверить что за код создаёт компилер во всех режимах оптимизации. Лишь бы фрейм стека не выделялся.

-----------
А чем вообще отличается статическая функция класса от обычной функции вне классовой дискриминации? smile.gif
Область видимости чего-то и всё?

Сообщение отредактировал GetSmart - Mar 11 2010, 19:08


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Novichok1
сообщение Mar 12 2010, 04:49
Сообщение #30


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 8-07-09
Пользователь №: 51 032



Цитата(GetSmart @ Mar 11 2010, 22:02) *
А чем вообще отличается статическая функция класса от обычной функции вне классовой дискриминации? smile.gif
Область видимости чего-то и всё?


На сколько я знаю, да. Но согласитесь, это удобно, если функция логически связана с классом, и ей нужен доступ к приватным и защищенным методам и полям, тогда проще ее объявить статическим методом, чем делать дополнительные телодвижения с установкой дружественной функцией. Да и более логичен вызов этой функции извне через название класса, как мне кажется. То есть не будет путаницы, если у вас несколько функций с одинаковыми именами, но относящихся к разным классам.

А код я бы по другому сделал, например что-то типа:
Код
void OnIRQ // адрес этой функции будет записан в обработчик прерывания, должен быть атрибут (naked)
{
asm("пролог");

for(int i = 0; i < MAX_ISR_COUNT; i++)
{
      if(interrupt_handlers[i] != NULL)
      {
             interrupt_handlers[i]();
      }
}

asm("эпилог");
}


Ну правда возникает вопрос в надобности использования нескольких обработчиков на одно прерывание) Ну в принципе можно и без массива обработчиков, тогда будет вызываться просто указатель на один обработчик. Но в любом случае, мне не совсем понятна нужность вот этого кода:
Код
void MyIrq()
{
MyClassPtr->IrqHandler();  // функция класса, не статическая, статический указатель на экземпляр класса
}

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

Сообщение отредактировал Novichok1 - Mar 12 2010, 05:05
Go to the top of the page
 
+Quote Post

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

 


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


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