|
|
  |
Interrupt i IAR |
|
|
|
Oct 21 2005, 10:46
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 4-11-04
Из: Болгария
Пользователь №: 1 050

|
Спосибо DXP. Тепер все стало более понятно. Но если ползоватся inline функции,компилер игнорирует inline. вот что получается. Код \ 00000000 938A ST -Y, R24 \ 00000002 93FA ST -Y, R31 \ 00000004 93EA ST -Y, R30 \ 00000006 923A ST -Y, R3 \ 00000008 922A ST -Y, R2 \ 0000000A 921A ST -Y, R1 \ 0000000C 920A ST -Y, R0 \ 0000000E 937A ST -Y, R23 \ 00000010 936A ST -Y, R22 \ 00000012 935A ST -Y, R21 \ 00000014 934A ST -Y, R20 \ 00000016 933A ST -Y, R19 \ 00000018 932A ST -Y, R18 \ 0000001A 931A ST -Y, R17 \ 0000001C 930A ST -Y, R16 \ 0000001E B78F IN R24, 0x3F 66 Trnasmit(); // !!!!!!!!!!!!!!!!!!! Ето inline функция \ 00000020 ........ CALL ??Trnasmit 67 } \ 00000024 BF8F OUT 0x3F, R24 \ 00000026 9109 LD R16, Y+ \ 00000028 9119 LD R17, Y+ \ 0000002A 9129 LD R18, Y+ \ 0000002C 9139 LD R19, Y+ \ 0000002E 9149 LD R20, Y+ \ 00000030 9159 LD R21, Y+ \ 00000032 9169 LD R22, Y+ \ 00000034 9179 LD R23, Y+ \ 00000036 9009 LD R0, Y+ \ 00000038 9019 LD R1, Y+ \ 0000003A 9029 LD R2, Y+ \ 0000003C 9039 LD R3, Y+ \ 0000003E 91E9 LD R30, Y+ \ 00000040 91F9 LD R31, Y+ \ 00000042 9189 LD R24, Y+ \ 00000044 9518 RETI Ест ли идея почему так получается?
|
|
|
|
|
Oct 21 2005, 12:25
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Nikola Kirov @ Oct 21 2005, 16:46) Спосибо DXP. Тепер все стало более понятно. Но если ползоватся inline функции,компилер игнорирует inline. вот что получается. Код \ 00000000 938A ST -Y, R24 \ 00000002 93FA ST -Y, R31 ............. \ 0000001C 930A ST -Y, R16 \ 0000001E B78F IN R24, 0x3F 66 Trnasmit(); // !!!!!!!!!!!!!!!!!!! Ето inline функция \ 00000020 ........ CALL ??Trnasmit 67 } \ 00000024 BF8F OUT 0x3F, R24 \ 00000026 9109 LD R16, Y+ ............. \ 00000042 9189 LD R24, Y+ \ 00000044 9518 RETI Ест ли идея почему так получается? Надо убедиться, что определение функции "Trnasmit()" видно в точке ее вызова. Если компилятор не видит в точке вызова тела функции, он, очевидно, не может ее встроить. Включите определение этой функции в заголовочный файл и подключите его к исходному, где Ваш ISR. Еще компилятор может умничать и подавлять встраивание - например, считать, что функция большая и ее встраивать нецелесообразно. Этот "интеллект" компилятора можно подавить с помощью #pragma inline=forced, размещенной перед прототипом или определением функции.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 21 2005, 15:03
|

инженер
   
Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701

|
Цитата(Nikola Kirov @ Oct 21 2005, 19:28) да ето с #pragma inline=forced помогло. но я должен переключат 8 разнъе функции на переключение уходит много время. Получается тоже как сделал сначала с помощи указателя. Должно имется какои то метод сделат на C бъстрее. В асме возможно,почему не может на C сделат. Принцип ясен нада все функции написат как функции перервания. В функция перервания которъе нада переключат при помочи указателя въизават необходимои функции.В самои функции прерервания ест толко переход к функции которъи указъивает указател и поетому не нада и регистръи сохранят. Необходимъие регистри будут правилно сохраненъи и возтоновленнъие в самои функции,потому что они написанъие как функции перервания. В логике работъи нечего сложное нет,вопрос как ето сделат в ИАР-е Nikola, если условия Вашей задачи переложить на Cи, то вот это нужно? Код interrupt IRQHandler() { void (*func[8])();
..... // по какому-то условию вызов требуемой функции (*func[i])(); .... } Спрашиваю пока, чтобы уяснить Вашу задачу.
|
|
|
|
|
Oct 21 2005, 15:51
|

инженер
   
Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701

|
Цитата(Nikola Kirov @ Oct 21 2005, 20:32) На проверки условия уходит много циклов. А нада бъистрее. Нада сделат как описал с указател к функции. Проблем как ето реализироват в ИАР Так я и спрашивала про формулировку задачи, а то текстом очень туманно. Может поправите мой текст на Си, чтобы понять Вашу задачу. А уж потом подумаем про быстродействие и что нужно указать дополнительно компилятору. К сожалению, я прощаюсь до завтра.
|
|
|
|
|
Oct 22 2005, 07:08
|

инженер
   
Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701

|
To Nikola. Вот эти условия Вашей задачи не совсем понятны: Цитата ...но я должен переключат 8 разнъе функции.... Цитата В функция перервания которъе нада переключат при помочи указателя въизават необходимои функции.В самои функции прерервания ест толко переход к функции которъи указъивает указател... В конце концов Вы можете переключение функции осуществлять с помощью библиотечной функции установки вектора прерываний. Если же таковой нету в IAR, то свою написать не сложно (в самом крайнем случае на ассемблере). В общем-то, эта функция должна делать это Код void setvect(int IRQ_num, __interrupt void (*IRQ_Handler)()) {unsigned long *p; //это указатель на адрес вектора прерываний *p=(unsigned long)IRQ_Handler; } К сожалению, я не знаю архитектуру и систему команд для Вашего контроллера. Это только идея, а с Вашей стороны должно быть творческое использование этой идеи применительно к архитектуре: на основе знаний как располагаются вектора прерываний и что они представляют собой - просто адреса подпрограмм обработки прерываний или JMP на подпрограмму (в последнем случае setvect незначительно усложнится). Посмотрите еще раз на предыдущие советы выше (нечто подобное уже посоветовали).
|
|
|
|
|
Oct 22 2005, 10:18
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 4-11-04
Из: Болгария
Пользователь №: 1 050

|
Спосибо Vic1 но тут вопрос относится к специфике IAR-а и AVR. Опят, должно получится ето,но проблем как ето реализироват Цитата Принцип ясен, нада все функции написат как функции перервания. В функция перервания которая нада переключат при помочи указателя въизават необходимои функции.В самои функции прерервания ест толко переход к функции которъи указъивает указател и поетому не нада и регистръи сохранят. Необходимъие регистри будут правилно сохраненъи и возтоновленнъие в самои функции,потому что они написанъие как функции перервания Возможно и неправилно обяснил по руски.Вот пример в коде Код #pragma vector = USART_TXC_vect __interrupt void TXCinterrupt() /// Так должно въиглядет само перервание { pActiv_TXinterrupt_Function(); /// ето указател к функции } А сами функции должно въиглядет так Код #pragma vector = XXXXXXXX_vect __interrupt Funct1() { ----------- } #pragma vector = XXXXXXXX_vect __interrupt Funct2() { ----------- } сам указател декларирован так Код void (__interrupt * pActiv_TXinterrupt_Function)(void); Нашел решение которъие работает. pActiv_TXinterrupt_Function въизъиваю из асме. для Funct1,Funct2 ползуюс из векторов перервании которъие не ползуется в програме. Но ето мне не нравится и не хватют свободнъие вектор прерервания
|
|
|
|
|
Oct 22 2005, 14:13
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 4-11-04
Из: Болгария
Пользователь №: 1 050

|
Цитата Вместо 16-разрядных опций сравнения указателя будут 8-и разрядные и т.д. protoss Възов функции через указател не приводит к никакие 16-разрядных опций сравнения. Вообще вопрос очен сложнъи и решение может дат толко человек кто очен глубоко понимает IAR. Опят скажу решение которое нашел работает,не сохраняет излишнее регистри,не теряет время на пререключения задач. Если у вас мало задач ,можно восползоватся из него. Всегда ест свободнъие векторъи перервания. Проблем что нада функции писат как перервания и ползаватся из свободнъие векторъи а у меня задач много и не хватают. А и должно ест метод каторъи сделает все так и без използования свободнъих векторов и асмовъие вставки.
|
|
|
|
|
Oct 22 2005, 17:28
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(Nikola Kirov @ Oct 22 2005, 22:13) Цитата Вместо 16-разрядных опций сравнения указателя будут 8-и разрядные и т.д. А и должно ест метод каторъи сделает все так и без използования свободнъих векторов и асмовъие вставки. Могу предложить тебе один метод. Как всегда это только мысль, которую, скорее всего ты сможешь развить. Не буду писать на полнстью ASM, а напишу как алгоритм. И так: 1. Входим в прерывание (выполняем какие то действия) 2. Вычисляем адрес нужной нам функции 3. Загружаем в стек адрес перехода (например командой PUSH) 4. Выходим из прерывания. Правда, здесь необходимо, иметь ввиду некоторые ньюансы. Во первых писать вектор придется на ASM, т.к не вижу, как и где в Си вставить оператор asm("PUSH (HI)ptr"); asm ("PUSH (LO(ptr)"), да так, чтоб после него шла команда RETI. Во вторых во время работы исполняемой после прерывания функции будут возникать другие разрешенные прерывание, в том числе и то, которое эту функцию вызвало, так что время выполнения функции ограничено минимальным периодом возникающего прерывания. В третьих, нужно отслеживать,какие регистры сохранять в функции, потому как эту функцию компилятор за прерывание (и за вызываемую в прерывании) считать не будет, соответственно не будет сохранять все задействованные в функции регистры, а только те, которые он посчитает нужными сохранить. Вот такой расклад. Может быть все написанное выше, полный бред. Не судите сильно строго, это пришло мне в голову после сна :-) но до выполнения зарядки.
--------------------
|
|
|
|
|
Oct 22 2005, 17:58
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 4-11-04
Из: Болгария
Пользователь №: 1 050

|
Цитата Может быть все написанное выше, полный бред. Не судите сильно строго, это пришло мне в голову после сна :-) но до выполнения зарядки. Да так. Если не сложно не мешаи в ету тему.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|