Пропуски зажигания при сборке GCC и новыми верс. IAR

Обсуждение прошивок SECU-3. Discussion of SECU-3 firmware.

Moderator: STC

ender11
LQFP112 - Up with the play
Posts: 197
Joined: Sat Dec 11, 2010 4:05 pm

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by ender11 »

скажу более -- gcc как-то совсем плохо с битовыми флагами работает.
Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by Qwertty »

Ну давайте попробуем смеху ради получить из этого что то удобоваримое.
Вопросов три - что такое в void iocfg_s_ign_out2(uint8_t value) value? Это вычисляемое значение или константа?
Как выглядит вызов этой функции в основном коде?
С какой целью вообще регистр IO представлен именно как структура с битовыми полями?
User avatar
STC
LQFP144 - On Top Of The Game
Posts: 2420
Joined: Fri Oct 22, 2010 10:47 pm
Location: Ukraine, Kiev
Contact:

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by STC »

Qwertty,
void iocfg_s_ign_out2(uint8_t value) это функция которая устанавливает значение линии порта в указанное, указанное значение приходит в value (0, 1). Это вычисляемое значение, с константами GCC работает как нужно! Выглядеть вызов этой функции в коде может по-разному - и сконстантой и с переменной.
С какой целью вообще регистр IO представлен именно как структура с битовыми полями?
Программа была изначально написана для ИАР, потом я ее портировал под GCC. В файле port/portbits.h все битовые поля описаны:

Code: Select all

typedef struct 
{
 unsigned char bit0:1, bit1:1, bit2:1, bit3:1,
               bit4:1, bit5:1, bit6:1, bit7:1;
}__bit_field_t;

#ifdef PORTA
#define PORTA_Bit0 (*((volatile __bit_field_t*) (&PORTA))).bit0
#define PORTA_Bit1 (*((volatile __bit_field_t*) (&PORTA))).bit1
#define PORTA_Bit2 (*((volatile __bit_field_t*) (&PORTA))).bit2
#define PORTA_Bit3 (*((volatile __bit_field_t*) (&PORTA))).bit3
#define PORTA_Bit4 (*((volatile __bit_field_t*) (&PORTA))).bit4
#define PORTA_Bit5 (*((volatile __bit_field_t*) (&PORTA))).bit5
#define PORTA_Bit6 (*((volatile __bit_field_t*) (&PORTA))).bit6
#define PORTA_Bit7 (*((volatile __bit_field_t*) (&PORTA))).bit7
#endif //PORTA
Думаю что это особенность (недоработка) GCC-шного генератора кода, так как если написать
PORTx_Bitx = constant
то все ок, а если
PORTx_Bitx = variable
то вот тот бред получается
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
User avatar
STC
LQFP144 - On Top Of The Game
Posts: 2420
Joined: Fri Oct 22, 2010 10:47 pm
Location: Ukraine, Kiev
Contact:

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by STC »

Я надеялся что мне не прийдется код менять, но видимо прийдется заменять
PORTx_Bitx = x
на:
if (x)
PORTx_Bitx = 1;
else
PORTx_Bitx = 0;
Можно оформить это в виде макроса и/или ассемблерной вставки, но это я уже проделаю работу за компилятор...
Второй вариант и на GCC и на ИАР дает одинаковый, оптимальный код:

Code: Select all

 
  00000000   2300                       TST     R16
  00000002   F011                       BREQ    LABEL
  00000004   9A95                       SBI     0x12,0x05
  00000006   9508                       RET
   LABEL:
   00000008   9895                       CBI     0x12,0x05
   0000000A   9508                       RET
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
User avatar
STC
LQFP144 - On Top Of The Game
Posts: 2420
Joined: Fri Oct 22, 2010 10:47 pm
Location: Ukraine, Kiev
Contact:

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by STC »

Code: Select all

#define SETBIT(x,y)   ((x) |= (1<<(y)))
#define CLEARBIT(x,y) ((x) &= (~(1<<(y))))
#define WRITEBIT(x, y, v) ((v) ? SETBIT(x,y) : CLEARBIT(x, y))

void iocfg_s_ign_out2(uint8_t value)
{
 WRITEBIT(PORTD, 5, value);
}
Дубль #2. Очередной маразм ГНУси:
347 0000 8823 tst r24
348 0002 01F0 breq .L99
349 0004 959A sbi 50-32,5
350 0006 00C0 rjmp .L102
351 .L99:
352 0008 9598 cbi 50-32,5
353 .L102:
354 000a 82B3 in r24,50-32
355 000c 0895 ret
:lol: Лишние инструкции выделены жирным (rjmp нужно было заменить ret, а in там вообще не нужна). Вообще не понимаю какую траву он курит...
Жесть. Как можно с таким компилятором получить оптимальный код?
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
User avatar
STC
LQFP144 - On Top Of The Game
Posts: 2420
Joined: Fri Oct 22, 2010 10:47 pm
Location: Ukraine, Kiev
Contact:

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by STC »

Короче, отказался я от битовых полей и заменил все на макросы работы с битами. При работе с битовыми полями GCC генерирует отвратительный код, он тупо забывает что в AVR есть инcтрукции cbi, sbi. Ту что же, за кросс-платформенность нужно платить :-)
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
Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by Qwertty »

STC wrote:Qwertty,
void iocfg_s_ign_out2(uint8_t value) это функция которая устанавливает значение линии порта в указанное, указанное значение приходит в value (0, 1). Это вычисляемое значение
Где посмотреть пример вызова этой функции и пример расчета value в репозитории? Имя файла и функция.
User avatar
STC
LQFP144 - On Top Of The Game
Posts: 2420
Joined: Fri Oct 22, 2010 10:47 pm
Location: Ukraine, Kiev
Contact:

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by STC »

Эта функция вызывается только косвенно - через таблицу указателей на функции (макросом ее не заменишь). Что там смотреть?
value принимает значения 0 или 1
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
Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by Qwertty »

Надеюсь вызывается по указателю не в прерывании? Прерывания АВР и функции по указателю ведут к нехилому оверхеду. Все call used регистры помещаются в стек в прологе прерывания. Даже если реально используется только один. Ровно то же относится к простому вызову функций расположенных в другом модуле.
User avatar
STC
LQFP144 - On Top Of The Game
Posts: 2420
Joined: Fri Oct 22, 2010 10:47 pm
Location: Ukraine, Kiev
Contact:

Re: Пропуски зажигания при сборке GCC и новыми верс. IAR

Post by STC »

Вызывается в прерывании тоже, но в каждой из этих функций используется максимум один из регистров общего назначения (входной параметр value).
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
Post Reply