Serg_el 0 22 декабря, 2008 Опубликовано 22 декабря, 2008 · Жалоба Есть некая глобальная переменная, которая является счетчиком и инкриминируется в процедуре обработки прерывания таймера. Есть функция выдержки времени, в которой используется эта переменная. Перед функцией я обнуляю переменную-счетчик и жду пока таймер не отсчитает необходимое количество времени, после этого выхожу из функции задержки. Проблема в том, что при включении оптимизации компилятор выкидывает строку обнуления, т.е. (я так понимаю) он не видит, что она меняется в таймере и считает строку обнуления лишней! Как это можно обойти? Вместо обнуления пробовал считывать текущее значение таймера и прибавлять к нему требуемую задержку и далее эту величину подставлять в условие, но там похожая ситуация. 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); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bloodden 0 22 декабря, 2008 Опубликовано 22 декабря, 2008 · Жалоба При объявлении переменной напишите volatile int timer Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
forever failure 0 22 декабря, 2008 Опубликовано 22 декабря, 2008 (изменено) · Жалоба volatile int timer; А ещё обеспечивать атомарное обращение к этой переменной (если, конечно, она занимает более одного байта). Изменено 22 декабря, 2008 пользователем forever failure Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 22 декабря, 2008 Опубликовано 22 декабря, 2008 · Жалоба А ещё обеспечивать атомарное обращение к этой переменной Ручками : запретить прерывания, разрешить прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Serg_el 0 22 декабря, 2008 Опубликовано 22 декабря, 2008 · Жалоба А что такое атомарное и причем здесь прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
forever failure 0 22 декабря, 2008 Опубликовано 22 декабря, 2008 (изменено) · Жалоба Это означает, что если переменная, допустим, типа int, и она проверяется в основной программе, в момент проверки, после сравнения, допустим старшего байта происходит прерываие таймера и изменяет эту переменную. В результате в операции сравнения сравнивается старший байт от старого значения, а младший - от нового. Вот такой получается косячок-с. Для того, чтоб такого не происходило, на время обращения к этой переменной прерывания надо запретить, а потом опять восстановить. (Или одно, конкретное прерывание, которое обновляет переменную). Изменено 22 декабря, 2008 пользователем forever failure Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 22 декабря, 2008 Опубликовано 22 декабря, 2008 · Жалоба А что такое атомарное и причем здесь прерывания? При всём уважении, но Вам надо в форум для начинающих. Эта проблема стара как мир, и компилятор IAR тут ни при чём. Зачем снова отвечать на одни и те же вопросы? Используйте поиск... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Serg_el 0 22 декабря, 2008 Опубликовано 22 декабря, 2008 · Жалоба Спасибо. Буду пробовать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 22 декабря, 2008 Опубликовано 22 декабря, 2008 · Жалоба Вот такой получается косячок-с. Для того, чтоб такого не происходило, на время обращения к этой переменной прерывания надо запретить, а потом опять восстановить. (Или одно, конкретное прерывание, которое обновляет переменную). Есть ещё один способ. Считать переменную 2 раза и сравнить старший байт для двух считываний. Если не изменился - всё ОК, иначе - повторить. Есть свои минусы, но зато прерывание не запрещаем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Serg_el 0 23 декабря, 2008 Опубликовано 23 декабря, 2008 · Жалоба Вот еще один прикол. Прописываю константу limit по фиксированному адресу и присваиваю ей значение. const unsigned int limit @ 0xE1FE = 29; Компилятор игнорит, тот факт, что указан конкретный адрес и заменяет все ссылки на нее по тексту программы на ее значение 29. Константа используется для значения, программируемого извне. А значение 29 присваивал для отладки и пока не закомментил, не хотел компилятор использовать limit. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HARMHARM 0 23 декабря, 2008 Опубликовано 23 декабря, 2008 · Жалоба Вот еще один прикол. Прописываю константу limit по фиксированному адресу и присваиваю ей значение. const unsigned int limit @ 0xE1FE = 29; Компилятор игнорит, тот факт, что указан конкретный адрес и заменяет все ссылки на нее по тексту программы на ее значение 29. Константа используется для значения, программируемого извне. А значение 29 присваивал для отладки и пока не закомментил, не хотел компилятор использовать limit. Добавьте __root. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 23 декабря, 2008 Опубликовано 23 декабря, 2008 · Жалоба Эта тема напоминает торный путь из граблей, по которому ходят все вновьприбывшие. И каждый вновьприбывший удивляется тому факту, что дорога вроде давно протоптана, а грабли все еще лежат там же ;) Про volatile надо писать в FAQ крупными буквами. А по поводу оптимизации обращения к константе, расположенной по фиксированному адресу, я сам недавно писал и там же указал решение/обходной путь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Есть ещё один способ. Считать переменную 2 раза и сравнить старший байт для двух считываний. Если не изменился - всё ОК, иначе - повторить. Есть свои минусы, но зато прерывание не запрещаем. Может наоборот, сравнивать младшие байты? А то ведь старшие могут быть равны, а младший отличаться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Может наоборот, сравнивать младшие байты? А то ведь старшие могут быть равны, а младший отличаться.При этом результат каждого чтения будет содержать корректное на момент чтения значение пары младшего и старшего байтов. Поскольку прерывание с точки зрения программы атомарно. Т.е. не может сначала изменить младший байт с 0xFF на 0x00, потом дать немного поработать программе и только потом увеличить на 1 старший байт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться