Запрет прерывания

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 611
Зарегистрирован: Вс июн 08, 2008 14:26:20
Откуда: г. Астрахань

Сообщение Frensis »

Вот код с CodeVisioonAVR по обработке прерывания прихода символа в USART:

Код: Выделить всё

interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
};
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

так вот в курсе 123авр фрагмент
#asm("cli")
--rx_counter;
#asm("sei")

описан, но я его в корне не пойму....зачем и смысл останавлиать прерывания потом его заново запускать....непойму...


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

#asm("cli") // запретить прерывания глобально
--rx_counter; // вычесть 1 из rx_counter
#asm("sei") // разрешить прерывания глобально

Обратите внимание что перед декрементом мы запрещаем прерывания, а после прерывания включаем опять.

Зачем ? Вот фо ??? воскликнул бы англоязычный читатель ...

А затем, что в обработчике прерывания есть инкремент rx_counter - и если на декременте возникнет прерывание мы можем зациклится в этом месте программы и получить ошибку в числе символов в буфере.
....получается, что они останавливают прерывания только для того чтоб не помешать декременту....но а смысл если когда произойдет прерывание то по его окончанию все равно декремент выполнится, ведь прерывание не портит функции --rx_counter если выполняется в тот же момент
Контактная информация:
Реклама
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Сообщение nirq »

2. Очень внимательно приглядываемся к rx_counter, понимаем: что оно есть на самом деле и какие конкретно действия прячутся в надписи "--rx_counter".
1. В интернете читаем про слово "атомарность".

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

Простыню не читал, потому что не нужно.



Факультативно:
СпойлерКак выбираешь источники информации, на пользование которыми имеет смысл тратить своё время (вместо каких других)?

а). по знакомству дали ссылку;
б). в интернете первая или вторая ссылка по запросу;
в). чтобы русскими буквами и понятно (то есть попроще как-нибудь, "для идио чайников"... с яркими иллюстрациями и без многабукф);
г). чтобы без ошибок и правильно (а кто гарантирует);
д). чтобы было популярным, я в интернете самый умный особенный чтоле или как все обычный (~ вариант б);
е). официальные документы ищу одним или несколькими из перечисленных способов;
ё). официальные документы беру с сайта производителя;
ж). пишу на форумах;
з). читаю на форумах;
и). сначала пишу, потом читаю;
й). сначала читаю, потом пишу;
к). ...
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 611
Зарегистрирован: Вс июн 08, 2008 14:26:20
Откуда: г. Астрахань

Сообщение Frensis »

вопрос остается открытым
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Frensis, вам предельно ясно написали, что "--rx_counter"это не одна команда, а как минимум две. И таки да, ассемблер знать очень желательно, благо на AVR он прост, как валенок.
Так вот, если между этими двумя командами ворвётся прерывание, вы словите нехилый такой глюк, который ни повторить, ни отловить не удастся, т.к. при повторении прерывание может и не быть в этом месте. А по закону подлоти глюк этот будет в уже работающей железке, а не во время отладки.
Реклама
Эиком - электронные компоненты и радиодетали
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 330
Зарегистрирован: Чт июн 23, 2011 07:55:51

Сообщение korsaj »

А можно ссылку на первоисточник.
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Frensis, переменная rx_counter используется из двух мест - из основного кода и из прерывания. Поэтому переменная должна быть размещена в ОЗУ (volitile), а не в регистрах, как компиляторы Си, обычно, делают при оптимизации.
Как вы думаете сколько машинных команд надо для "--rx_counter". Да же если rx_counter однобайтовая, то команд будет 3. И предполагается, что во время выполнения этой последовательности команд содержимое ячейки памяти будет изменено только этой же самой последовательностью команд (а не из прерывания). А если переменная двухбайтовая, то прерывание может ещё и между операциями с байтами вклиниться. Понятно?

korsaj, http://www.123avr.com/
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 611
Зарегистрирован: Вс июн 08, 2008 14:26:20
Откуда: г. Астрахань

Сообщение Frensis »

ploop писал(а):Frensisесли между этими двумя командами ворвётся прерывание, вы словите нехилый такой глюк, который ни повторить, ни отловить не удастся, т.к. при повторении прерывание может и не быть в этом месте
Kavka писал(а):Frensis, переменная rx_counter используется из двух мест - из основного кода и из прерывания. Поэтому.......
......Понятно?
Да, спасибо, все ясно...
Контактная информация:
Ответить

Вернуться в «AVR»