|
GCC: Как избежать избыточного пользования стеком в прерываниях |
|
|
|
Apr 26 2013, 08:13
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(MaxiMuz @ Apr 26 2013, 10:47)  - хотябы потому что она изначально возвращает ничего, а static д.относится к переменной (хотя могу запблуждаться) Вы заблуждаетесь. static функция может возвращать результат, но не будет видна из других файлов. Цитата(MaxiMuz @ Apr 26 2013, 10:47)  А про инлайн , уже непомню писал или нет, нельзя включить т.к. в самой вызываемой ф-ии имеется еще одна ф. которую заинлайнить не получиться , т.к. она спец. вкл. чтобы компил. не выкидывал регистровую переменную, Неубедительно всё это.
|
|
|
|
|
Apr 26 2013, 08:33
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(_Артём_ @ Apr 26 2013, 11:13)  Неубедительно всё это. Есть регистровая переменная описанная в *.h Код #ifdef __ASSEMBLER__
# define FlgsSt r18
#else /* !ASSEMBLER */
register uint8_t FlgsSt asm("r18"); // рег. Флагов часть ее меняется в другом прерывании, как в main организовать ожидание установки бита в рег.переменной ? просто while (!(FlgsSt&MaskEndS)) { ; } не прокатывает ! Цитата(neiver @ Apr 26 2013, 10:59)  Ого! EmptyCall ни разу не empty. Это таки задержка тактов этак на 800. А чтоб компилятор не выкидывал переменные, надо ему точнее объяснять свои намерения, например, volatile. там всякие... И вообще что-то у Вас, сударь, там мутновато. Отсюда и желания странные. описал по новому: Код void EmptyCall (void) __attribute__((__noinline__)); void EmptyCall (void) { asm("nop");} а причем тут volatile непонимаю ?
|
|
|
|
|
Apr 26 2013, 08:50
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(MaxiMuz @ Apr 26 2013, 12:33)  а причем тут volatile непонимаю ? при том, что переменные надо правильно описывать, чтобы было меньше проблем с оптимизицией. у вас, судя по всему, переменная FlgsSt должна быть о писана в *.h-файле как volatile uint8_t register FlgsSt asm("r18"); (в ветке #else вашего определения) тогда компилятор будет знать, что это за переменная, и где она хранится, а так же благодаря volatile он не выбросит ее при оптимизации. в принципе, вместо volatile должно пройти и extern - тогда тоже не выбросит... но вообще говоря, вызывать из обработчика прерываний не-static функции, да еще с вложенными функциями, да еще и с задержками - это уж какой-то совсем плоховатый стиль... при таком стиле в одном месте вы выровняете - в другом разладится...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 26 2013, 08:57
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Еще разок про 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(). Профит: компилер уберет все лишние стековые операции и вообще соптимизирует все хорошо. И для вызова глобальной функции ничего эдакого лишнего не произойдет.
|
|
|
|
|
Apr 26 2013, 11:04
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(_Pasha @ Apr 26 2013, 11:57)  Еще разок про 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 , т.е. какбы использовать подставную функцию ? - не работает !
Сообщение отредактировал MaxiMuz - Apr 26 2013, 11:13
|
|
|
|
|
Apr 26 2013, 11:06
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
не использовать автоматических переменных в теле функции типа uint8_t temp; не вызывать функции, передающие параметры через стек типа OnSound (temp); т.е. примерно так: Код static uint8_t temp; static void OnSound (void){ temp; ... } ISR (INT0_vect) { temp=PORTB; OnSound (); } или использовать какую-нибудь очередь заданий, которая будет заполняться в прерывании, а обрабатываться в основной программе
|
|
|
|
|
Apr 26 2013, 11:48
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(psL @ Apr 26 2013, 14:06)  не использовать автоматических переменных в теле функции типа uint8_t temp; не вызывать функции, передающие параметры через стек типа OnSound (temp); т.е. примерно так: Код static uint8_t temp; static void OnSound (void){ temp; ... } ISR (INT0_vect) { temp=PORTB; OnSound (); } или использовать какую-нибудь очередь заданий, которая будет заполняться в прерывании, а обрабатываться в основной программе компилятору пофигу какие там переменные в ф-ии используются и передаются параметры в ф-ии или нет , он либо делает ф-ию инлайн либо, либо сохранет все регистры , и фсе! ЁЁ.. , столько времяни потратил на эти эксперементы !!!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|