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

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


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(sonycman @ Jan 26 2009, 14:38) *
Код
do

{


ATOMIC_BLOCK(ATOMIC_RESTORESTATE) new_value = sys_tick;
}

while ((new_value - old_value) < mksec);


Пусть sys_tick volatile, проехали предыдущий вопрос. Если мы говорим конкретно об AVR, то дороговатая операция получается. Я бы для такого случая завел бы какой-нить байтовый кеш таймерок. Тогда не надо атомарного доступа.
Портируемость AVR->ARM стремится к нулю sad.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 26 2009, 13:24
Сообщение #32


Гуру
******

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



Цитата(_Pasha @ Jan 26 2009, 13:55) *
Портируемость AVR->ARM стремится к нулю sad.gif
Сделать для чтения переменной встраиваемую функцию-обертку, которая и будет портируемой. В варианте для AVR считывать sys_tick в цикле и сравнивать с предыдущим значением. Если старший(старшие) байты двух чтений совпали - возвращать результат. Для ARM и переменной размером меньше 32 бит - просто считывать и возвращать результат.


--------------------
На любой вопрос даю любой ответ
"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 26 2009, 14:02
Сообщение #33


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

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



Цитата(_Pasha @ Jan 26 2009, 15:55) *
Пусть sys_tick volatile, проехали предыдущий вопрос. Если мы говорим конкретно об AVR, то дороговатая операция получается. Я бы для такого случая завел бы какой-нить байтовый кеш таймерок. Тогда не надо атомарного доступа.

Тогда страдает или разрешение таймера, или величина макс. выдержки.
На AVR приходилось делать на двух байтах.
На ARM вообще без проблем smile.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 26 2009, 14:40
Сообщение #34


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(sonycman @ Jan 26 2009, 18:02) *
Тогда страдает или разрешение таймера, или величина макс. выдержки.


Я применял это там, где тик был медленный = 1мс. В таких условиях в мониторе событий крутился опрос "быстрого" однобайтового таймера  и этот тик (в предельном случае-вместе с вызовом обработчика) генерился там же. Т.е. преследовались цели: разгрузить прерывание, минимизировать джиттер прерывания от таймера из-за частых запретов/разрешений, разделить быстрые и медленные процессы. Понятно, что на  ARM "мельчить" объектами меньше чем 32 бита не только не полезно, но и вредно. И никаких извратов там не надо.
И, следуя вполне нормальному желанию портировать код, завел тип timer_t - размерностью какой надо в конкретном случае. Извиняюсь если написал много банальщины.

Цитата(Сергей Борщ @ Jan 26 2009, 17:24) *
В варианте для AVR считывать sys_tick в цикле и сравнивать с предыдущим значением.

По остальным тезисам - согласен, а тут - слишком искусственная ситуация, ибо такие циклы встречаются довольно редко. Согласитесь, чаще встречается  конструкция типа 

Код
void action (void)

{
static timer_t local_timer =0;
timer_t tmp;
tmp = get_tick();
if ((local_timer - tmp) < My_Time_To_DO) return;
local_timer = tmp;
Do_Be_Do_Be_Do();

**********

return;
}
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 26 2009, 15:20
Сообщение #35


Гуру
******

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



Цитата(_Pasha @ Jan 26 2009, 16:40) *
Согласитесь, чаще встречается  конструкция типа 
Да. Так вот
Код
timer_t get_tick()
{
    timer_t Tmp1 = sys_tick;
    timer_t Tmp2 = sys_tick;
    while((Tmp2 >> 8) != (Tmp1 >> 8))
    {
       Tmp1 = Tmp2;
       Tmp2 = sys_tick
    }
    return Tmp2;
}


--------------------
На любой вопрос даю любой ответ
"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
_Pasha
сообщение Jan 26 2009, 15:40
Сообщение #36


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Сергей Борщ @ Jan 26 2009, 18:20) *
timer_t get_tick()
Спасибо, понял. 
Go to the top of the page
 
+Quote Post
777777
сообщение Jan 26 2009, 17:45
Сообщение #37


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Сергей Борщ @ Jan 26 2009, 11:20) *
Вообще-то это требуется всегда, когда переменная изменяется неизвестным компилятору образом, например в прерывании, другом потоке или аппаратно отражает состояние внешних по отношению к ядру устройств.

А также если глобальная переменная используется в нескольких функциях. Транслируя каждую функцию по отдельности, компилятор не знает, как изменяется такая переменная. Однако вы же не делаете ее volatile. Такое объявление приводит лишь к тому, что если например она используется в функции дважды, то ее значение будет считываться из памяти каждый раз, а при отсутствии volatile (и наличии оптимизатора) - только раз.
Цитата(Сергей Борщ @ Jan 26 2009, 11:20) *
Зато _вы_ можете сделать предположение за компилятор. cranky.gif . Может он. Чтобы не мог - существует volatile. Если в конкретном случае без volatile вдруг не сделал, то при малейшем изменении исходника или версии компилятора сможет сделать и вот вам граблями в лоб - получите.

Ну например, в прерывании таймера инкрементируется некая переменная, а в прерывании какого-нибудь передатчика ее значение куда-то передается. Что может знать компилятор о ее содержимом? И "малейшего" изменения исходников (а тем более версии компилятора) недостаточно для изменения ее поведения. Нужно "существенное" изменение, например, если мы попытаемся ввести какую-нибудь паузу, как написал ниже sonycman - но паузы и задержки это и есть то, для чего придуман volatile. Но с другой стороны, введение задержек в микропроцессорной системе таким способом - явный признак дурного стиля, это снижает производительность системы. Для задержек как раз и существуют таймеры.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 26 2009, 18:56
Сообщение #38


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

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



Цитата(777777 @ Jan 26 2009, 21:45) *
Но с другой стороны, введение задержек в микропроцессорной системе таким способом - явный признак дурного стиля, это снижает производительность системы. Для задержек как раз и существуют таймеры.

Это был просто пример.
Естественно в реальной системе мёртво стопорить процессор при ожидании глупо.
Хотя иногда и необходимо, и такие функции существуют.

Но вернёмся к теме - вы всё же считаете, что volatile не обязателен для случая с инкрементом счётчика в ISR и чтения его в основной программе?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 26 2009, 19:18
Сообщение #39


Гуру
******

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



Цитата(777777 @ Jan 26 2009, 19:45) *
А также если глобальная переменная используется в нескольких функциях. Транслируя каждую функцию по отдельности, компилятор не знает, как изменяется такая переменная.
Знает. Почитайте что такое точки последовательности, побочные эффекты. Функция исполняется от начала и до конца. Одна. Компилятор ничего не знает ни о прерываниях, ни о многопоточности. Задача прерывания - обеспечить неизменность состояния среды исполнения (state of the execution environment). Все, что изменяет это состояние является побочными эффектами (side-effects). Одним из побочных эффектов является обращение к volatile-переменной. Прочтите стандарт, чтобы не писать глупости.

И компилятор имеет право встроить функцию. Так что "Транслируя каждую функцию по отдельности" бывает далеко не всегда.


--------------------
На любой вопрос даю любой ответ
"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

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

 


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


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