sonycman 0 22 ноября, 2008 Опубликовано 22 ноября, 2008 · Жалоба Сейчас пытаюсь подогнать ИАРовский проект на меге88 под ВинАВР 4.3.2. Чувствую, помучаться придётся немало :smile3046: Пока не могу разобраться, как красиво прочитать/записать 16-ти битный таймер, обеспечив атомарность операции. Аналога иаровского __monitor не нашёл. Существуют ли подобные макросы? Или надо писать самому? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 22 ноября, 2008 Опубликовано 22 ноября, 2008 · Жалоба Поможет WinAVR\avr\include\util\atomic.h Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 22 ноября, 2008 Опубликовано 22 ноября, 2008 · Жалоба Поможет WinAVR\avr\include\util\atomic.h Уря, разобрался! :a14: С меня :beer: Я то пытался накропать код и заюзать что-то типа cli() и sei() своими корявенькими ручонками, а тут уже готовое решение, такое компактное и мощное одновременно! Разрабы туда, наверное, тонну хитрости запихали! Учитывать все выходы из секции для восстановления прерываний... бла, как они это осуществили? Всё, пошёл спать. С утра буду невыспавшийся - зато довольный :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба Насколько я помню, у WinAVR имеется отличная документация, включающая в том числе раздел "Porting Code From IAR" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба Насколько я помню, у WinAVR имеется отличная документация, включающая в том числе раздел "Porting Code From IAR" Спасибо, теперь всё понятно и с прерываниями Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба Насколько я помню, у WinAVR имеется отличная документация, включающая в том числе раздел "Porting Code From IAR" А может кто подскажет, где поискать документацию по AVR GCC в виде PDF? А то не очень удобно пользоваться html версией... :07: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба А может кто подскажет, где поискать документацию по AVR GCC в виде PDF? А то не очень удобно пользоваться html версией... :07: как правило, она находится в папке WinAVR\doc\avr-libc - я ведь верно понял, что интересует документация на avr-libc? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба Разрабы туда, наверное, тонну хитрости запихали! Учитывать все выходы из секции для восстановления прерываний... бла, как они это осуществили?У gcc есть довольно мощная штука - атрибуты. Куча разных. Например, атрибутом можно сказать, что результат, возвращаемый данной функцией, зависит только от передаваемых ей параметров и она сама вовне ничего не меняет, т.е. не имеет "побочных эффектов". Вся математика типа sqrt() такая. Тогда если её вызывать с одними и теми же неизменными аргументами (константами либо переменными, про которые компилятор знает, что они не менялись) несколько раз - компилятор вызовет одитн раз, запомнит значение и подставит где нужно сам. Для переменных можно задать аттрибутами функции создания и очистки, при создании переменной будет вызвана одна функция, при уничтожении (при выходе из окружающего её блока { } ) - другая. Это что-то типа конструкторов-деструкторов в C++. Вот они и спрятали в макросах переменную, при создании которой в неё копируется SREG и прерывания запрещаются/разрешаются, в зависимости от типа блока, а при удалении она переписывается назад в SREG, таким образом состояние прерываний восстанавливается. Чтобы созданная как бы до блока переменная была привязана к блоку, т.е. чтобы можно было писать ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ... } А не { ATOMIC_BLOCK(ATOMIC_RESTORESTATE); ... } макросы оформили в виде заголовка цикла for(;;) - переменная, которая объявлена в заголовке (for( unsigned char u; ...; ... ) ) имеет время жизни в пределах цикла, создаётся до первого входа в тело и уничтожается после выхода из цикла. Очень симпатично сделано... Учтено всё. Вот тут ещё на эту тему было, только "наоборот" - нужно на время разрешить прерывания: http://electronix.ru/forum/index.php?showt...mp;#entry487831 в примере макрос из atomic.h и С++ класс дали при компиляции тождественный код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба как правило, она находится в папке WinAVR\doc\avr-libc - я ведь верно понял, что интересует документация на avr-libc? Нет, на библиотеку как раз pdf есть. Мне бы на компилятор, со всеми его ключевыми словами, аттрибутами и т.д... Она там только в формате html... в принципе, сойдёт, если нет лучшего :) Очень симпатично сделано... Учтено всё. Спасибо за разъяснение, стало понятнее! Сам только недавно начал осваивать С++, и имею небольшое представление о классах. Очень интересная штука ;) У меня возникла очередная проблема в портировании проекта IAR на WinAVR. Есть класс таймеров: #include <util/atomic.h> typedef unsigned long dword; typedef unsigned short word; typedef unsigned char byte; extern volatile word tcounter; //hardware timer class CTimer { private: word interval; word counter; public: CTimer (word timeout = 0) { Set(timeout); } void operator = (word timeout); void Set (word timeout); bool operator ! (); operator bool (); }; CTimer::operator bool() { if (!interval) return TRUE; if ((tcounter - counter) >= interval) { interval = 0; return TRUE; } return FALSE; } bool CTimer::operator ! () { return !operator bool(); } void CTimer::operator = (word timeout) { Set(timeout); } void CTimer::Set(word timeout) { if (timeout) { interval = timeout / 10; //interrupts timer resolution is 10ms counter = tcounter; } else { interval = 0; } } Этот файл компилируется нормально. Но при компиляции таких строк: static CTimer tmrSpinup; то есть при создании объекта класса выдаётся ошибка: undefined reference to `__cxa_guard_release' Что-то я пока что в тупике. Описания такой функции нет в исходниках компилятора. Что делать? Почему так получилось? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба У gcc есть довольно мощная штука - атрибуты. Куча разных. .... Для переменных можно задать аттрибутами функции создания и очистки, при создании переменной будет вызвана одна функция, при уничтожении (при выходе из окружающего её блока { } ) - другая. Это что-то типа конструкторов-деструкторов в C++. Вот они и спрятали в макросах переменную, при создании которой в неё копируется SREG и прерывания запрещаются/разрешаются, в зависимости от типа блока, а при удалении она переписывается назад в SREG, таким образом состояние прерываний восстанавливается. Чтобы созданная как бы до блока переменная была привязана к блоку, т.е. чтобы можно было писать ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ... } А не { ATOMIC_BLOCK(ATOMIC_RESTORESTATE); ... } макросы оформили в виде заголовка цикла for(;;) - переменная, которая объявлена в заголовке (for( unsigned char u; ...; ... ) ) имеет время жизни в пределах цикла, создаётся до первого входа в тело и уничтожается после выхода из цикла. Очень симпатично сделано... Учтено всё. .... В принципе понятно как они сделали. но во зачем - непонятно. зачем такой хитрый выверт с непереносимыми атрибутами, когда аналогичную штуку можно проделать без них? например: #define ATOMIC_BLOCK() for(U8 __temp=get_SREG_and_CLI(),iter=0;iter<1;i++,SREG=__temp) И переносимо, и без хитрых атрибутов? Может я чего-то не понял. Или есть какой-то потаёный от меня смысл? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба то есть при создании объекта класса выдаётся ошибка: undefined reference to `__cxa_guard_release' Что-то я пока что в тупике. Описания такой функции нет в исходниках компилятора. Что делать? Почему так получилось? Странно. К тому коду было добавлено static CTimer tmrSpinup; int main() { tmrSpinup.Set(10); while( !tmrSpinup ); for(;;); } и всё собралось-слинковалось несколькими версиями от 3.4.6 (WinAVR-20060421) до 4.4.0 (Klen-20080530), более свежих нет на компе. Это функция, похоже, должна была бы быть в libstdc++, если бы она для AVR была. Там же __cxa_pure_virtual и т.д., т.е. поддержка для более "взрослого" применения С++ с исключениями и т.д. Почему вдруг в данном случае компилятор решил, что нужна помощь зала библиотеки поддержки - неясно. Иногда такое бывает и иногда при этом помогает добавление ключей CFLAGS += -ffunction-sections #-fdata-sections LDFLAGS += -Wl,--gc-sections Это предназначено для итеративного выбрасывания кода и данных, которые никогда не вызывается/не используются. За компанию стоит добавить LDFLAGS += -Wl,--relax поиском по разделу AVR можно найти объяснения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба В принципе понятно как они сделали. но во зачем - непонятно. зачем такой хитрый выверт с непереносимыми атрибутами, когда аналогичную штуку можно проделать без них? например: #define ATOMIC_BLOCK() for(U8 __temp=get_SREG_and_CLI(),iter=0;iter<1;i++,SREG=__temp) И переносимо, и без хитрых атрибутов? Может я чего-то не понял. Или есть какой-то потаёный от меня смысл? А если внутри блока будет break или return? Выполнится ли тогда SREG=__temp? Странно. К тому коду было добавлено static CTimer tmrSpinup; int main() { tmrSpinup.Set(10); while( !tmrSpinup ); for(;;); } и всё собралось-слинковалось несколькими версиями от 3.4.6 (WinAVR-20060421) до 4.4.0 (Klen-20080530), более свежих нет на компе. Есть информация, что некоторые статические объекты вызывают такую ошибку в новых версиях компилятора, так как отсутствует какая-то библиотека... Решилось добавлением ключа -fno-threadsafe-statics Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба В принципе понятно как они сделали. но во зачем - непонятно. зачем такой хитрый выверт с непереносимыми атрибутами, когда аналогичную штуку можно проделать без них? например:#define ATOMIC_BLOCK() for(U8 __temp=get_SREG_and_CLI(),iter=0;iter<1;i++,SREG=__temp) И переносимо, и без хитрых атрибутов? Может я чего-то не понял. Или есть какой-то потаёный от меня смысл? Это НЕ аналогичная штука. По ссылке, там где я пример с классом приводил, достаточно полный пример зачем это надо (конструкторы-деструкторы, пусть даже в виде прицепленных атрибутами функций). Может быть выход из середины блока, простой "переносимый" вариант при этом не отработает освобождение (у вcякой задачи есть два решения - простое и правильное ;-) ) #include <avr/interrupt.h> #include <util/atomic.h> uint8_t get_SREG_and_CLI() { uint8_t s = SREG; cli(); return s; } #define ATOM() for(uint8_t __temp=get_SREG_and_CLI(),iter=0; iter<1; iter++,SREG=__temp) volatile uint8_t v; void foo(uint8_t z) { ATOM() { ++v; if(z) return; ++v; } } void moo(uint8_t z) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ++v; if(z) return; ++v; } } .global foo .type foo, @function foo: in r18,95-0x20 /* #APP */ cli /* #NOAPP */ lds r25,v subi r25,lo8(-(1)) sts v,r25 tst r24 brne .L10 lds r24,v subi r24,lo8(-(1)) sts v,r24 out 95-0x20,r18 .L10: ; <--- а кто прерывания взад вернёт??? ret .global moo .type moo, @function moo: in r18,95-0x20 /* #APP */ cli /* #NOAPP */ lds r25,v subi r25,lo8(-(1)) sts v,r25 tst r24 brne .L4 lds r24,v subi r24,lo8(-(1)) sts v,r24 .L4: ; <--- вот это другое дело! out 95-0x20,r18 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба то есть при создании объекта класса выдаётся ошибка: undefined reference to `__cxa_guard_release'Полный ответ здесь. Но я на это не нарывался, видимо потому, что использую --ffunction-section и --gc-sections. Я и узнал-то об этих функциях только из статьи по ссылке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 23 ноября, 2008 Опубликовано 23 ноября, 2008 · Жалоба А если объявить tmrSpinup как static? Есть информация, что некоторые статические объекты вызывают такую ошибку в новых версиях компилятора, так как отсутствует какая-то библиотека... Решилось добавлением ключа -fno-threadsafe-statics Так у меня она static и объявлена, вероятно, у меня достаточно старые версии :-) За ключик спасибо, добавлю как упреждающий манёвр. Полный ответ здесь. У меня из дому какие-то проблемы именно с этим сайтом :-( По прямому линку заходит, но страшно медленно, а вот на вторую страницу какой-то темы зайти уже нереально. Поэтому я его практически не смотрю, на работе как правило не до интернета. При этом всё остальное дома "летает", как и положено adsl2+, многое быстрее, чем на работе. Так что гляну уже после "типоотпуска". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться