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

 
 
> Две таблицы векторов в одном софте, xmega
xelax
сообщение Apr 20 2011, 08:58
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Привет всем!

Тут некоторых коллег посетила нездоровая идея иметь два вектора прерывания на одну периферию (NVM eeprom и flash).
Одна таблица в application другая в bootloader секции. И всё это должно жить в одной программе. В возможности иметь две таблице векторов прерывания для xmegа я не вижу никаких технических препятствий, то как это реализовать в одном софте средствами компилятора и линкера пока не понимаю. Не могу же я иметь две функции
Код
ISR(NVM_EE_vect)


Пока не вижу другого способа кроме как для application секции формировать таблицу посредством макросов ISR, а для bootloader формировать её в рукопашную, размещая jmp на обработчики по фиксированным адресам из bootloader и добавляя в функции обработки рукописные прологи и эпилоги.

Но уж очень этот вариант на камасутру похож. Может кто-то знает более красивые варианты решения?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
xelax
сообщение Apr 20 2011, 09:19
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Так камни с ядром avr имеют гарвардскую архитектуру и умеют исполнять код только из FLASH области, к сожалению это не cortex crying.gif .
Go to the top of the page
 
+Quote Post
defunct
сообщение May 19 2011, 15:32
Сообщение #3


кекс
******

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



Цитата(xelax @ Apr 20 2011, 12:19) *
Так камни с ядром avr имеют гарвардскую архитектуру и умеют исполнять код только из FLASH области, к сожалению это не cortex crying.gif .

И что с того?
В ОЗУ для каждого вектора пусть лежит адрес обработчика, а по реальному вектору прерывания во флеш пусть лежит буквально следующий код:
Код
lds zh, high( vector_i )
lds zl, low( vector_i)
ijmp

Где vector_i - переменная в ОЗУ.

Если с асмом туго, переместите все вектора в область бутлоадера, и состряпайте Сишные wrapper'ы:

Код
ISR( vect_xxx)
{
     if (handlers[ vect_xxx ])
         handlers[ vect_xxx ]();
}


где "handlers" массив в ОЗУ, где каждый элемент - адрес обработчика.

Цитата(V_G @ May 11 2011, 16:04) *
Но не думаю, что IAR C умеет ее использовать для целей, потребных топикстартеру.
Все-таки 2 отдельных проекта реальнее, чем так извращаться на Си

Toolchain от IAR включает еще и транслятор Asm'а. Создаете .s файл, пишете в нем код таблицы векторов, и линкером кладете в секцию таблицы векторов вот и всего делов.


Цитата(vvppvv @ May 13 2011, 16:00) *
__interrupt __raw void irqUSART0_RXC (void)
{
interrupt_entry ();
(* Ufunc_ptr)();
interrupt_exit ();
}

Не вижу смысла в ручных entry / exit.
Надо просто тупо вызвать функцию.
Go to the top of the page
 
+Quote Post
vvppvv
сообщение May 31 2011, 18:14
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 3-07-05
Пользователь №: 6 485



Цитата
Не вижу смысла в ручных entry / exit.
Надо просто тупо вызвать функцию.


Тупо можно на этапе изучения контроллера, системы команд и написания первых "Hello, World". Дальше "тупо" - не надо. У меня перед объявлением программ прерываний стоИт __raw. Это совсем не просто так. Оптимизатор IAR спотыкается о косвенный взов, и начинает, как Вы говорите, "тупо" сохранять все регистры. Поэтому были составлены специальные inline-функции interrupt_entry (); и interrupt_exit (); Просто я выдрал пример из конкретного проекта, и немного его "не очистил" от лишнего, не относящегося к теме wink.gif)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 2 2011, 00:38
Сообщение #5


кекс
******

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



Цитата(vvppvv @ May 31 2011, 21:14) *
У меня перед объявлением программ прерываний стоИт __raw.

Как тут на форуме кто-то сказал - "в японии проходит ежегодный конкурс на самое сложное решение простой задачи, может быть вам стоит отправить туда и свое решение?" )
Особый интерес наверняка проявят к программке-доработке компилятора, для анализа используемых регистров в подменяемых функциях. )

Цитата
как Вы говорите, "тупо" сохранять все регистры.

Отлично, и пусть сохраняет. Обеспечивается максимальная гибкость - там где требуется гибкость, там нет требований к скорости исполнения, потому что это взаимоисключающие вещи.

Цитата
У меня перед объявлением программ прерываний стоИт __raw. Поэтому были составлены специальные inline-функции interrupt_entry (); и interrupt_exit ();

Вопрос в том насколько легко подцепить туда любую другую функцию после этого - тобиш вопрос поддержки проекта и расширения функционала.
Гораздо проще объявить __interrupt без __raw, и без ручных пролога и эпилога, тогда он сохранит все регистры из-за используемого внутри косвенного вызова, а саму, вызываемую косвенно, функцию обьявить с __raw.

Цитата
Тупо можно на этапе изучения контроллера, системы команд и написания первых "Hello, World". Дальше "тупо" - не надо.

Именно так - тупо - и используется в наиболее серьезных проектах. В больших и сложных проектах - простота реализации - залог успеха. Минимизировать нужно число IRQ где возможно - если можно обрабатывать сразу несколько прерываний от нескольких источников. Не нужно доводить до абсурда задачу минимизации кода отдельно взятого обработчика с подсчетом используемых регистров в каждой функции взависимости от сборки компилятора и ключа оптимизации (что наверняка вы со своим ручным прологом и делаете).

Бывают и другие цели, для их достижения приходится жертвовать гибкостью, - в этом случае лучше просто использовать по максимуму возможности конкретной архитектуры и используемого инструментария. В контексте IAR под AVR это - вообще не вызывать никаких функций из обработчика прерываний, и иметь всегда строго один обработчик на одно прерывание. Еще лучше возможно будет писать весь проект на ASM, но это подходит только для задач по сложности типа контроллера светодиода.
Go to the top of the page
 
+Quote Post
vvppvv
сообщение Jun 5 2011, 10:22
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 3-07-05
Пользователь №: 6 485



Цитата
Вопрос в том насколько легко подцепить туда любую другую функцию после этого - тобиш вопрос поддержки проекта и расширения функционала.


Ответ - подцепить нелегко. Но в данном конкретном месте проекта вопрос про "любые другие функции" не стоял. Там была задача достичь максимального быстродействия этого, конкретного, специфического куска кода. Грубо говоря, написать его на ассемблере. Что позволило с меги128 вытянуть пол-мегабитный проприетарный протокол, вместо 128кБит, когда "обеспечивается универсальность и хорошая переносимость кода".

Цитата
Гораздо проще объявить __interrupt без __raw, и без ручных пролога и эпилога,


Разумеется. Это и делается в 99% случаев.

Цитата
тогда он сохранит все регистры из-за используемого внутри косвенного вызова,


Да, именно так. Причем сохранять будет в памяти, используя обычный "сишный" стек. А мой "ручной" пролог-эпилог использует команды MOVW, копирования слов (пар регистров), это самый быстрый способ сохранения-восстановления регистров в системе команд AVR.

Цитата
а саму, вызываемую косвенно, функцию обьявить с __raw.


А это зачем? sm.gif
Рав нужен только для прерываний. Вот, выдержка из мануала:
"This keyword prevents saving used registers in interrupt functions.
Interrupt functions preserve the contents of all used processor registers at function
entrance and restore them at exit. However, for some very special applications, it can be
desirable to prevent the registers from being saved at function entrance. This can be
accomplished by the use of the keyword __raw."

Вот у меня как раз пример был из "very special applications".

Цитата
Бывают и другие цели, для их достижения приходится жертвовать гибкостью, - в этом случае лучше просто использовать по максимуму возможности конкретной архитектуры и используемого инструментария.


Совершенно верно! Что я и сделал.

Цитата
В контексте IAR под AVR это - вообще не вызывать никаких функций из обработчика прерываний, и иметь всегда строго один обработчик на одно прерывание.


Не пойдет. Не бывает универсальных правильных решений. Тогда мне бы пришлось семафорить, развешивать флажки, статусы и пр. В итоге - раздутость кода и потеря производительности и потребительских свойств проектируемой железки.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 27th June 2025 - 06:53
Рейтинг@Mail.ru


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