View unanswered posts | View active topics It is currently Fri Nov 16, 2018 9:00 pm



Reply to topic  [ 55 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6
Пропуски зажигания при сборке GCC и новыми верс. IAR 
Author Message
LQFP144 - On Top Of The Game

Joined: Thu Jul 26, 2012 12:35 pm
Posts: 252
Хорошо, так понять сложно. На примерах попробую.
И так тестовый пример очень простой:
Code:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

static void test_func(void)
{
    PORTD |= (1<<PD5);
}

ISR(TIMER0_OVF_vect)
{
    test_func();
}

int main(void)
{
while(1)
    {
    };
}

Листинг прерывания:
Code:
---- test_isr.c -----------------------------------------------------------------------------------
12:       {
+00000049:   921F        PUSH    R1               Push register on stack
+0000004A:   920F        PUSH    R0               Push register on stack
+0000004B:   B60F        IN      R0,0x3F          In from I/O location
+0000004C:   920F        PUSH    R0               Push register on stack
+0000004D:   2411        CLR     R1               Clear Register
7:            PORTD |= (1<<PD5);
+0000004E:   9A95        SBI     0x12,5           Set bit in I/O register
+0000004F:   900F        POP     R0               Pop register from stack
+00000050:   BE0F        OUT     0x3F,R0          Out to I/O location
+00000051:   900F        POP     R0               Pop register from stack
+00000052:   901F        POP     R1               Pop register from stack
+00000053:   9518        RETI                     Interrupt return

Вот тут видно стандартный оверхед ГЦЦ на простых обработчиках. Этот компилятор всегда сохраняет SREG. Ну и заодно ZERO регистр. Но это сейчас неважно.
Сама функция просто проинлайнена что очень логично. Изменим пример на работу с указателем:
Code:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

typedef void (*FuncPtr)(void);
FuncPtr FPtr;

static void test_func(void)
{
    PORTD |= (1<<PD5);
}

ISR(TIMER0_OVF_vect)
{
    (FPtr)();
}

Листинг обработчика прерывания стал таким:
Code:
@0000004B: __vector_11
17:       {
+0000004B:   921F        PUSH    R1               Push register on stack
+0000004C:   920F        PUSH    R0               Push register on stack
+0000004D:   B60F        IN      R0,0x3F          In from I/O location
+0000004E:   920F        PUSH    R0               Push register on stack
+0000004F:   2411        CLR     R1               Clear Register
+00000050:   932F        PUSH    R18              Push register on stack
+00000051:   933F        PUSH    R19              Push register on stack
+00000052:   934F        PUSH    R20              Push register on stack
+00000053:   935F        PUSH    R21              Push register on stack
+00000054:   936F        PUSH    R22              Push register on stack
+00000055:   937F        PUSH    R23              Push register on stack
+00000056:   938F        PUSH    R24              Push register on stack
+00000057:   939F        PUSH    R25              Push register on stack
+00000058:   93AF        PUSH    R26              Push register on stack
+00000059:   93BF        PUSH    R27              Push register on stack
+0000005A:   93EF        PUSH    R30              Push register on stack
+0000005B:   93FF        PUSH    R31              Push register on stack
18:           (FPtr)();
+0000005C:   91E00060    LDS     R30,0x0060       Load direct from data space
+0000005E:   91F00061    LDS     R31,0x0061       Load direct from data space
+00000060:   9509        ICALL                    Indirect call to (Z)
+00000061:   91FF        POP     R31              Pop register from stack
+00000062:   91EF        POP     R30              Pop register from stack
+00000063:   91BF        POP     R27              Pop register from stack
+00000064:   91AF        POP     R26              Pop register from stack
+00000065:   919F        POP     R25              Pop register from stack
+00000066:   918F        POP     R24              Pop register from stack
+00000067:   917F        POP     R23              Pop register from stack
+00000068:   916F        POP     R22              Pop register from stack
+00000069:   915F        POP     R21              Pop register from stack
+0000006A:   914F        POP     R20              Pop register from stack
+0000006B:   913F        POP     R19              Pop register from stack
+0000006C:   912F        POP     R18              Pop register from stack
+0000006D:   900F        POP     R0               Pop register from stack
+0000006E:   BE0F        OUT     0x3F,R0          Out to I/O location
+0000006F:   900F        POP     R0               Pop register from stack
+00000070:   901F        POP     R1               Pop register from stack
+00000071:   9518        RETI   

Разница думаю заметна.
При этом сама функция вообще регистров не использует:
Code:
+00000049:   9A95        SBI     0x12,5           Set bit in I/O register
+0000004A:   9508        RET                      Subroutine return

Тот же эффект будет если сделать вызов обычным, без указателя, но перенести void test_func(void) в другой файл. Т.е. не в тот где обработчик.


Wed Aug 22, 2012 6:30 pm
Profile
LQFP144 - On Top Of The Game
User avatar

Joined: Fri Oct 22, 2010 10:47 pm
Posts: 2415
Location: Ukraine, Kiev
Qwertty спасибо за пример!
В моем обработчике прерывания такие функции (что по указателю, что без него) особой погоды не сделают, так как там и без них все плохо :lol: Там одно только деление 32/16 все перекрывает :lol:

_________________
Author of the SECU-3 project. SECU-3 Engine control unit / Ignition control system
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook


Wed Aug 22, 2012 10:39 pm
Profile ICQ WWW
LQFP144 - On Top Of The Game

Joined: Thu Jul 26, 2012 12:35 pm
Posts: 252
Выше потеря примерно ТРЕХ тактов вызвала панику и желание уйти от битовых полей на макросы. Это в принципе логично и без привязки к оптимальности кода. Тут же 24 такта лишних паники не вызывают. :) Плюс лишние такты на вызов и на считывание указателя. Вот так понемногу и набирается приличное количество лишних действий.
Кстати у варианта GCC помимо минуса от лишнего времени выполнения есть и плюс - независимость этого времени от параметра функции. Иногда это важней.


Wed Aug 22, 2012 11:03 pm
Profile
LQFP144 - On Top Of The Game
User avatar

Joined: Fri Oct 22, 2010 10:47 pm
Posts: 2415
Location: Ukraine, Kiev
Все, покончено с пропусками и на GCC. Теперь бы еще оптимизировать тяжеловесное прерывание и вообще было бы супер :-).
Обновил исходники и бинарники. Продолжаю охоту за багами.

_________________
Author of the SECU-3 project. SECU-3 Engine control unit / Ignition control system
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook


Thu Aug 23, 2012 9:54 am
Profile ICQ WWW
LQFP144 - On Top Of The Game
User avatar

Joined: Fri Oct 22, 2010 10:47 pm
Posts: 2415
Location: Ukraine, Kiev
Вопросы по сборке прошивки перенесены в отдельную тему в разделе "Поддержка пользователей" viewtopic.php?f=71&t=2028

_________________
Author of the SECU-3 project. SECU-3 Engine control unit / Ignition control system
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook


Tue Feb 05, 2013 3:18 pm
Profile ICQ WWW
Display posts from previous:  Sort by  
Reply to topic   [ 55 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6

Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software for PTF. ColorizeIt.