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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Обычная переменная для ISR и volatile для всех остальных, как лучше реализовать?
sonycman
сообщение Jan 24 2009, 15:32
Сообщение #1


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Что-то вот задумался над одной мелочью, в принципе.
Есть переменная таймера, которая объявлена как volatile, так как модифицируется в обработчике прерывания.

Всё бы хорошо, да только хотелось бы, чтобы эта переменная была volatile для всех, кроме самого обработчика прерываний, так как лишние сохранения/загрузки в нём - это совершенно лишнее. smile.gif

Есть мысля сделать так:
Код
union {
dword isr_timer;
volatile dword timer;
}

и в ISR юзать isr_timer, а в других местах - просто timer.

Что скажете?
Go to the top of the page
 
+Quote Post
kimstik
сообщение Jan 24 2009, 16:43
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 46
Регистрация: 4-02-05
Из: Москва
Пользователь №: 2 430



ISR сделай в отдельном файле и используй как
dword timer;

а в основном объяви как
extern volatile dword timer;

Сообщение отредактировал kimstik - Jan 24 2009, 16:54
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 24 2009, 17:47
Сообщение #3


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(kimstik @ Jan 24 2009, 20:43) *
ISR сделай в отдельном файле и используй как
dword timer;

а в основном объяви как
extern volatile dword timer;

Спасибо!
Работает smile.gif

А я почему-то подумал, что extern должен быть с точно таким-же типом, что и оригинальная переменная... 01.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2009, 18:33
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(sonycman @ Jan 24 2009, 17:32) *
Что скажете?
Заведите внутри обработчика прерывания локальную переменную, считайте в нее timer и работайте дальше с ней. В конце, если надо, сохраните локальную переменную обратно в timer. Зачем какие-то велосипеды с выносом в другой файл?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 24 2009, 18:55
Сообщение #5


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



А я вот чего-то совсем не припоминаю из стандарта почему исходный вариант неправильный ?
ИМХО, вполне себе подходит с union.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 24 2009, 19:04
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sonycman @ Jan 24 2009, 18:32) *
Что скажете?

Хорошо.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2009, 19:39
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(singlskv @ Jan 24 2009, 20:55) *
А я вот чего-то совсем не припоминаю из стандарта почему исходный вариант неправильный ?
Он не неправильный. Он несколько... некрасивый. Как вы организуете доступ к этому безымянному unionу из другого файла? Вы вынесете его в заголовочный файл с extern, и при этом сделаете видимым не-volatile пременную. Никакой гарантии, что случайно не используете эту переменную вне прерывания. Если есть возможность железно ограничить область видимости не-volatile переменной обработчиком прерывания, сделав ее локальной - почему не использовать ее?

Цитата(sonycman @ Jan 24 2009, 19:47) *
А я почему-то подумал, что extern должен быть с точно таким-же типом, что и оригинальная переменная...
Думаю, что он может накладывать дополнительные ограничения (volatile, const) на переменную, но не снимать их. Искать в стандарте лень, никогда не использовал такой финт.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 24 2009, 19:51
Сообщение #8


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(Сергей Борщ @ Jan 24 2009, 22:33) *
Заведите внутри обработчика прерывания локальную переменную, считайте в нее timer и работайте дальше с ней. В конце, если надо, сохраните локальную переменную обратно в timer. Зачем какие-то велосипеды с выносом в другой файл?

Этот счётчик необходим для класса таймеров рассредоточенных по всему проекту.
Поэтому его вынос обязателен.

Последовал совету kimstik.
Накладывание доп. ограничений (volatile) на внешнюю переменную для внутренних нужд - это прикольно cheers.gif
Можно ещё и const добавить для подстраховки...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 24 2009, 19:53
Сообщение #9


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Сергей Борщ @ Jan 24 2009, 22:39) *
Он не неправильный. Он несколько... некрасивый. Как вы организуете доступ к этому безымянному unionу из другого файла? Вы вынесете его в заголовочный файл с extern, и при этом сделаете видимым не-volatile пременную. Никакой гарантии, что случайно не используете эту переменную вне прерывания. Если есть возможность железно ограничить область видимости не-volatile переменной обработчиком прерывания, сделав ее локальной - почему не использовать ее?

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

А сам бы я тоже локальную просто завел... чисто по привычке.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 24 2009, 19:55
Сообщение #10


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(singlskv @ Jan 24 2009, 23:53) *
Безымянный глобальный union это вообще не хорошо, компилятор должен варнинг давать, поэтому конечно нужно дать имя ему.

Компилер заставил поставить static. А имя - зачем оно? Лишняя писанина только...
Объединение не должно быть в области видимости снаружи. Оно только для нужд прерывания.
А снаружи - только volatile dword...

Да ладно, это не актуально более smile.gif
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 24 2009, 20:39
Сообщение #11


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(sonycman @ Jan 24 2009, 19:47) *
А я почему-то подумал, что extern должен быть с точно таким-же типом, что и оригинальная переменная... 01.gif
Ну вообще говоря "желательно".
Прокатить такое может только если в файл с обработчиком ISR не включать тот h-файл, в котором объявлено переменную для остальных - я же предпочитаю объявлеия включать везде для проверки (если вдруг поменяю в .h uint16_t на uint32_t, а в .c забуду - компилятор выругатся.
Но тогда
vv.h
Код
extern volatile unsigned u;

vv.c
Код
#include <vv.h>
unsigned u;

Компиляция:
Код
vv.c:2: error: conflicting type qualifiers for 'u'
./vv.h:1: error: previous declaration of 'u' was here


Я как правило кеширую переменную в обработчике прерывания во веменную и сохраняю при выходе.

Можно и так, набросал вот wink.gif
Код
template <typename T, volatile T& var>
class cache_volatile
{
public:
    cache_volatile() : t(var) {}
    ~cache_volatile() { var = t; }

    T t;
};

volatile uint8_t timer;

ISR(TIMER0_OVF_vect)
{
    cache_volatile<uint8_t, timer> tim;
    if( --tim.t == 0 ) {
        tim.t = 127;
    }
    
    if( PINB & 0x02) return; // тут тоже запишется назад изменённое значение
    
    if( tim.t & 0x01 ) PINB |= 0x01;
}


Код
__vector_9:
    push __zero_reg__
    push __tmp_reg__
    in __tmp_reg__,__SREG__
    push __tmp_reg__
    clr __zero_reg__
    push r24

    lds r24,timer
    subi r24,lo8(-(-1))
    brne .L2
    ldi r24,lo8(127)
.L2:
    sbic 54-0x20,1
    rjmp .L4
    sbrc r24,0
    sbi 54-0x20,0
.L4:
    sts timer,r24

    pop r24
    pop __tmp_reg__
    out __SREG__,__tmp_reg__
    pop __tmp_reg__
    pop __zero_reg__
    reti


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 24 2009, 22:12
Сообщение #12


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Хм, спасибо!
Если будут проблемы с extern, то придётся именно так и поступать.
Эх, пора мне, наверное, шаблоны поизучать - а то аж искры из глаз, пока силился понять, что там вы с ними "замутили" laughing.gif
Можно, конечно, и без них обойтись...
Go to the top of the page
 
+Quote Post
kimstik
сообщение Jan 25 2009, 11:43
Сообщение #13


Участник
*

Группа: Свой
Сообщений: 46
Регистрация: 4-02-05
Из: Москва
Пользователь №: 2 430



Я стараюсь union реже использовать - это одна из самых непереносимых и компилерозависимых вещей.
Не все компилеры понимают безымяный union. Длинные бестолковые имена. Куча не всегда понятных переменных.
А то что в хедер для проверки не вставить объявления - это цена вопроса.
Вы же сами просили решения(хака)? Значит вам за него и отвечать. smile.gif
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 25 2009, 12:42
Сообщение #14


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(kimstik @ Jan 25 2009, 15:43) *
Я стараюсь union реже использовать - это одна из самых непереносимых и компилерозависимых вещей.
Не все компилеры понимают безымяный union. Длинные бестолковые имена. Куча не всегда понятных переменных.

Согласен со всем.

Позволю себе усомниться, разве что, что не все компиляторы понимают безымянное объединение.
И какие, например, компиляторы С++ не соответствуют стандарту?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 25 2009, 13:21
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(kimstik @ Jan 25 2009, 14:43) *
Длинные бестолковые имена. Куча не всегда понятных переменных.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:15
Рейтинг@Mail.ru


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