|
Обработчик прерываний |
|
|
|
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)  ...чтобы компилятор ее не использовал для своих целей? ... т.е. у Вас возникают проблемы с написанием программы на ассемблере для обращения к фиксированному адресу, я прально понял? При этом у Вас настолько большая программа на азме(читай не управляемый из консерватории код) что Вы забыли какой адресс и как Вы юзаете, или как? Или у Вас задача состыковки с другими языками, и Вы не знаете как в них задётся привязка к конкретному адресу в памяти? Или, что Вы имеете ввиду? Я вот чётко, например, могу указать где будет таблица векторов, какой где конкретный(!) адресс. Я так понимаешь - для Вас это не посильная задача выходит... кхм... однако... Или Вы считаете, что команды привязки адресов служат только для формирования таблицы прерываний? чуствуете какие элементарные вещи мы тут с вами обсуждать собрались? на уровне прочитать документацию к применяемым языкам и архитектуры железа.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|