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

 
 
 
Reply to this topicStart new topic
> Как обойти глюки оптимизации, или мои глюки ...
Serg_el
сообщение Dec 22 2008, 13:25
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 302
Регистрация: 13-12-06
Из: Togliatti
Пользователь №: 23 473



Есть некая глобальная переменная, которая является счетчиком и инкриминируется в процедуре обработки прерывания таймера. Есть функция выдержки времени, в которой используется эта переменная. Перед функцией я обнуляю переменную-счетчик и жду пока таймер не отсчитает необходимое количество времени, после этого выхожу из функции задержки. Проблема в том, что при включении оптимизации компилятор выкидывает строку обнуления, т.е. (я так понимаю) он не видит, что она меняется в таймере и считает строку обнуления лишней! Как это можно обойти? Вместо обнуления пробовал считывать текущее значение таймера и прибавлять к нему требуемую задержку и далее эту величину подставлять в условие, но там похожая ситуация.



void delay(unsigned int time)
{
while (timer < time);
{
}
}


#pragma vector=TIMERA0_VECTOR
__interrupt void TIMERA0_INT( void )
{
timer++;
}




void function(void)
{
timer = 0;
delay(2200);
}
Go to the top of the page
 
+Quote Post
bloodden
сообщение Dec 22 2008, 13:32
Сообщение #2


Бывалый
***

Группа: Validating
Сообщений: 375
Регистрация: 19-10-05
Из: Kiev, UA
Пользователь №: 9 853



При объявлении переменной напишите volatile int timer


--------------------
Заходите кому надо на мой сайт
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 22 2008, 13:32
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



volatile int timer;
А ещё обеспечивать атомарное обращение к этой переменной (если, конечно, она занимает более одного байта).

Сообщение отредактировал forever failure - Dec 22 2008, 13:35
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Dec 22 2008, 13:41
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(forever failure @ Dec 22 2008, 17:32) *
А ещё обеспечивать атомарное обращение к этой переменной

Ручками : запретить прерывания, разрешить прерывания.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Serg_el
сообщение Dec 22 2008, 13:46
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 302
Регистрация: 13-12-06
Из: Togliatti
Пользователь №: 23 473



А что такое атомарное и причем здесь прерывания?
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 22 2008, 13:54
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



Это означает, что если переменная, допустим, типа int, и она проверяется в основной программе, в момент проверки, после сравнения, допустим старшего байта происходит прерываие таймера и изменяет эту переменную. В результате в операции сравнения сравнивается старший байт от старого значения, а младший - от нового.
Вот такой получается косячок-с. Для того, чтоб такого не происходило, на время обращения к этой переменной прерывания надо запретить, а потом опять восстановить. (Или одно, конкретное прерывание, которое обновляет переменную).

Сообщение отредактировал forever failure - Dec 22 2008, 13:54
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 22 2008, 13:57
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Serg_el @ Dec 22 2008, 16:46) *
А что такое атомарное и причем здесь прерывания?

При всём уважении, но Вам надо в форум для начинающих. Эта проблема стара как мир, и компилятор IAR тут ни при чём. Зачем снова отвечать на одни и те же вопросы? Используйте поиск...
Go to the top of the page
 
+Quote Post
Serg_el
сообщение Dec 22 2008, 13:58
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 302
Регистрация: 13-12-06
Из: Togliatti
Пользователь №: 23 473



Спасибо. Буду пробовать
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 22 2008, 14:06
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(forever failure @ Dec 22 2008, 16:54) *
Вот такой получается косячок-с. Для того, чтоб такого не происходило, на время обращения к этой переменной прерывания надо запретить, а потом опять восстановить. (Или одно, конкретное прерывание, которое обновляет переменную).

Есть ещё один способ. Считать переменную 2 раза и сравнить старший байт для двух считываний. Если не изменился - всё ОК, иначе - повторить. Есть свои минусы, но зато прерывание не запрещаем.
Go to the top of the page
 
+Quote Post
Serg_el
сообщение Dec 23 2008, 15:19
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 302
Регистрация: 13-12-06
Из: Togliatti
Пользователь №: 23 473



Вот еще один прикол. Прописываю константу limit по фиксированному адресу и присваиваю ей значение.

const unsigned int limit @ 0xE1FE = 29;

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

Константа используется для значения, программируемого извне. А значение 29 присваивал для отладки и пока не закомментил, не хотел компилятор использовать limit.
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Dec 23 2008, 15:42
Сообщение #11


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(Serg_el @ Dec 23 2008, 17:19) *
Вот еще один прикол. Прописываю константу limit по фиксированному адресу и присваиваю ей значение.

const unsigned int limit @ 0xE1FE = 29;

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

Константа используется для значения, программируемого извне. А значение 29 присваивал для отладки и пока не закомментил, не хотел компилятор использовать limit.

Добавьте __root.
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 23 2008, 16:06
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Эта тема напоминает торный путь из граблей, по которому ходят все вновьприбывшие. biggrin.gif И каждый вновьприбывший удивляется тому факту, что дорога вроде давно протоптана, а грабли все еще лежат там же wink.gif
Про volatile надо писать в FAQ крупными буквами. А по поводу оптимизации обращения к константе, расположенной по фиксированному адресу, я сам недавно писал и там же указал решение/обходной путь.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Dec 25 2008, 15:13
Сообщение #13


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

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



Цитата(scifi @ Dec 22 2008, 18:06) *
Есть ещё один способ. Считать переменную 2 раза и сравнить старший байт для двух считываний. Если не изменился - всё ОК, иначе - повторить. Есть свои минусы, но зато прерывание не запрещаем.

Может наоборот, сравнивать младшие байты? А то ведь старшие могут быть равны, а младший отличаться.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 25 2008, 15:32
Сообщение #14


Гуру
******

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



Цитата(sonycman @ Dec 25 2008, 17:13) *
Может наоборот, сравнивать младшие байты? А то ведь старшие могут быть равны, а младший отличаться.
При этом результат каждого чтения будет содержать корректное на момент чтения значение пары младшего и старшего байтов. Поскольку прерывание с точки зрения программы атомарно. Т.е. не может сначала изменить младший байт с 0xFF на 0x00, потом дать немного поработать программе и только потом увеличить на 1 старший байт.


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

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 00:07
Рейтинг@Mail.ru


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