|
Обработчик прерываний |
|
|
|
Jan 16 2014, 19:18
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Цитата(_Артём_ @ Jan 16 2014, 23:00)  Для default-mcu? Это какие? Меня интересуют AVR. Но правила компилятора наверно одинаковые для разных контроллеров.
|
|
|
|
|
Jan 16 2014, 20:40
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(lexa12 @ Jan 16 2014, 21:18)  Меня интересуют AVR. Что-то типа такого (это не заработает точно - но принцип верный) Код ////какие-то ключевые слова
EXTERN A;или ?A
sts @A,R16; адрес может по-другому как-то задаётся Код volatile unsigned char A;
int main ()
{
while (A==0) {}
} И зачем вам это надо? Цитата(lexa12 @ Jan 16 2014, 21:18)  Но правила компилятора наверно одинаковые для разных контроллеров. Как выйдет - может разные, а может и нет.
|
|
|
|
|
Jan 24 2014, 01:33
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Цитата(kolobok0 @ Jan 18 2014, 00:59)  зафиксировать адресс внешней переменной. В языках выглядит как переменная с бОльшей областью видимости чем Ваш обработчик. Какие то странные способы Вы предлагаете. В ассемблере IBM PC например передача параметров может быть осуществлена либо через специальные регистры или через стек. Вроде в IAR можно использовать R16 для передачи однобайтовой переменной.
|
|
|
|
|
Jan 24 2014, 02:48
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(lexa12 @ Jan 16 2014, 20:34)  Добрый вечер! Помогите пожалуйста разобраться со следующим вопросом - как правильно написать обработчик прерывания на ассемблере с передачей параметров (переменной) в основную программу? Разве тут есть проблема? Используете память в качестве хранилища данных обычным образом. В обработчике прерывания записываете в эту память данные, а основная программа эти данные оттуда забирает или сразу использует. В тех случаях, когда может возникнуть накладка (в прерывании получаем новые данные прежде, чем основная программа успела воспользоваться старыми), то организуете (опять же в памяти) стек FIFO (первым пришел, первым вышел). Тогда в обработчике запихиваете данные в стек, а в основной программе забираете данные оттуда. Короче говоря, никакой особой специфики, вытекающей из работы с прерываниями, здесь нет, а имеет место типичный случай асинхронного обмена данными между двумя потоками.
|
|
|
|
|
Jan 24 2014, 06:36
|
Участник

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

|
Я всегда в EWAVR вот такой скелет использую. Только вектор прерывания меняю и тело переписываю. А когда в главной программе обращаюсь к переменной, используемой в прерывании, это прерывание временно запрещаю. Код //* Обработчик прерывания PCINT0 */ name EXT_PCINT0 #include "iom88pa.h" extern PCINT0_ISR common INTVEC(1) ; Code in interrupt vector segment org PCINT0_vect ; Place code at interrupt vector rjmp PCINT0_ISR ; Jump to assembler interrupt function endmod
name PCINT0_ISR #include "iom88pa.h" extern count; внешняя переменная public PCINT0_ISR
rseg CODE ; This code is relocatable, RSEG PCINT0_ISR: st -Y,R16 ; Push used registers on stack in R16,SREG ; Read status register st -Y,R16 ; Push Status register
lds R16,count inc R16 sts count,R16
ld R16,Y+ ; Pop status register out SREG,R16 ; Store status register ld R16,Y+ ; Pop Register R16 reti end
|
|
|
|
|
Feb 5 2014, 18:38
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Всем спасибо за ответы, все таки разобрался  Цитата(Xenia @ Jan 24 2014, 06:48)  Разве тут есть проблема? Используете память в качестве хранилища данных обычным образом. В обработчике прерывания записываете в эту память данные, а основная программа эти данные оттуда забирает или сразу использует.
В тех случаях, когда может возникнуть накладка (в прерывании получаем новые данные прежде, чем основная программа успела воспользоваться старыми), то организуете (опять же в памяти) стек FIFO (первым пришел, первым вышел). Тогда в обработчике запихиваете данные в стек, а в основной программе забираете данные оттуда.
Короче говоря, никакой особой специфики, вытекающей из работы с прерываниями, здесь нет, а имеет место типичный случай асинхронного обмена данными между двумя потоками. Просто я вспомнил, что модули подпрограмм на ассемблере и Си отдельно компилятся и потом объединяются линковщиком в один модуль, как в асме для PC. Технология передачи данных между подпрограммами, либо через стек или специальные регистры AX или DX:AX Цитата(kolobok0 @ Jan 24 2014, 14:11)  ну почему же либо? стэк(если писюк то это та же озу), регистры, озу(конкретный адресс), внешняя переферия. Стек и регистры понятно откуда известны, но откуда компилятор узнает адрес ОЗУ в другом модуле например? Не совсем очевидно, если вспомнить, что модули отдельно компилируются.
|
|
|
|
|
Feb 6 2014, 02:57
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(lexa12 @ Feb 6 2014, 00:38)  Стек и регистры понятно откуда известны, но откуда компилятор узнает адрес ОЗУ в другом модуле например? Не совсем очевидно, если вспомнить, что модули отдельно компилируются. Компилятор не узнаёт, узнаёт линкер. Компилятор при создании obj-файлов к ним цеплят таблицы экспорта/импорта для внешних ссылок. А линкёр потом, используя эти таблицы, связывает модули и подставляет реальные адреса. Либо не реальные адреса, а например, может формировать таблицу перемещений, по которой потом загрузчик подставит реальные адреса. Но этот вариант не для выполнения проги из флеш CPU определённо.
|
|
|
|
|
Feb 6 2014, 19:39
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(lexa12 @ Feb 5 2014, 22:38)  ...Стек...понятно откуда известны, но откуда компилятор узнает адрес ОЗУ в другом модуле например? ..модули отдельно компилируются. если Вам про стэк понятно, то откуда вопрос про ОЗУ?  Или по другому. Если стэк программный - то откуда Вы знаете что он тот же самый в "разных модулях"? Наверное соглашение между модулями. А кто, простите Вам запрещает зафиксировать ячейку данных по определённому адресу и свято соблюдать это в любых модулях программы?
|
|
|
|
|
Feb 7 2014, 17:12
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Цитата(kolobok0 @ Feb 6 2014, 23:39)  зафиксировать ячейку данных по определённому адресу каким образом, чтобы компилятор ее не использовал для своих целей? в этом собственно и вопрос, а то как Вы ответили - взять любой адрес со всеми вытекающими... например у меня в обработчике используется R16, можно ли его залочить и уже не сохранять в стеке при вызове обработчика для экономии времени?
|
|
|
|
|
Feb 7 2014, 18:26
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(lexa12 @ Feb 7 2014, 19:12)  например у меня в обработчике используется R16, можно ли его залочить и уже не сохранять в стеке при вызове обработчика для экономии времени? Нет, нельзя. Можно залочить регистры с R4 по R15. В свойствах проекта C/C++ compiler - Code - Number of registers to lock. Цитата(lexa12 @ Feb 7 2014, 19:12)  обработчика для экономии времени? Сколько вы там сэкономите? 10 тактов ? Возьмите МК по-быстрее (хоть xmega на 32 Mhz) или алгоритм пересмотрите. P.S. Оптимизацию включать пробовали?
|
|
|
|
|
Feb 7 2014, 21:42
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(lexa12 @ Feb 7 2014, 21:12)  ...чтобы компилятор ее не использовал для своих целей? ... т.е. у Вас возникают проблемы с написанием программы на ассемблере для обращения к фиксированному адресу, я прально понял? При этом у Вас настолько большая программа на азме(читай не управляемый из консерватории код) что Вы забыли какой адресс и как Вы юзаете, или как? Или у Вас задача состыковки с другими языками, и Вы не знаете как в них задётся привязка к конкретному адресу в памяти? Или, что Вы имеете ввиду? Я вот чётко, например, могу указать где будет таблица векторов, какой где конкретный(!) адресс. Я так понимаешь - для Вас это не посильная задача выходит... кхм... однако... Или Вы считаете, что команды привязки адресов служат только для формирования таблицы прерываний? чуствуете какие элементарные вещи мы тут с вами обсуждать собрались? на уровне прочитать документацию к применяемым языкам и архитектуры железа.
|
|
|
|
|
Feb 8 2014, 07:25
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Цитата(_Артём_ @ Feb 7 2014, 22:26)  P.S. Оптимизацию включать пробовали? Если обработчик написан на асме, зачем включать оптимизацию и что она даст? Цитата(kolobok0 @ Feb 8 2014, 01:42)  Или Вы считаете, что команды привязки адресов служат только для формирования таблицы прерываний? Вы используете странные понятия. Что в Вашем понимании "команды привязки адресов" ? Звучит как абракадабра. Если это какие то директивы или настройки компилятора, так и пишите. Цитата(kolobok0 @ Jan 24 2014, 14:11)  ну почему же либо? стэк(если писюк то это та же озу), регистры, озу(конкретный адресс), внешняя переферия. Мне вот это очень понравилось, для Вас переферия МК и "регистры" разные понятия
|
|
|
|
|
Feb 8 2014, 08:49
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Цитата(_Артём_ @ Feb 8 2014, 11:44)  Если на асме - ничего не даст. Попробуйте на Си написать с включённой оптимизацией. Может и не понадобится асм. Обработчик простейший - пара команд. Если убрать сохранение в стек при вызове, получится то что надо. Писать на Си с оптимизацией наверно будет тоже самое. Я думаю может как-нибудь проинициализировать переменную в основной программе как "regvar", но настораживает, что нельзя залочить регистр в компиляторе.
|
|
|
|
|
Feb 8 2014, 10:07
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Цитата(_Артём_ @ Feb 8 2014, 13:27)  Код __regvar __no_init unsigned short IntCounter @ 14; Как написано в руководстве по компилятору есть т.н. "Scratch registers" и "Preserved registers". А требуется как раз доступ к "Scratch register" недоступный __regvar. В этом то сейчас и вопрос как его залочить
|
|
|
|
|
Feb 8 2014, 13:39
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(lexa12 @ Feb 8 2014, 12:07)  В этом то сейчас и вопрос как его залочить  Компилятор предоставляет вам возможность золочить регистры R4-R15. Про другие регистры ничего не говорится. Цитата(lexa12 @ Feb 8 2014, 12:07)  А требуется как раз доступ к "Scratch register" Самые лучшие регистры он оставил себе. Цитата(lexa12 @ Feb 8 2014, 12:07)  есть т.н. "Scratch registers" и "Preserved registers". Это относится к соглашениям о вызовах функций. Резервирование регистров - вопрос отдельный.
|
|
|
|
|
Feb 9 2014, 22:33
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(lexa12 @ Feb 8 2014, 11:25)  ...Что в Вашем понимании... ...для Вас переферия МК и "регистры" разные понятия  Вы не ответили на поставленный вопрос. И пытаетесь уйти от проблем возникших у Вас. странно как то.. переферия это совокупность не только регистров но и некой обвязки выполняющей определённый функционал. Например ПДП, Или скажем АЦП. Теоретически - Вам никто не мешает сохранить (зная поведение данного узла) определённого размера данные. Надеюсь Вам стали понятны отличия?
|
|
|
|
|
Feb 10 2014, 08:24
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(_Артём_ @ Feb 9 2014, 21:01)  Хоть R14...запросто.... А что - что-то не так? Ну так напишите - что толку намёками говорить... А ничего что в R15 - программный счётчик? Ну если без R14 ещё как-то можно вообразить выполнение программы (без вызовов функций  , то без PC.... затрудняюсь... Или у вас тут AVR, а не ARM? Тогда - ФИ.....  ))
|
|
|
|
|
Feb 10 2014, 09:33
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(jcxz @ Feb 10 2014, 12:24)  А ничего что в R15 - программный счётчик? Это - ничего...мелочи. Цитата(jcxz @ Feb 10 2014, 12:24)  Ну если без R14 ещё как-то можно вообразить выполнение программы (без вызовов функций  , то без PC.... затрудняюсь... Быстро сдаётесь - а ведь могли бы сказать новое слово в науке и технике. Цитата(jcxz @ Feb 10 2014, 12:24)  Или у вас тут AVR, а не ARM? Тогда - ФИ.....  )) Ну да - мелко плаваем ...
|
|
|
|
|
Feb 10 2014, 19:04
|
Частый гость
 
Группа: Свой
Сообщений: 196
Регистрация: 6-10-10
Из: Санкт-Петербург
Пользователь №: 59 971

|
Цитата(kolobok0 @ Feb 10 2014, 02:33)  Вы не ответили на поставленный вопрос. И пытаетесь уйти от проблем возникших у Вас. странно как то..
переферия это совокупность не только регистров но и некой обвязки выполняющей определённый функционал. Например ПДП, Или скажем АЦП. Теоретически - Вам никто не мешает сохранить (зная поведение данного узла) определённого размера данные. Надеюсь Вам стали понятны отличия? Вы не поняли вопрос. Специально для Вас повторяю развернуто "как правильно написать обработчик прерывания на ассемблере с передачей параметров (переменной) в основную программу в IAR? " И на этот вопрос уже есть ответ (не Ваш, боюсь не поймете - используя директиву EXTERN). А Вы начинаете разводить какую то теорию. Если не знаете ответа, зачем отвечать? Насчет переферии, очевидно тот же АЦП для программиста это тот же самый регистр(или регистры), тем более в контексте обсуждаемой темы. Зачем Вы разделяете эти понятия известно только Вам
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|