|
спецификатор static |
|
|
|
May 26 2010, 12:30
|
Участник

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

|
Добрый день,
в какой памяти AVR хранится переменная объявленная со спецификатором static?
есть ли в avr libc (поставляемой вместе с WinAvr) атомарная операция nop?
|
|
|
|
|
May 26 2010, 12:54
|
Участник

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

|
абсолютно все переменные попадают в ОЗУ? или есть исключения?
|
|
|
|
|
May 26 2010, 16:44
|
Частый гость
 
Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425

|
Цитата(John851 @ May 26 2010, 15:30)  есть ли в avr libc (поставляемой вместе с WinAvr) атомарная операция nop? добавлю свои пять копеек... Код #define nop() asm volatile("nop\n\t"::)
|
|
|
|
|
May 27 2010, 05:30
|
Участник

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

|
Еще немного про ОЗУ: А как происходит работа с ОЗУ? Переменные туда попадают при каждом старте МК или зашиваются при прошивке? Почему такой маленький объем этой памяти?
что означает спецификатор inline перед функцией? как это отразится МК, т.е. она будет какая то особая?
|
|
|
|
|
May 27 2010, 05:43
|

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

|
Цитата(John851 @ May 27 2010, 09:30)  Еще немного про ОЗУ: А как происходит работа с ОЗУ? Переменные туда попадают при каждом старте МК или зашиваются при прошивке? Почему такой маленький объем этой памяти? А информатики в школе не было? ОЗУ - это то, что гаснет при выключении питания, а при включении может заполняться произвольными значениями. В переменные, инициализированные при объявлении, значения заносятся процедурой startup, которая стартует перед main(). Остальные - ваша личная забота. Объём маленький (по сравнению с флешью), потому что это дорогая, большая по физическим размерам и довольно прожорливая статическая память. Цитата что означает спецификатор inline перед функцией? как это отразится МК, т.е. она будет какая то особая? Таким образом вы сообщаете компилятору, что хотели бы встроить тело функции в месте вызова, вместо того чтобы вызывать функцию через CALL. Это увеличивает быстродействие, а в случае совсем маленьких функций может даже экономить место.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
May 27 2010, 06:03
|

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

|
Цитата(sigmaN @ May 26 2010, 19:01)  static переменная не размещается в стеке(как все локальные), а помещается в секцию .bss, ко всем остальным глобальным переменным(если мне не изменяет память). Уверены, что всегда размещаются в bss секции? Есть предположение, что в примере переменная ляжет в секцию data. Код void function(void) { static uint8_t tempVariable = 0x55; .... }
|
|
|
|
|
May 27 2010, 08:20
|
Участник

Группа: Участник
Сообщений: 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), и соответственно при сравнении обнуляется. Если сделать глобальное объявление переменной, то проблема исчезает. Но почему так происходит, к сожалению понять так и не смог.
|
|
|
|
|
May 27 2010, 10:31
|
Участник

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

|
Цитата(aaarrr @ May 27 2010, 12:31)  Стеком поди затирается. Вообще, использование sin() и прочей плавучки внутри обработчика прерывания - это ну совсем нехорошо по целому ряду причин. Действительно стек на 32 байта, заполнен полностью. А можете рассказать про причины, или дать ссылку? Знаю, что прерывания не должны "подвешивать" программу. Но в данном случае я проверял по количеству циклов, все вычисления уложаться до начала реверсивного счета. Цитата Попробуйте сделать табличку значений синуса с нужным шагом во флеши. И ещё у Вас UART буферизован? Проблема в том, что потребуется слишком много значений. Можно по идее ограничиться десятью и постепенно подгружать новые, но при этом нужно будет основную программу синхронизировать с прерыванием, чтобы в функцию обработки попадали только "нужные" значения. Это отдельная задача, и я еще над ней не задумывался. Та же проблема с UARTом, который тоже должен работать независимо.
|
|
|
|
|
May 27 2010, 11:15
|
Участник

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

|
Цитата(MrYuran @ May 27 2010, 14:37)  Да у вас один вызов функции может полстека съесть! Что ж так жадничаете? Затруднил себя покопаться поглубже в настройках компилятора )) Мне казалось, что его размер выбирается автоматически
|
|
|
|
|
May 27 2010, 12:27
|
Участник

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

|
хм, в чем разница объявления глобальной переменной в модуле?
int abc;
static int abc;
Разницы ведь никакой, переменная так и останется глобальной в пределах видимости модуля, дак зачем тогда еще и static прописывать?
|
|
|
|
|
May 27 2010, 12:35
|

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

|
Цитата(John851 @ May 27 2010, 16:27)  Разницы ведь никакой, переменная так и останется глобальной в пределах видимости модуля, дак зачем тогда еще и static прописывать? Вот именно, "в пределах видимости модуля". То есть мы сообщаем компилятору, что за пределами данного модуля эта переменная не используется. Что позволяет ему оптимизировать её в хвост и гриву. То же самое относится и к функциям. Вывод: Если для вас разницы нет, пишите static везде, где можно.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
May 28 2010, 06:25
|

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

|
Цитата(_Pasha @ May 28 2010, 09:52)  А шо, не использовать же delay() в прерываниях!?  А действительно, я как-то и не думал о таком применении. Это ж можно макрос накатать типа TIMER(interval,action) и существенно обкультурить исходники
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
May 28 2010, 07:04
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(sigmaN @ May 28 2010, 00:42)  IMHO - ничего не понимаете вы в колбасных обрезках  Может быть всех тонкостей применения static не знаю - учился на электронщика а не программиста Но для глобальных переменных никогда его не применял  Были конструкции такого типа (когдато подсказали сдесь на форуме) Код #define PutString(x) do{static __flash char str[]=x; _putstring(str);}while(0); Ну ещё в прерываниях по таймеру если нужно было с фиксированным периодом чтото выполнять Код void ISR_PIT(); { static unsigned int i=1000;
//вызов задачи раз в секунду if(i>0) i--; else { i=1000; TaskON(5); } } Цитата(Сергей Борщ @ May 28 2010, 02:24)  static для глобальных и локальных переменных имеет разное значение. Вопрос #17 был про глобальные переменные, а вы ответили про локальные. Вы правы - действительно мой ответ касался локальных переменных В глобальных не приходилось применять - небыло необходимости объявлять переменные видимые только в одном модуле
Сообщение отредактировал mempfis_ - May 28 2010, 07:04
|
|
|
|
|
May 28 2010, 10:02
|
Участник

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

|
хм, а если я создам массив большой >1 Кб а памяти ОЗУ у меня всего 1Кб, тогда чего будет динамическая подгрузка данных из флэши?))
|
|
|
|
|
Jun 1 2010, 06:57
|

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

|
Цитата(MrYuran @ May 28 2010, 10:25)  Это ж можно макрос накатать типа Вот, накатал... Попробовать, правда, пока не могу, некогда... Код /********************************************************* * Макрос для установки локального таймера * realtime - переменная системного времени * type - тип realtime * timer - временной интервал в тиках системного времени * action - действие по окончании интервала * continue - флаг "перезарядки" таймера *********************************************************/ #define SET_TIMER(realtime, type, timer, action, continue) \ do{ \ static type timerVar = realtime + timer; \ if(timerVar>realtime){ \ action; \ if(continue) timerVar = realtime + timer; \ } \ }while(0) Пример применения: SET_TIMER(RealTime, unsigned int, 1000, DoSomething(), 1); По идее, должен завести статическую переменную unsigned int под таймер, отсчитать 1000 тиков, выполнить DoSomething() и перезапустить таймер Вопрос на засыпку: локальную переменную создаст для do-while или для обёртывающей функции?
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|