|
спецификатор 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ом, который тоже должен работать независимо.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|