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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> спецификатор static
John851
сообщение May 26 2010, 12:30
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 2-05-09
Пользователь №: 48 549



Добрый день,

в какой памяти AVR хранится переменная объявленная со спецификатором static?

есть ли в avr libc (поставляемой вместе с WinAvr) атомарная операция nop?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 26 2010, 12:46
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(John851 @ May 26 2010, 16:30) *
в какой памяти AVR хранится переменная объявленная со спецификатором static?

Если переменная, то в ОЗУ, где ж ей ещё быть


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
John851
сообщение May 26 2010, 12:54
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 2-05-09
Пользователь №: 48 549



абсолютно все переменные попадают в ОЗУ? или есть исключения?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 26 2010, 13:11
Сообщение #4


Гуру
******

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



Цитата(John851 @ May 26 2010, 15:54) *
абсолютно все переменные попадают в ОЗУ? или есть исключения?
Если они объявлены с макросами PROGMEM (PSTR()), EEMEM - то во флеш и eeprom соответственно. Но доступ к ним должен осуществляться через соответствующие макросы. И static к этому отношения не имеет.


--------------------
На любой вопрос даю любой ответ
"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
sigmaN
сообщение May 26 2010, 15:01
Сообщение #5


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



static лишь ограничивает область видимости переменной текущим модулем(в котором она объявлена).
Ещё static внутри функции - отдельная тема. Там область видимости уже не модуль, а функция, но значения переменной сохраняются между вызовами функции.

Вообще, для облегчения жизни компилятору, нужно всегда использовать static там, где оно действительно static.
Это же относится и к функциям(функция в таком случае видна только внутри модуля).
явный static позволяет компилятору лучше оптимизировать код.

Вообще static немного влияет на размещение переменных, но только в случае локальной переменной(внутри функции).
static переменная не размещается в стеке(как все локальные), а помещается в секцию .bss, ко всем остальным глобальным переменным(если мне не изменяет память).


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
swisst
сообщение May 26 2010, 16:44
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Цитата(John851 @ May 26 2010, 15:30) *
есть ли в avr libc (поставляемой вместе с WinAvr) атомарная операция nop?


добавлю свои пять копеек...

Код
#define nop() asm volatile("nop\n\t"::)
Go to the top of the page
 
+Quote Post
John851
сообщение May 27 2010, 05:30
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 2-05-09
Пользователь №: 48 549



Еще немного про ОЗУ:
А как происходит работа с ОЗУ? Переменные туда попадают при каждом старте МК или зашиваются при прошивке? Почему такой маленький объем этой памяти?

что означает спецификатор inline перед функцией? как это отразится МК, т.е. она будет какая то особая?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 27 2010, 05:43
Сообщение #8


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(John851 @ May 27 2010, 09:30) *
Еще немного про ОЗУ:
А как происходит работа с ОЗУ? Переменные туда попадают при каждом старте МК или зашиваются при прошивке? Почему такой маленький объем этой памяти?

А информатики в школе не было? biggrin.gif
ОЗУ - это то, что гаснет при выключении питания, а при включении может заполняться произвольными значениями.
В переменные, инициализированные при объявлении, значения заносятся процедурой startup, которая стартует перед main().
Остальные - ваша личная забота.
Объём маленький (по сравнению с флешью), потому что это дорогая, большая по физическим размерам и довольно прожорливая статическая память.
Цитата
что означает спецификатор inline перед функцией? как это отразится МК, т.е. она будет какая то особая?

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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
xelax
сообщение May 27 2010, 06:03
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(sigmaN @ May 26 2010, 19:01) *
static переменная не размещается в стеке(как все локальные), а помещается в секцию .bss, ко всем остальным глобальным переменным(если мне не изменяет память).


Уверены, что всегда размещаются в bss секции?
Есть предположение, что в примере переменная ляжет в секцию data.
Код
void function(void)
{
  static uint8_t tempVariable = 0x55;
  ....
}
Go to the top of the page
 
+Quote Post
eracer
сообщение May 27 2010, 08:20
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 24-05-10
Пользователь №: 57 488



Извиняюсь, что влезаю в чужой топик. Возникла непонятка со спецификатором static, поэтому решил запостить сюда вопрос. Программа осуществляет ЦАП с помощью ШИМ. Запись в регистр сравнения осущетсвляется по прерыванию при переполнению счетчика.
Функция обработки прерывания выглядит следующим образом:
Код
__interrupt void T1_OVF_Handler()
{
    static unsigned int num = 0;
    temp = sin(2*pi*Fsin*num/Fpwm); //
    OCR1A = short(temp*TOP_PWM);
    num++;
    if (num >= Fpwm) num = 0;
    IntToChar(UART_out, 4, OCR1A);
    PutTextToUART(UART_out, 4);
}

При пошаговой отладке после вычисления синуса, значение num меняется на 22016 (причем Fpwm=7844), и соответственно при сравнении обнуляется. Если сделать глобальное объявление переменной, то проблема исчезает. Но почему так происходит, к сожалению понять так и не смог.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 27 2010, 08:31
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(eracer @ May 27 2010, 12:20) *
При пошаговой отладке после вычисления синуса, значение num меняется на 22016 (причем Fpwm=7844), и соответственно при сравнении обнуляется. Если сделать глобальное объявление переменной, то проблема исчезает. Но почему так происходит, к сожалению понять так и не смог.

Стеком поди затирается. Вообще, использование sin() и прочей плавучки внутри обработчика прерывания - это ну совсем нехорошо по целому ряду причин.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 27 2010, 09:30
Сообщение #12


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Попробуйте сделать табличку значений синуса с нужным шагом во флеши.
И ещё у Вас UART буферизован?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
eracer
сообщение May 27 2010, 10:31
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 24-05-10
Пользователь №: 57 488



Цитата(aaarrr @ May 27 2010, 12:31) *
Стеком поди затирается. Вообще, использование sin() и прочей плавучки внутри обработчика прерывания - это ну совсем нехорошо по целому ряду причин.

Действительно стек на 32 байта, заполнен полностью. А можете рассказать про причины, или дать ссылку?
Знаю, что прерывания не должны "подвешивать" программу. Но в данном случае я проверял по количеству циклов, все вычисления уложаться до начала реверсивного счета.

Цитата
Попробуйте сделать табличку значений синуса с нужным шагом во флеши.
И ещё у Вас UART буферизован?

Проблема в том, что потребуется слишком много значений. Можно по идее ограничиться десятью и постепенно подгружать новые, но при этом нужно будет основную программу синхронизировать с прерыванием, чтобы в функцию обработки попадали только "нужные" значения. Это отдельная задача, и я еще над ней не задумывался. Та же проблема с UARTом, который тоже должен работать независимо.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 27 2010, 10:37
Сообщение #14


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(eracer @ May 27 2010, 14:31) *
Действительно стек на 32 байта, заполнен полностью.

lol.gif
Да у вас один вызов функции может полстека съесть!
Что ж так жадничаете?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 27 2010, 10:37
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(eracer @ May 27 2010, 14:31) *
А можете рассказать про причины, или дать ссылку?

Причина в том, что работа с плавающей запятой по определению ресурсоемкая и медленная. Кроме того, данные функции не всегда являются реентерабельными (нужно справится в документации на конкретную библиотеку), что накладывает дополнительные ограничения на их использование в прерываниях.
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 Текстовая версия Сейчас: 20th July 2025 - 19:17
Рейтинг@Mail.ru


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