neiver 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба Ого! EmptyCall ни разу не empty. Это таки задержка тактов этак на 800. А чтоб компилятор не выкидывал переменные, надо ему точнее объяснять свои намерения, например, volatile. там всякие... И вообще что-то у Вас, сударь, там мутновато. Отсюда и желания странные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба - хотябы потому что она изначально возвращает ничего, а static д.относится к переменной (хотя могу запблуждаться) Вы заблуждаетесь. static функция может возвращать результат, но не будет видна из других файлов. А про инлайн , уже непомню писал или нет, нельзя включить т.к. в самой вызываемой ф-ии имеется еще одна ф. которую заинлайнить не получиться , т.к. она спец. вкл. чтобы компил. не выкидывал регистровую переменную, Неубедительно всё это. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба Неубедительно всё это. Есть регистровая переменная описанная в *.h #ifdef __ASSEMBLER__ # define FlgsSt r18 #else /* !ASSEMBLER */ register uint8_t FlgsSt asm("r18"); // рег. Флагов часть ее меняется в другом прерывании, как в main организовать ожидание установки бита в рег.переменной ? просто while (!(FlgsSt&MaskEndS)) { ; } не прокатывает ! Ого! EmptyCall ни разу не empty. Это таки задержка тактов этак на 800. А чтоб компилятор не выкидывал переменные, надо ему точнее объяснять свои намерения, например, volatile. там всякие... И вообще что-то у Вас, сударь, там мутновато. Отсюда и желания странные. описал по новому: void EmptyCall (void) __attribute__((__noinline__)); void EmptyCall (void) { asm("nop");} а причем тут volatile непонимаю ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
neiver 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба А. простите, что вам дает эта регистравая переменная? Экономия байта оперативки и двух тактов обращения к ней? Так EmptyCall в последней версии съест по крайней мере 7 тактов. Вот так экономия на спичках приводит к сами знаете чему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба а причем тут volatile непонимаю ? при том, что переменные надо правильно описывать, чтобы было меньше проблем с оптимизицией. у вас, судя по всему, переменная FlgsSt должна быть о писана в *.h-файле как volatile uint8_t register FlgsSt asm("r18"); (в ветке #else вашего определения) тогда компилятор будет знать, что это за переменная, и где она хранится, а так же благодаря volatile он не выбросит ее при оптимизации. в принципе, вместо volatile должно пройти и extern - тогда тоже не выбросит... но вообще говоря, вызывать из обработчика прерываний не-static функции, да еще с вложенными функциями, да еще и с задержками - это уж какой-то совсем плоховатый стиль... при таком стиле в одном месте вы выровняете - в другом разладится... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба Еще разок про static функции Вот, предположим, Вам надо чтобы OnSound(uint8_t param) была видна всюду, и чтобы красиво вызывалась в прерывании. Есть типовый приемчик на сей случай: static void OnSound_prim(uint8_t param); void OnSound(uint8_t param) { OnSound_prim(param); } void OnSound_prim(uint8_t param) { // сюда помещаем то, что изначально находилось в OnSound() } и из прерывания вызываем OnSound_prim(). Профит: компилер уберет все лишние стековые операции и вообще соптимизирует все хорошо. И для вызова глобальной функции ничего эдакого лишнего не произойдет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 (изменено) · Жалоба Еще разок про static функции Вот, предположим, Вам надо чтобы OnSound(uint8_t param) была видна всюду, и чтобы красиво вызывалась в прерывании. Есть типовый приемчик на сей случай: static void OnSound_prim(uint8_t param); void OnSound(uint8_t param) { OnSound_prim(param); } void OnSound_prim(uint8_t param) { // сюда помещаем то, что изначально находилось в OnSound() } и из прерывания вызываем OnSound_prim(). Профит: компилер уберет все лишние стековые операции и вообще соптимизирует все хорошо. И для вызова глобальной функции ничего эдакого лишнего не произойдет. т.е. вызывать в прерывании из ф-ии1 ф-ию2, которую нужно обьявить static , т.е. какбы использовать подставную функцию ? - не работает ! Изменено 26 апреля, 2013 пользователем MaxiMuz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба не использовать автоматических переменных в теле функции типа uint8_t temp; не вызывать функции, передающие параметры через стек типа OnSound (temp); т.е. примерно так: static uint8_t temp; static void OnSound (void){ temp; ... } ISR (INT0_vect) { temp=PORTB; OnSound (); } или использовать какую-нибудь очередь заданий, которая будет заполняться в прерывании, а обрабатываться в основной программе Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба не использовать автоматических переменных в теле функции типа uint8_t temp; не вызывать функции, передающие параметры через стек типа OnSound (temp); т.е. примерно так: static uint8_t temp; static void OnSound (void){ temp; ... } ISR (INT0_vect) { temp=PORTB; OnSound (); } или использовать какую-нибудь очередь заданий, которая будет заполняться в прерывании, а обрабатываться в основной программе компилятору пофигу какие там переменные в ф-ии используются и передаются параметры в ф-ии или нет , он либо делает ф-ию инлайн либо, либо сохранет все регистры , и фсе! ЁЁ.. , столько времяни потратил на эти эксперементы !!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба А как сделать так чтобы компилятор сохранял только задействованные в конретном прерывании регистры ? По идее никак. Компилятор в принципе не может отследить контекст, в котором вызывается прерывание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 26 апреля, 2013 Опубликовано 26 апреля, 2013 · Жалоба Слушайте, если у Вас так туго с времянкой, давным давно бы уже врукопашную на ассемблере написали... :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slavka012 0 29 апреля, 2013 Опубликовано 29 апреля, 2013 · Жалоба По идее никак. Компилятор в принципе не может отследить контекст, в котором вызывается прерывание. +1. На этапе компиляции компилятор не может знать, какие регистры используются во всех функциях, вызываемых в прерывании. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться