John851 0 26 мая, 2010 Опубликовано 26 мая, 2010 · Жалоба Добрый день, в какой памяти AVR хранится переменная объявленная со спецификатором static? есть ли в avr libc (поставляемой вместе с WinAvr) атомарная операция nop? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 17 26 мая, 2010 Опубликовано 26 мая, 2010 · Жалоба в какой памяти AVR хранится переменная объявленная со спецификатором static? Если переменная, то в ОЗУ, где ж ей ещё быть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
John851 0 26 мая, 2010 Опубликовано 26 мая, 2010 · Жалоба абсолютно все переменные попадают в ОЗУ? или есть исключения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 26 мая, 2010 Опубликовано 26 мая, 2010 · Жалоба абсолютно все переменные попадают в ОЗУ? или есть исключения?Если они объявлены с макросами PROGMEM (PSTR()), EEMEM - то во флеш и eeprom соответственно. Но доступ к ним должен осуществляться через соответствующие макросы. И static к этому отношения не имеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 26 мая, 2010 Опубликовано 26 мая, 2010 · Жалоба static лишь ограничивает область видимости переменной текущим модулем(в котором она объявлена). Ещё static внутри функции - отдельная тема. Там область видимости уже не модуль, а функция, но значения переменной сохраняются между вызовами функции. Вообще, для облегчения жизни компилятору, нужно всегда использовать static там, где оно действительно static. Это же относится и к функциям(функция в таком случае видна только внутри модуля). явный static позволяет компилятору лучше оптимизировать код. Вообще static немного влияет на размещение переменных, но только в случае локальной переменной(внутри функции). static переменная не размещается в стеке(как все локальные), а помещается в секцию .bss, ко всем остальным глобальным переменным(если мне не изменяет память). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
swisst 0 26 мая, 2010 Опубликовано 26 мая, 2010 · Жалоба есть ли в avr libc (поставляемой вместе с WinAvr) атомарная операция nop? добавлю свои пять копеек... #define nop() asm volatile("nop\n\t"::) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
John851 0 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба Еще немного про ОЗУ: А как происходит работа с ОЗУ? Переменные туда попадают при каждом старте МК или зашиваются при прошивке? Почему такой маленький объем этой памяти? что означает спецификатор inline перед функцией? как это отразится МК, т.е. она будет какая то особая? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 17 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба Еще немного про ОЗУ: А как происходит работа с ОЗУ? Переменные туда попадают при каждом старте МК или зашиваются при прошивке? Почему такой маленький объем этой памяти? А информатики в школе не было? ОЗУ - это то, что гаснет при выключении питания, а при включении может заполняться произвольными значениями. В переменные, инициализированные при объявлении, значения заносятся процедурой startup, которая стартует перед main(). Остальные - ваша личная забота. Объём маленький (по сравнению с флешью), потому что это дорогая, большая по физическим размерам и довольно прожорливая статическая память. что означает спецификатор inline перед функцией? как это отразится МК, т.е. она будет какая то особая? Таким образом вы сообщаете компилятору, что хотели бы встроить тело функции в месте вызова, вместо того чтобы вызывать функцию через CALL. Это увеличивает быстродействие, а в случае совсем маленьких функций может даже экономить место. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xelax 0 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба static переменная не размещается в стеке(как все локальные), а помещается в секцию .bss, ко всем остальным глобальным переменным(если мне не изменяет память). Уверены, что всегда размещаются в bss секции? Есть предположение, что в примере переменная ляжет в секцию data. void function(void) { static uint8_t tempVariable = 0x55; .... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eracer 0 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба Извиняюсь, что влезаю в чужой топик. Возникла непонятка со спецификатором 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), и соответственно при сравнении обнуляется. Если сделать глобальное объявление переменной, то проблема исчезает. Но почему так происходит, к сожалению понять так и не смог. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 68 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба При пошаговой отладке после вычисления синуса, значение num меняется на 22016 (причем Fpwm=7844), и соответственно при сравнении обнуляется. Если сделать глобальное объявление переменной, то проблема исчезает. Но почему так происходит, к сожалению понять так и не смог. Стеком поди затирается. Вообще, использование sin() и прочей плавучки внутри обработчика прерывания - это ну совсем нехорошо по целому ряду причин. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба Попробуйте сделать табличку значений синуса с нужным шагом во флеши. И ещё у Вас UART буферизован? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eracer 0 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба Стеком поди затирается. Вообще, использование sin() и прочей плавучки внутри обработчика прерывания - это ну совсем нехорошо по целому ряду причин. Действительно стек на 32 байта, заполнен полностью. А можете рассказать про причины, или дать ссылку? Знаю, что прерывания не должны "подвешивать" программу. Но в данном случае я проверял по количеству циклов, все вычисления уложаться до начала реверсивного счета. Попробуйте сделать табличку значений синуса с нужным шагом во флеши. И ещё у Вас UART буферизован? Проблема в том, что потребуется слишком много значений. Можно по идее ограничиться десятью и постепенно подгружать новые, но при этом нужно будет основную программу синхронизировать с прерыванием, чтобы в функцию обработки попадали только "нужные" значения. Это отдельная задача, и я еще над ней не задумывался. Та же проблема с UARTом, который тоже должен работать независимо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 17 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба Действительно стек на 32 байта, заполнен полностью. Да у вас один вызов функции может полстека съесть! Что ж так жадничаете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 68 27 мая, 2010 Опубликовано 27 мая, 2010 · Жалоба А можете рассказать про причины, или дать ссылку? Причина в том, что работа с плавающей запятой по определению ресурсоемкая и медленная. Кроме того, данные функции не всегда являются реентерабельными (нужно справится в документации на конкретную библиотеку), что накладывает дополнительные ограничения на их использование в прерываниях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться