Пропуски зажигания при сборке GCC и новыми верс. IAR
Moderator: STC
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
скажу более -- gcc как-то совсем плохо с битовыми флагами работает.
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Ну давайте попробуем смеху ради получить из этого что то удобоваримое.
Вопросов три - что такое в void iocfg_s_ign_out2(uint8_t value) value? Это вычисляемое значение или константа?
Как выглядит вызов этой функции в основном коде?
С какой целью вообще регистр IO представлен именно как структура с битовыми полями?
Вопросов три - что такое в void iocfg_s_ign_out2(uint8_t value) value? Это вычисляемое значение или константа?
Как выглядит вызов этой функции в основном коде?
С какой целью вообще регистр IO представлен именно как структура с битовыми полями?
- STC
- LQFP144 - On Top Of The Game
- Posts: 2420
- Joined: Fri Oct 22, 2010 10:47 pm
- Location: Ukraine, Kiev
- Contact:
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Qwertty,
void iocfg_s_ign_out2(uint8_t value) это функция которая устанавливает значение линии порта в указанное, указанное значение приходит в value (0, 1). Это вычисляемое значение, с константами GCC работает как нужно! Выглядеть вызов этой функции в коде может по-разному - и сконстантой и с переменной.
Думаю что это особенность (недоработка) GCC-шного генератора кода, так как если написать
PORTx_Bitx = constant
то все ок, а если
PORTx_Bitx = variable
то вот тот бред получается
void iocfg_s_ign_out2(uint8_t value) это функция которая устанавливает значение линии порта в указанное, указанное значение приходит в value (0, 1). Это вычисляемое значение, с константами GCC работает как нужно! Выглядеть вызов этой функции в коде может по-разному - и сконстантой и с переменной.
Программа была изначально написана для ИАР, потом я ее портировал под GCC. В файле port/portbits.h все битовые поля описаны:С какой целью вообще регистр IO представлен именно как структура с битовыми полями?
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
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
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook
- STC
- LQFP144 - On Top Of The Game
- Posts: 2420
- Joined: Fri Oct 22, 2010 10:47 pm
- Location: Ukraine, Kiev
- Contact:
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Я надеялся что мне не прийдется код менять, но видимо прийдется заменять
PORTx_Bitx = x
на:
if (x)
PORTx_Bitx = 1;
else
PORTx_Bitx = 0;
Можно оформить это в виде макроса и/или ассемблерной вставки, но это я уже проделаю работу за компилятор...
Второй вариант и на GCC и на ИАР дает одинаковый, оптимальный код:
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
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook
- STC
- LQFP144 - On Top Of The Game
- Posts: 2420
- Joined: Fri Oct 22, 2010 10:47 pm
- Location: Ukraine, Kiev
- Contact:
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
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);
}
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
Лишние инструкции выделены жирным (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
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook
- STC
- LQFP144 - On Top Of The Game
- Posts: 2420
- Joined: Fri Oct 22, 2010 10:47 pm
- Location: Ukraine, Kiev
- Contact:
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Короче, отказался я от битовых полей и заменил все на макросы работы с битами. При работе с битовыми полями 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
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Где посмотреть пример вызова этой функции и пример расчета value в репозитории? Имя файла и функция.STC wrote:Qwertty,
void iocfg_s_ign_out2(uint8_t value) это функция которая устанавливает значение линии порта в указанное, указанное значение приходит в value (0, 1). Это вычисляемое значение
- STC
- LQFP144 - On Top Of The Game
- Posts: 2420
- Joined: Fri Oct 22, 2010 10:47 pm
- Location: Ukraine, Kiev
- Contact:
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Эта функция вызывается только косвенно - через таблицу указателей на функции (макросом ее не заменишь). Что там смотреть?
value принимает значения 0 или 1
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
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Надеюсь вызывается по указателю не в прерывании? Прерывания АВР и функции по указателю ведут к нехилому оверхеду. Все call used регистры помещаются в стек в прологе прерывания. Даже если реально используется только один. Ровно то же относится к простому вызову функций расположенных в другом модуле.
- STC
- LQFP144 - On Top Of The Game
- Posts: 2420
- Joined: Fri Oct 22, 2010 10:47 pm
- Location: Ukraine, Kiev
- Contact:
Re: Пропуски зажигания при сборке GCC и новыми верс. IAR
Вызывается в прерывании тоже, но в каждой из этих функций используется максимум один из регистров общего назначения (входной параметр 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
SECU-3.org (Русский)
SECU-3.org (English)
SECU-3 Club ВКонтакте
SECU-3 EMS Project Facebook